Reconstruct codes
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -300,28 +299,16 @@ public class TaskWindow extends javax.swing.JDialog
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
Runnable r = () -> {
|
||||
return SwingUtils.invokeAndWait(() -> {
|
||||
synchronized (INSTANCE) {
|
||||
if (INSTANCE.isVisible()) {
|
||||
flag = false;
|
||||
return;
|
||||
}
|
||||
if (INSTANCE.isVisible())
|
||||
return false;
|
||||
TaskWindow tw = inst();
|
||||
for (Task t : ll)
|
||||
tw.addTask(t);
|
||||
flag = tw.start();
|
||||
return tw.start();
|
||||
}
|
||||
};
|
||||
if (EventQueue.isDispatchThread())
|
||||
r.run();
|
||||
else
|
||||
try {
|
||||
EventQueue.invokeAndWait(r);
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to invokeAndWait, the UI will work abnormally.", e);
|
||||
r.run();
|
||||
}
|
||||
return flag;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* 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.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface IUpdateChecker {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void checkOutdate();
|
||||
|
||||
/**
|
||||
* Get the <b>cached</b> newest version number, use "process" method to download!
|
||||
* @return the newest version number
|
||||
* @see process
|
||||
*/
|
||||
VersionNumber getNewVersion();
|
||||
|
||||
/**
|
||||
* Download the version number synchronously.
|
||||
* When you execute this method first, should leave "showMessage" false.
|
||||
* @param showMessage If it is requested to warn the user that there is a new version.
|
||||
* @return the process observable.
|
||||
*/
|
||||
Observable process(boolean showMessage);
|
||||
|
||||
/**
|
||||
* Get the download links.
|
||||
* @return a JSON, which contains the server response.
|
||||
*/
|
||||
Observable<Map<String, String>> requestDownloadLink();
|
||||
|
||||
}
|
||||
@@ -97,9 +97,9 @@ public class MessageBox {
|
||||
case YES_NO_OPTION:
|
||||
case YES_NO_CANCEL_OPTION:
|
||||
case OK_CANCEL_OPTION:
|
||||
return JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10);
|
||||
return SwingUtils.invokeAndWait(() -> JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10));
|
||||
default:
|
||||
JOptionPane.showMessageDialog(null, Msg, Title, Option);
|
||||
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, Msg, Title, Option));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -52,4 +53,28 @@ public class Pair<K, V> implements Map.Entry<K, V> {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 29 * hash + Objects.hashCode(this.key);
|
||||
hash = 29 * hash + Objects.hashCode(this.value);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||
if (!Objects.equals(this.key, other.key))
|
||||
return false;
|
||||
if (!Objects.equals(this.value, other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.FontMetrics;
|
||||
import java.net.URI;
|
||||
import javax.swing.DefaultListModel;
|
||||
@@ -28,6 +29,7 @@ import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.functions.NonFunction;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,8 +49,8 @@ public class SwingUtils {
|
||||
*/
|
||||
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
|
||||
return new DefaultTableModel(
|
||||
new Object[][] {},
|
||||
titleA) {
|
||||
new Object[][] {},
|
||||
titleA) {
|
||||
Class[] types = typesA;
|
||||
boolean[] canEdit = canEditA;
|
||||
|
||||
@@ -131,7 +133,7 @@ public class SwingUtils {
|
||||
* Clear the JTable
|
||||
*
|
||||
* @param table JTable with DefaultTableModel.
|
||||
*
|
||||
*
|
||||
* @return To make the code succinct
|
||||
*/
|
||||
public static DefaultTableModel clearDefaultTable(JTable table) {
|
||||
@@ -177,4 +179,24 @@ public class SwingUtils {
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static final ThreadLocal<Object> THREAD_LOCAL = new ThreadLocal<>();
|
||||
|
||||
public static <T> T invokeAndWait(NonFunction<T> x) {
|
||||
Runnable r = () -> THREAD_LOCAL.set(x.apply());
|
||||
invokeAndWait(r);
|
||||
return (T) THREAD_LOCAL.get();
|
||||
}
|
||||
|
||||
public static void invokeAndWait(Runnable r) {
|
||||
if (EventQueue.isDispatchThread())
|
||||
r.run();
|
||||
else
|
||||
try {
|
||||
EventQueue.invokeAndWait(r);
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to invokeAndWait, the UI will work abnormally.", e);
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,66 +20,74 @@ package org.jackhuang.hellominecraft.utils;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class UpdateChecker extends Thread {
|
||||
|
||||
public static boolean OUT_DATED = false;
|
||||
public final class UpdateChecker implements IUpdateChecker {
|
||||
|
||||
public boolean OUT_DATED = false;
|
||||
public VersionNumber base;
|
||||
public String versionString;
|
||||
public String type;
|
||||
public Runnable dl;
|
||||
public Map<String, String> download_link = null;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type, Runnable dl) {
|
||||
super("UpdateChecker");
|
||||
private Map<String, String> download_link = null;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type) {
|
||||
this.base = base;
|
||||
this.type = type;
|
||||
this.dl = dl;
|
||||
}
|
||||
|
||||
|
||||
VersionNumber value;
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update url.", e);
|
||||
return;
|
||||
}
|
||||
value = VersionNumber.check(versionString);
|
||||
process(false);
|
||||
if (OUT_DATED)
|
||||
dl.run();
|
||||
public Observable<VersionNumber> process(boolean showMessage) {
|
||||
return Observable.createWithEmptySubscription(t -> {
|
||||
if (value == null) {
|
||||
try {
|
||||
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update url.", e);
|
||||
return;
|
||||
}
|
||||
value = VersionNumber.check(versionString);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.Show(C.i18n("update.failed"));
|
||||
} else if (VersionNumber.isOlder(base, value))
|
||||
OUT_DATED = true;
|
||||
if (OUT_DATED)
|
||||
t.onNext(value);
|
||||
});
|
||||
}
|
||||
|
||||
public void process(boolean showMessage) {
|
||||
if (value == null) {
|
||||
HMCLog.warn("Failed to check update...");
|
||||
if (showMessage)
|
||||
MessageBox.Show(C.i18n("update.failed"));
|
||||
} else if (VersionNumber.isOlder(base, value))
|
||||
OUT_DATED = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VersionNumber getNewVersion() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public synchronized void requestDownloadLink(Runnable finish) {
|
||||
new Thread(() -> {
|
||||
|
||||
@Override
|
||||
public synchronized Observable<Map<String, String>> requestDownloadLink() {
|
||||
return Observable.createWithEmptySubscription(t -> {
|
||||
if (download_link == null)
|
||||
try {
|
||||
download_link = C.gson.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update link.", e);
|
||||
}
|
||||
finish.run();
|
||||
}).start();
|
||||
t.onNext(download_link);
|
||||
});
|
||||
}
|
||||
|
||||
public final EventHandler<VersionNumber> outdated = new EventHandler<>(this);
|
||||
|
||||
@Override
|
||||
public void checkOutdate() {
|
||||
if (OUT_DATED)
|
||||
outdated.execute(getNewVersion());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,18 @@ import org.jackhuang.hellominecraft.HMCLog;
|
||||
*/
|
||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
|
||||
public byte firstVer, secondVer, thirdVer;
|
||||
public final byte firstVer, secondVer, thirdVer;
|
||||
public final String version;
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c) {
|
||||
this(a, b, c, null);
|
||||
}
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c, String version) {
|
||||
firstVer = a;
|
||||
secondVer = b;
|
||||
thirdVer = c;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static VersionNumber check(String data) {
|
||||
@@ -46,7 +52,7 @@ public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
v1 = Byte.parseByte(ver[0]);
|
||||
v2 = Byte.parseByte(ver[1]);
|
||||
v3 = Byte.parseByte(ver[2]);
|
||||
ur = new VersionNumber(v1, v2, v3);
|
||||
ur = new VersionNumber(v1, v2, v3, data);
|
||||
return ur;
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to parse the version", e);
|
||||
|
||||
@@ -112,6 +112,18 @@ public class IOUtils {
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static String getRealPath() {
|
||||
String realPath = IOUtils.class.getClassLoader().getResource("").getFile();
|
||||
java.io.File file = new java.io.File(realPath);
|
||||
realPath = file.getAbsolutePath();
|
||||
try {
|
||||
realPath = java.net.URLDecoder.decode(realPath, "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return realPath;
|
||||
}
|
||||
|
||||
public static File currentDir() {
|
||||
return new File(".");
|
||||
}
|
||||
@@ -219,19 +231,19 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
public static void write(byte[] data, OutputStream output)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (data != null)
|
||||
output.write(data);
|
||||
}
|
||||
|
||||
public static void write(String data, OutputStream output, String encoding)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (data != null)
|
||||
output.write(data.getBytes(encoding));
|
||||
}
|
||||
|
||||
public static FileInputStream openInputStream(File file)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory())
|
||||
throw new IOException("File '" + file + "' exists but is a directory");
|
||||
|
||||
@@ -26,7 +26,9 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.border.AbstractBorder;
|
||||
import org.jackhuang.hellominecraft.utils.Pair;
|
||||
|
||||
public class DropShadowBorder extends AbstractBorder {
|
||||
|
||||
@@ -61,29 +63,37 @@ public class DropShadowBorder extends AbstractBorder {
|
||||
return getBorderInsets(c);
|
||||
}
|
||||
|
||||
private static final HashMap<Pair<Integer, Integer>, BufferedImage> CACHE = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
BufferedImage shadow = new BufferedImage(width, height, 2);
|
||||
Pair<Integer, Integer> pair = new Pair<>(width, height);
|
||||
if (CACHE.containsKey(pair))
|
||||
g.drawImage(CACHE.get(pair), x, y, width, height, null);
|
||||
else {
|
||||
BufferedImage shadow = new BufferedImage(width, height, 2);
|
||||
|
||||
Graphics2D g2 = shadow.createGraphics();
|
||||
g2.setRenderingHints(this.hints);
|
||||
Composite oldComposite = g2.getComposite();
|
||||
AlphaComposite composite = AlphaComposite.getInstance(1, 0.0F);
|
||||
g2.setComposite(composite);
|
||||
g2.setColor(new Color(0, 0, 0, 0));
|
||||
g2.fillRect(0, 0, width, height);
|
||||
g2.setComposite(oldComposite);
|
||||
g2.setColor(this.color);
|
||||
int border = (int) (this.thickness * 4);
|
||||
g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2);
|
||||
g2.dispose();
|
||||
Graphics2D g2 = shadow.createGraphics();
|
||||
g2.setRenderingHints(this.hints);
|
||||
Composite oldComposite = g2.getComposite();
|
||||
AlphaComposite composite = AlphaComposite.getInstance(1, 0.0F);
|
||||
g2.setComposite(composite);
|
||||
g2.setColor(new Color(0, 0, 0, 0));
|
||||
g2.fillRect(0, 0, width, height);
|
||||
g2.setComposite(oldComposite);
|
||||
g2.setColor(this.color);
|
||||
int border = (int) (this.thickness * 4);
|
||||
g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2);
|
||||
g2.dispose();
|
||||
|
||||
FastBlurFilter blur = new FastBlurFilter(this.thickness);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
FastBlurFilter blur = new FastBlurFilter(this.thickness);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
shadow = blur.filter(shadow, null);
|
||||
|
||||
g.drawImage(shadow, x, y, width, height, null);
|
||||
CACHE.put(pair, shadow);
|
||||
g.drawImage(shadow, x, y, width, height, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user