Reconstruct codes

This commit is contained in:
huanghongxun
2015-12-15 21:39:53 +08:00
parent b3fb372e3b
commit 713a0171cc
25 changed files with 546 additions and 285 deletions

View File

@@ -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;
});
}
}
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);
}
}
}