This commit is contained in:
huangyuhui 2017-01-27 16:26:02 +08:00
parent 68cfa3a5da
commit 809d7378e2
19 changed files with 117 additions and 234 deletions

View File

@ -46,7 +46,7 @@ public class DefaultGameLauncher extends GameLauncher {
if (names.contains(s.lib.name)) if (names.contains(s.lib.name))
continue; continue;
names.add(s.lib.name); names.add(s.lib.name);
parallelTask.addDependsTask(new LibraryDownloadTask(s)); parallelTask.addTask(new LibraryDownloadTask(s));
} }
dw.append(parallelTask); dw.append(parallelTask);
boolean flag = true; boolean flag = true;

View File

@ -111,10 +111,10 @@ public class GameDownloadPanel extends Page {
MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType()) MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType())
.reg((ver) -> model.addRow(new Object[] { ver.id, ver.time, .reg((ver) -> model.addRow(new Object[] { ver.id, ver.time,
StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type })) StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type }))
.regDone(() -> { .regDone(SwingUtils.invokeLater(() -> {
lstDownloads.requestFocus(); lstDownloads.requestFocus();
model.removeRow(0); model.removeRow(0);
}).execute(); })).execute();
} }
void downloadMinecraft() { void downloadMinecraft() {

View File

@ -112,13 +112,6 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
Settings.profileChangedEvent.register(onSelectedProfilesChanged); Settings.profileChangedEvent.register(onSelectedProfilesChanged);
dropTarget = new DropTarget(lstExternalMods, DnDConstants.ACTION_COPY_OR_MOVE, this); dropTarget = new DropTarget(lstExternalMods, DnDConstants.ACTION_COPY_OR_MOVE, this);
/*AeroPage pnlAero = new AeroPage();
pnlAero.setBounds(0, 0, 800, 480);
pnlAero.setLayout(null);
pnlAero.addAeroObject(jPanel1);
pnlAero.setBackgroundImage(MainFrame.INSTANCE.background.getImage());
add(jPanel1);*/
} }
void initExplorationMenu() { void initExplorationMenu() {
@ -248,9 +241,11 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
} }
} }
}); });
((NewTabPane) tabVersionEdit).initializing = true; ((NewTabPane) tabVersionEdit).initializing = true;
tabVersionEdit.addTab(C.i18n("settings.tabs.game_download"), pnlGameDownloads); // NOI18N tabVersionEdit.addTab(C.i18n("settings.tabs.game_download"), pnlGameDownloads);
((NewTabPane) tabVersionEdit).initializing = false; ((NewTabPane) tabVersionEdit).initializing = false;
((NewTabPane) tabInstallers).initializing = true; ((NewTabPane) tabInstallers).initializing = true;
for (int i = 0; i < InstallerType.values().length; i++) for (int i = 0; i < InstallerType.values().length; i++)
tabInstallers.addTab(InstallerType.values()[i].getLocalizedName(), installerPanels[i]); tabInstallers.addTab(InstallerType.values()[i].getLocalizedName(), installerPanels[i]);

View File

@ -67,16 +67,15 @@
<Component id="lblAbout" min="-2" max="-2" attributes="0"/> <Component id="lblAbout" min="-2" max="-2" attributes="0"/>
<Component id="lblModpack" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="lblModpack" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lblRestart" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="lblRestart" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="chkEnableShadow" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkEnableBlur" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="chkDecorated" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0">
<Component id="chkEnableShadow" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="chkEnableBlur" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -121,20 +120,21 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="chkEnableShadow" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="chkEnableShadow" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="chkDecorated" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="chkEnableBlur" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="chkEnableBlur" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace type="unrelated" max="32767" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="chkDecorated" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="6" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btnCheckUpdate" alignment="3" min="-2" pref="26" max="-2" attributes="0"/> <Component id="btnCheckUpdate" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
<Component id="btnMCBBS" alignment="3" max="32767" attributes="0"/> <Component id="btnMCBBS" alignment="3" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblRestart" min="-2" max="-2" attributes="0"/> <Component id="lblRestart" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblModpack" min="-2" max="-2" attributes="0"/> <Component id="lblModpack" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblAbout" min="-2" pref="173" max="-2" attributes="0"/> <Component id="lblAbout" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>

View File

@ -293,14 +293,13 @@ public class LauncherSettingsPanel extends RepaintPage {
.addComponent(btnMCBBS)) .addComponent(btnMCBBS))
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblRestart)) .addComponent(lblRestart)
.addGap(0, 0, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup() .addComponent(chkEnableShadow)
.addComponent(chkEnableShadow) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkEnableBlur))
.addComponent(chkEnableBlur) .addComponent(chkDecorated))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, Short.MAX_VALUE)))
.addComponent(chkDecorated)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
@ -337,9 +336,10 @@ public class LauncherSettingsPanel extends RepaintPage {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(chkEnableShadow) .addComponent(chkEnableShadow)
.addComponent(chkDecorated)
.addComponent(chkEnableBlur)) .addComponent(chkEnableBlur))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(chkDecorated)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnMCBBS, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(btnMCBBS, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
@ -348,7 +348,7 @@ public class LauncherSettingsPanel extends RepaintPage {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblModpack, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblAbout, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap()) .addContainerGap())
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents

View File

@ -31,7 +31,7 @@ import org.jackhuang.hellominecraft.util.system.IOUtils;
/** /**
* *
* @author huang * @author huangyuhui
*/ */
public final class NetUtils { public final class NetUtils {

View File

@ -24,7 +24,7 @@ import java.util.Locale;
* @author huangyuhui * @author huangyuhui
*/ */
public enum SupportedLocales { public enum SupportedLocales {
def(Locale.getDefault(), "lang.default"), en(Locale.ENGLISH, null), zh_TW(Locale.TRADITIONAL_CHINESE, null), zh_CN(Locale.SIMPLIFIED_CHINESE, null); def(Locale.getDefault(), "lang.default"), en(Locale.ENGLISH, null), zh_TW(Locale.TRADITIONAL_CHINESE, null), zh_CN(Locale.SIMPLIFIED_CHINESE, null), vi(new Locale("vi"), null);
public Locale self; public Locale self;
private String showString, customized; private String showString, customized;

View File

@ -26,7 +26,7 @@ import java.util.HashSet;
*/ */
public class ParallelTask extends Task { public class ParallelTask extends Task {
Collection<Task> dependsTask = new HashSet<>(); Collection<Task> tasks = new HashSet<>();
public ParallelTask() { public ParallelTask() {
hidden = true; hidden = true;
@ -43,11 +43,11 @@ public class ParallelTask extends Task {
@Override @Override
public Collection<Task> getDependTasks() { public Collection<Task> getDependTasks() {
return dependsTask; return tasks;
} }
public void addDependsTask(Task t) { public void addTask(Task t) {
dependsTask.add(t); tasks.add(t);
} }
} }

View File

@ -23,15 +23,13 @@ package org.jackhuang.hellominecraft.util.tasks;
*/ */
public abstract class TaskInfo extends Task { public abstract class TaskInfo extends Task {
String info;
public TaskInfo(String info) { public TaskInfo(String info) {
this.info = info; this.tag = info;
} }
@Override @Override
public String getInfo() { public String getInfo() {
return info; return tag;
} }
} }

View File

@ -70,12 +70,10 @@ public class TaskWindow extends javax.swing.JDialog
return; return;
taskList = new TaskList(); taskList = new TaskList();
taskList.addTaskListener(this); taskList.addTaskListener(this);
taskList.doneEvent.register(() -> { taskList.doneEvent.register(SwingUtils.invokeLater(() -> {
SwingUtilities.invokeLater(() -> { dispose();
dispose(); suc = true;
suc = true; }));
});
});
} }
public static String downloadSource = ""; public static String downloadSource = "";

View File

@ -1,38 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.comm;
/**
*
* @author huangyuhui
* @param <T> the type of result.
*/
public class DefaultPreviousResult<T> implements PreviousResult<T> {
T a;
public DefaultPreviousResult(T a) {
this.a = a;
}
@Override
public T getResult() {
return a;
}
}

View File

@ -30,7 +30,7 @@ public interface PreviousResultRegistrar<T> {
* *
* @param pr previous task handler * @param pr previous task handler
* *
* @return task self instance * @return task self instance(factory mode!)
*/ */
Task registerPreviousResult(PreviousResult<T> pr); Task registerPreviousResult(PreviousResult<T> pr);
} }

View File

@ -1,31 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
import org.jackhuang.hellominecraft.util.tasks.ProgressProviderListener;
/**
*
* @author huangyuhui
*/
public interface DownloadListener extends ProgressProviderListener {
boolean OnFailed();
void OnFailedMoreThan5Times(String url);
}

View File

@ -130,12 +130,12 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
// Make sure response code is in the 200 range. // Make sure response code is in the 200 range.
if (con.getResponseCode() / 100 != 2) if (con.getResponseCode() / 100 != 2)
throw new NetException(C.i18n("download.not_200") + " " + con.getResponseCode()); throw new IOException(C.i18n("download.not_200") + " " + con.getResponseCode());
// Check for valid content length. // Check for valid content length.
int contentLength = con.getContentLength(); int contentLength = con.getContentLength();
if (contentLength < 1) if (contentLength < 1)
throw new NetException("The content length is invalid."); throw new IOException("The content length is invalid.");
if (!filePath.getParentFile().mkdirs() && !filePath.getParentFile().isDirectory()) if (!filePath.getParentFile().mkdirs() && !filePath.getParentFile().isDirectory())
throw new IOException("Could not make directory"); throw new IOException("Could not make directory");
@ -210,8 +210,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
if (ppl != null) if (ppl != null)
ppl.onProgressProviderDone(this); ppl.onProgressProviderDone(this);
return; return;
} catch (IOException | IllegalStateException | NetException e) { } catch (IOException | IllegalStateException e) {
setFailReason(new NetException(C.i18n("download.failed") + " " + url, e)); setFailReason(new IOException(C.i18n("download.failed") + " " + url, e));
} finally { } finally {
closeFiles(); closeFiles();
} }

View File

@ -85,7 +85,7 @@ public class HTTPGetTask extends Task implements PreviousResult<String> {
doneEvent.execute(result); doneEvent.execute(result);
return; return;
} catch (IOException ex) { } catch (IOException ex) {
t = new NetException("Failed to get " + url, ex); t = new IOException("Failed to get " + url, ex);
} }
} }
if (t != null) if (t != null)

View File

@ -1,38 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
/**
*
* @author huangyuhui
*/
public class NetException extends RuntimeException {
public NetException(Exception message) {
super(message);
}
public NetException(String message) {
super(message);
}
public NetException(String message, Exception e) {
super(message, e);
}
}

View File

@ -51,12 +51,9 @@ public class LogWindowOutputStream extends OutputStream {
} }
private void append(final String str) { private void append(final String str) {
try { SwingUtilities.invokeLater(() -> {
SwingUtilities.invokeLater(() -> { txt.log(str, Level.guessLevel(str, sas));
txt.log(str, Level.guessLevel(str, sas)); });
});
} catch (Throwable ignore) {
}
} }
@Override @Override

View File

@ -41,6 +41,7 @@ import javax.swing.JScrollBar;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog; import org.jackhuang.hellominecraft.util.logging.HMCLog;
@ -55,58 +56,58 @@ import org.jackhuang.hellominecraft.util.system.OS;
* @author huang * @author huang
*/ */
public final class SwingUtils { public final class SwingUtils {
private SwingUtils() { private SwingUtils() {
} }
/** /**
* Make DefaultTableModel by overriding getColumnClass and isCellEditable of * Make DefaultTableModel by overriding getColumnClass and isCellEditable of
* DefaultTableModel. * DefaultTableModel.
* *
* @param titleA The title of each column. * @param titleA The title of each column.
* @param typesA The type of each column value. * @param typesA The type of each column value.
* @param canEditA Is column editable? * @param canEditA Is column editable?
* *
* @return * @return
*/ */
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) { public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
return new DefaultTableModel( return new DefaultTableModel(
new Object[][] {}, new Object[][] {},
titleA) { titleA) {
Class[] types = typesA; Class[] types = typesA;
boolean[] canEdit = canEditA; boolean[] canEdit = canEditA;
@Override @Override
public Class getColumnClass(int columnIndex) { public Class getColumnClass(int columnIndex) {
return types[columnIndex]; return types[columnIndex];
} }
@Override @Override
public boolean isCellEditable(int rowIndex, int columnIndex) { public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit[columnIndex]; return canEdit[columnIndex];
} }
}; };
} }
public static void openFolder(File f) { public static void openFolder(File f) {
f.mkdirs(); f.mkdirs();
String path = f.getAbsolutePath(); String path = f.getAbsolutePath();
switch (OS.os()) { switch (OS.os()) {
case OSX: case OSX:
try { try {
Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path }); Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path });
} catch (IOException ex) { } catch (IOException ex) {
HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex); HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex);
} }
break; break;
default: default:
try { try {
java.awt.Desktop.getDesktop().open(f); java.awt.Desktop.getDesktop().open(f);
} catch (Throwable ex) { } catch (Throwable ex) {
MessageBox.show(C.i18n("message.cannot_open_explorer") + ex.getMessage()); MessageBox.show(C.i18n("message.cannot_open_explorer") + ex.getMessage());
HMCLog.warn("Failed to open " + path + " through java.awt.Desktop.getDesktop().open()", ex); HMCLog.warn("Failed to open " + path + " through java.awt.Desktop.getDesktop().open()", ex);
} }
break; break;
} }
} }
@ -165,18 +166,18 @@ public final class SwingUtils {
/** /**
* Append new element to JList * Append new element to JList
* *
* @param list the JList * @param list the JList
* @param element the Element * @param element the Element
*/ */
public static void appendLast(JList list, Object element) { public static void appendLast(JList list, Object element) {
getDefaultListModel(list).addElement(element); getDefaultListModel(list).addElement(element);
} }
public static void replaceLast(JList list, Object element) { public static void replaceLast(JList list, Object element) {
DefaultListModel model = getDefaultListModel(list); DefaultListModel model = getDefaultListModel(list);
model.set(model.getSize() - 1, element); model.set(model.getSize() - 1, element);
} }
public static void clear(JList list) { public static void clear(JList list) {
list.setModel(new DefaultListModel()); list.setModel(new DefaultListModel());
} }
@ -194,17 +195,17 @@ public final class SwingUtils {
model.removeRow(0); model.removeRow(0);
return model; return model;
} }
public static void appendLast(JTable table, Object... elements) { public static void appendLast(JTable table, Object... elements) {
DefaultTableModel model = (DefaultTableModel) table.getModel(); DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(elements); model.addRow(elements);
} }
public static void setValueAt(JTable table, Object element, int row, int col) { public static void setValueAt(JTable table, Object element, int row, int col) {
DefaultTableModel model = (DefaultTableModel) table.getModel(); DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setValueAt(element, row, col); model.setValueAt(element, row, col);
} }
public static Object[] getValueBySelectedRow(JTable table, int rows[], int col) { public static Object[] getValueBySelectedRow(JTable table, int rows[], int col) {
DefaultTableModel model = (DefaultTableModel) table.getModel(); DefaultTableModel model = (DefaultTableModel) table.getModel();
Object[] ret = new Object[rows.length]; Object[] ret = new Object[rows.length];
@ -212,12 +213,12 @@ public final class SwingUtils {
ret[i] = model.getValueAt(rows[i], col); ret[i] = model.getValueAt(rows[i], col);
return ret; return ret;
} }
public static void removeRow(JTable table, int row) { public static void removeRow(JTable table, int row) {
DefaultTableModel model = (DefaultTableModel) table.getModel(); DefaultTableModel model = (DefaultTableModel) table.getModel();
model.removeRow(row); model.removeRow(row);
} }
public static String getParsedJPanelText(JLabel jLabel1, String longString) { public static String getParsedJPanelText(JLabel jLabel1, String longString) {
if (StrUtils.isBlank(longString)) if (StrUtils.isBlank(longString))
return longString; return longString;
@ -239,11 +240,11 @@ public final class SwingUtils {
} }
return builder.toString(); return builder.toString();
} }
private static final Map<Integer, Object> INVOKE_AND_WAIT_MAP = Collections.synchronizedMap(new HashMap<>()); private static final Map<Integer, Object> INVOKE_AND_WAIT_MAP = Collections.synchronizedMap(new HashMap<>());
private static int INVOKE_AND_WAIT_ID = 0; private static int INVOKE_AND_WAIT_ID = 0;
private static final Object INVOKE_AND_WAIT_LOCK = new Object(); private static final Object INVOKE_AND_WAIT_LOCK = new Object();
public static <T> T invokeAndWait(NonFunction<T> x) { public static <T> T invokeAndWait(NonFunction<T> x) {
int id; int id;
synchronized (INVOKE_AND_WAIT_LOCK) { synchronized (INVOKE_AND_WAIT_LOCK) {
@ -254,7 +255,7 @@ public final class SwingUtils {
invokeAndWait(r); invokeAndWait(r);
return (T) INVOKE_AND_WAIT_MAP.remove(id); return (T) INVOKE_AND_WAIT_MAP.remove(id);
} }
public static void invokeAndWait(Runnable r) { public static void invokeAndWait(Runnable r) {
if (EventQueue.isDispatchThread()) if (EventQueue.isDispatchThread())
r.run(); r.run();
@ -266,7 +267,7 @@ public final class SwingUtils {
r.run(); r.run();
} }
} }
public static int select(String[] selList, String msg) { public static int select(String[] selList, String msg) {
Object msgs[] = new Object[2]; Object msgs[] = new Object[2];
msgs[0] = msg; msgs[0] = msg;
@ -276,7 +277,7 @@ public final class SwingUtils {
return -1; return -1;
return ((JComboBox) msgs[1]).getSelectedIndex(); return ((JComboBox) msgs[1]).getSelectedIndex();
} }
public static void setEnabled(JComponent component, boolean t) { public static void setEnabled(JComponent component, boolean t) {
synchronized (component.getTreeLock()) { synchronized (component.getTreeLock()) {
for (Component c : component.getComponents()) for (Component c : component.getComponents())
@ -285,11 +286,11 @@ public final class SwingUtils {
} }
component.setEnabled(t); component.setEnabled(t);
} }
public static void exitIfNoWindow(Window thisFrame) { public static void exitIfNoWindow(Window thisFrame) {
exitIfNoWindow(thisFrame, false); exitIfNoWindow(thisFrame, false);
} }
public static void exitIfNoWindow(Window thisFrame, boolean neededDispose) { public static void exitIfNoWindow(Window thisFrame, boolean neededDispose) {
boolean flag = false; boolean flag = false;
for (Window f : Window.getWindows()) { for (Window f : Window.getWindows()) {
@ -308,11 +309,11 @@ public final class SwingUtils {
else else
thisFrame.dispose(); thisFrame.dispose();
} }
public static ImageIcon scaleImage(ImageIcon i, int x, int y) { public static ImageIcon scaleImage(ImageIcon i, int x, int y) {
return new ImageIcon(i.getImage().getScaledInstance(x, y, Image.SCALE_SMOOTH)); return new ImageIcon(i.getImage().getScaledInstance(x, y, Image.SCALE_SMOOTH));
} }
public static ImageIcon searchBackgroundImage(ImageIcon init, String bgpath, int width, int height) { public static ImageIcon searchBackgroundImage(ImageIcon init, String bgpath, int width, int height) {
Random r = new Random(); Random r = new Random();
boolean loaded = false; boolean loaded = false;
@ -362,9 +363,15 @@ public final class SwingUtils {
HMCLog.log("Prepared background image in background.jpg."); HMCLog.log("Prepared background image in background.jpg.");
} }
} }
if (background == null) if (background == null)
return init; return init;
return background; return background;
} }
public static Runnable invokeLater(Runnable r) {
return () -> {
SwingUtilities.invokeLater(r);
};
}
} }

View File

@ -1,31 +1,26 @@
# Hello Minecraft! Launcher [![Build Status](https://travis-ci.org/huanghongxun/HMCL.svg?branch=master)](https://travis-ci.org/huanghongxun/HMCL) # Hello Minecraft! Launcher [![Build Status](https://travis-ci.org/huanghongxun/HMCL.svg?branch=master)](https://travis-ci.org/huanghongxun/HMCL)
开源协议为GPL v3, 详情参见http://www.gnu.org/licenses/gpl.html 开源协议为GPL v3, 详情参见http://www.gnu.org/licenses/gpl.html
## 介绍 ## Introduction
HMCL是一个Minecraft启动器支持Mod管理游戏定制自动安装整合包制作界面主题定制等功能。 HMCL is a Minecraft launcher which supports Mod management, game customizing, auto installing(Forge, LiteLoader and OptiFine), modpack creating, UI customizing and so on.
并且一天的使用次数在工作日时有40万左右、节假日有150万左右的使用次数也就是说日活跃用户在10万以上。
但是本项目的代码不够完善希望有更多的人能加入HMCL的开发。
## 贡献 ## Contribution
如果你很想为本项目贡献代码,这里有一些要求: If you want to submit a pull request, there're some requirements:
* 开发环境为Netbeans 8.1 * IDE: Netbeans 8.1
* 编译器为Java 1.8通过retrolambda兼容Java 1.7所以请不要使用Java 8的新API如Stream * Compiler: Java 1.8 and libraries only supports Java 1.7(because of retrolambda).
* 请不要修改`gradle`文件 * Do NOT modify `gradle` files.
## 代码 ## Code
* `org.jackhuang.hellominecraft.util` 为HMCL和HMCSM的共用工具代码 * package `org.jackhuang.hellominecraft.util`: HMCL development utilities.
* `org.jackhuang.hellominecraft.launcher` 包含了HMCL的界面以及逻辑代码 * package `org.jackhuang.hellominecraft.launcher`: HMCL UI core.
* `org.jackhuang.hellominecraft.launcher.core` 为HMCL的启动核心 * package `org.jackhuang.hellominecraft.launcher.core`: HMCL game launcher core.
* `org.jackhuang.hellominecraft.launcher.api` 是HMCL为了便于定制提供的API暂不支持加载插件 * package `org.jackhuang.hellominecraft.launcher.api`: Nothing here!
* `org.jackhuang.hellominecraft.svrmgr` 为HMCSM的所有代码 * package `org.jackhuang.hellominecraft.svrmgr`: All HMCSM codes.
* 文件夹 `HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang` 包含了HMCL和HMCSM使用的语言文件 * Folder `HMCUtils/src/main/resources/org/jackhuang/hellominecraft/lang` contains language files.
由于包树已经相当清晰,因此不再赘述各包各类的用途。 ## Pay Attention
* When you do decide to modify this app, please and you MUST delete `org.jackhuang.hellominecraft.launcher.util.CrashReporter`, or errors your code cause will be sent to my server.
## 注意事项 * package `org.jackhuang.hellominecraft.util.logging`: repackaged Apache Log4j, Apache License 2.0.
* 包 `org.jackhuang.hellominecraft.util.logging` 包含了经过精简的Apache License 2.0的Log4j项目的代码 * package `com.google.gson`: Apache License 2.0
* 包 `com.google.gson` 为Google Gson项目Apache License 2.0的代码 * package `org.jackhuang.hellominecraft.lookandfeel.ui`: contains some NimbusLAF's code belonging to Sun Microsystems under LGPL.
* 包 `org.jackhuang.hellominecraft.lookandfeel.ui` 包含了Sun Microsystems的NimbusLookAndFeel项目的部分LGPL代码
* 所有Pull Request提交的代码均会被重写
* 本项目的开源协议是GPL v3因此包含LGPL和Apache License 2.0的代码是没有法律问题的