2
0
mirror of https://github.com/HMCL-dev/HMCL.git synced 2025-02-23 17:19:44 +08:00

Might fix game log watcher?

This commit is contained in:
huangyuhui 2016-02-16 18:57:26 +08:00
parent cb125b83cb
commit afecb87c6d
29 changed files with 280 additions and 223 deletions

View File

@ -26,16 +26,11 @@ import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.ui.LogWindow;
import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer;
import org.jackhuang.hellominecraft.util.DoubleOutputStream;
import org.jackhuang.hellominecraft.util.LauncherPrintStream;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.Utils;
/**
*
@ -69,14 +64,6 @@ public final class Launcher {
int len = tokenized.length;
if (showInfo) {
LogWindow.INSTANCE.setTerminateGame(() -> {
try {
Utils.shutdownForcely(1);
} catch (Exception e) {
MessageBox.Show(C.i18n("launcher.exit_failed"));
HMCLog.err("Failed to shutdown forcely", e);
}
});
try {
File logFile = new File("hmclmc.log");
if (!logFile.exists() && !logFile.createNewFile())
@ -95,7 +82,6 @@ public final class Launcher {
LOGGER.log(Level.INFO, "Arguments: '{'\n{0}\n'}'", StrUtils.parseParams(" ", args, "\n"));
LOGGER.log(Level.INFO, "Main Class: {0}", mainClass);
LOGGER.log(Level.INFO, "Class Path: '{'\n{0}\n'}'", StrUtils.parseParams(" ", tokenized, "\n"));
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
}
URL[] urls = new URL[len];
@ -104,7 +90,6 @@ public final class Launcher {
for (int j = 0; j < len; j++)
urls[j] = new File(tokenized[j]).toURI().toURL();
} catch (Throwable e) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
LOGGER.log(Level.SEVERE, "Failed to get classpath.", e);
return;
}
@ -115,48 +100,21 @@ public final class Launcher {
try {
minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
LOGGER.log(Level.SEVERE, "Minecraft main class not found.", t);
return;
}
LOGGER.info("*** Launching Game ***");
int flag = 0;
try {
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
} catch (Throwable throwable) {
String trace = StrUtils.getStackTrace(throwable);
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
System.err.println(C.i18n("crash.minecraft"));
System.err.println(advice);
System.err.println(MinecraftCrashAdvicer.getAdvice(trace));
System.err.println(trace);
LogWindow.INSTANCE.setExit(() -> true);
LogWindow.INSTANCE.setVisible(true);
flag = 1;
}
LOGGER.info("*** Game Exited ***");
try {
Utils.shutdownForcely(flag);
} catch (Exception e) {
MessageBox.Show(C.i18n("launcher.exit_failed"));
HMCLog.err("Failed to shutdown forcely", e);
}
LOGGER.info("*** Game exited ***");
}
/*
* static Object getShutdownHaltLock() {
* try {
* Class z = Class.forName("java.lang.Shutdown");
* Field haltLock = z.getDeclaredField("haltLock");
* haltLock.setAccessible(true);
* return haltLock.get(null);
* } catch (Throwable ex) {
* ex.printStackTrace();
* return new Object();
* }
* }
*/
}

View File

@ -18,6 +18,7 @@
package org.jackhuang.hellominecraft.launcher.core.download;
import java.io.File;
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
@ -26,12 +27,13 @@ import org.jackhuang.hellominecraft.util.system.IOUtils;
*/
public class DownloadLibraryJob {
public String url, name;
public IMinecraftLibrary lib;
public String url;
public File path;
public DownloadLibraryJob(String n, String u, File p) {
public DownloadLibraryJob(IMinecraftLibrary n, String u, File p) {
url = u;
name = n;
lib = n;
path = IOUtils.tryGetCanonicalFile(p);
}
}

View File

@ -65,7 +65,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/";
libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType()));
if (libURL != null)
downloadLibraries.add(new DownloadLibraryJob(l.name, libURL, ff));
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
}
}
}
@ -100,7 +100,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
return;
}
String jarURL = vurl + id + ".jar", hash = null;
if (mv != null && mv.downloads != null && service.getDownloadType().getProvider().isAllowedToUseSelfURL()) {
if (mv.downloads != null && service.getDownloadType().getProvider().isAllowedToUseSelfURL()) {
GameDownloadInfo gdi = mv.downloads.get("client");
if (gdi != null) {
if (gdi.url != null)

View File

@ -17,7 +17,9 @@
*/
package org.jackhuang.hellominecraft.launcher.core.download;
import java.util.Locale;
import org.jackhuang.hellominecraft.launcher.core.install.InstallerVersionList;
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
/**
*
@ -72,7 +74,15 @@ public class MojangDownloadProvider extends IDownloadProvider {
@Override
public String getParsedLibraryDownloadURL(String str) {
return str;
if (str == null)
return null;
else if (str.contains("typesafe"))
if (SupportedLocales.NOW_LOCALE.self == Locale.CHINA)
return str.replace("http://files.minecraftforge.net/maven", "http://maven.oschina.net/content/groups/public");
else
return str.replace("http://files.minecraftforge.net/maven", "http://repo1.maven.org/maven2");
else
return str;
}
}

View File

@ -43,9 +43,9 @@ public class DefaultGameLauncher extends GameLauncher {
ParallelTask parallelTask = new ParallelTask();
HashSet<String> names = new HashSet<>();
for (DownloadLibraryJob s : t) {
if (names.contains(s.name))
if (names.contains(s.lib.name))
continue;
names.add(s.name);
names.add(s.lib.name);
parallelTask.addDependsTask(new LibraryDownloadTask(s));
}
dw.append(parallelTask);

View File

@ -128,7 +128,7 @@ public class GameLauncher {
ProcessBuilder builder = new ProcessBuilder(str);
if (options.getLaunchVersion() == null || service.baseDirectory() == null)
throw new Error("Fucking bug!");
builder.directory(service.version().getRunDirectory(options.getLaunchVersion()))
builder.redirectErrorStream(true).directory(service.version().getRunDirectory(options.getLaunchVersion()))
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
HMCLog.log("The game process have been started");

View File

@ -38,13 +38,14 @@ public class LibraryDownloadTask extends FileDownloadTask {
@Override
public void executeTask() throws Throwable {
if (job.name.startsWith("net.minecraftforge:forge:")) {
String[] s = job.name.split(":");
String name = job.lib.name;
if (name.startsWith("net.minecraftforge:forge:")) {
String[] s = name.split(":");
if (s.length == 3)
job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar";
}
if (job.name.startsWith("com.mumfrey:liteloader:")) {
String[] s = job.name.split(":");
if (name.startsWith("com.mumfrey:liteloader:")) {
String[] s = name.split(":");
if (s.length == 3 && s[2].length() > 3)
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
}
@ -59,7 +60,7 @@ public class LibraryDownloadTask extends FileDownloadTask {
@Override
public String getInfo() {
return C.i18n("download") + ": " + job.name;
return C.i18n("download") + ": " + job.lib.name;
}
}

View File

@ -21,9 +21,17 @@ package org.jackhuang.hellominecraft.launcher.core.version;
*
* @author huangyuhui
*/
public class GameDownloadInfo {
public class GameDownloadInfo implements Cloneable {
public String sha1, url;
public int size;
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException ex) {
throw new Error(ex);
}
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.launcher.core.version;
/**
*
* @author huangyuhui
*/
public class LibraryDownloadInfo extends GameDownloadInfo {
public String path;
}

View File

@ -40,7 +40,7 @@ public class MinecraftLibrary extends IMinecraftLibrary {
super(name);
}
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract) {
public MinecraftLibrary(ArrayList<Rules> rules, String url, Natives natives, String name, Extract extract, LibraryDownloadInfo downloads) {
super(name);
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
this.url = url;

View File

@ -60,7 +60,8 @@ public class VersionSetting {
public VersionSetting() {
debug = fullscreen = canceledWrapper = false;
launcherVisibility = gameDirType = 0;
launcherVisibility = 1;
gameDirType = 0;
javaDir = java = minecraftArgs = serverIp = precalledCommand = "";
}

View File

@ -30,6 +30,7 @@ import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.system.JavaProcessMonitor;
import org.jackhuang.hellominecraft.util.ui.LogWindow;
import org.jackhuang.hellominecraft.util.ui.WebFrame;
/**
*
@ -71,15 +72,21 @@ public class LaunchingUIDaemon {
JavaProcessMonitor jpm = new JavaProcessMonitor(p);
jpm.applicationExitedAbnormallyEvent.register(t -> {
HMCLog.err("The game exited abnormally, exit code: " + t);
MessageBox.Show(C.i18n("launch.exited_abnormally") + ", exit code: " + t);
MessageBox.Show(C.i18n("launch.exited_abnormally") + " exit code: " + t);
WebFrame f = new WebFrame(jpm.getJavaProcess().getStdOutLines().toArray(new String[0]));
f.setTitle("Game output");
f.setVisible(true);
});
jpm.jvmLaunchFailedEvent.register(t -> {
HMCLog.err("Cannot create jvm, exit code: " + t);
MessageBox.Show(C.i18n("launch.cannot_create_jvm") + ", exit code: " + t);
MessageBox.Show(C.i18n("launch.cannot_create_jvm") + " exit code: " + t);
WebFrame f = new WebFrame(jpm.getJavaProcess().getStdOutLines().toArray(new String[0]));
f.setTitle("Game output");
f.setVisible(true);
});
jpm.stoppedEvent.register(() -> {
if ((LauncherVisibility) obj.getTag() != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("Without the option of keeping the launcher visible, this application will exit and will NOT catch game logs, but you can turn on \"Debug Mode\".");
if ((LauncherVisibility) obj.getTag() == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("With the option of closing the launcher anyway, the launcher will exit and will NOT catch game logs.");
System.exit(0);
}
});

View File

@ -48,7 +48,7 @@ import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.launcher.Main;
import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.lookandfeel.Theme;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;

View File

@ -37,7 +37,7 @@ import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton;
import org.jackhuang.hellominecraft.util.func.Consumer;

View File

@ -25,6 +25,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.StringTokenizer;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.func.Predicate;
/**
*
@ -115,6 +117,14 @@ public final class StrUtils {
return false;
}
public static boolean containsOne(List<String> base, List<String> match, Predicate<String> pred) {
for (String a : base)
for (String b : match)
if (pred.apply(a) && a.toLowerCase().contains(b.toLowerCase()))
return true;
return false;
}
public static int getCharShowTime(String s, char c) {
int res = 0;
for (int i = 0; i < s.length(); i++)
@ -141,33 +151,37 @@ public final class StrUtils {
return parseParams(addBefore, paramArrayOfObject.toArray(), paramString);
}
public static String parseParams(String addBefore, Object[] paramArrayOfObject, String paramString) {
if (paramArrayOfObject == null)
return "";
StringBuilder localStringBuffer = new StringBuilder();
for (int i = 0; i < paramArrayOfObject.length; i++) {
Object localObject = paramArrayOfObject[i];
if (i > 0)
localStringBuffer.append(addBefore).append(paramString);
if (localObject == null)
localStringBuffer.append("null");
else if (localObject.getClass().isArray()) {
localStringBuffer.append("[");
public static String parseParams(String addBefore, Object[] params, String addAfter) {
return parseParams(t -> addBefore, params, t -> addAfter);
}
if ((localObject instanceof Object[])) {
Object[] arrayOfObject = (Object[]) localObject;
localStringBuffer.append(parseParams(addBefore, arrayOfObject, paramString));
public static String parseParams(Function<Object, String> beforeFunc, Object[] params, Function<Object, String> afterFunc) {
if (params == null)
return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.length; i++) {
Object param = params[i];
String addBefore = beforeFunc.apply(param), addAfter = afterFunc.apply(param);
if (i > 0)
sb.append(addAfter).append(addBefore);
if (param == null)
sb.append("null");
else if (param.getClass().isArray()) {
sb.append("[");
if ((param instanceof Object[])) {
Object[] objs = (Object[]) param;
sb.append(parseParams(beforeFunc, objs, afterFunc));
} else
for (int j = 0; j < Array.getLength(localObject); j++) {
for (int j = 0; j < Array.getLength(param); j++) {
if (j > 0)
localStringBuffer.append(paramString);
localStringBuffer.append(addBefore).append(Array.get(localObject, j));
sb.append(addAfter);
sb.append(addBefore).append(Array.get(param, j));
}
localStringBuffer.append("]");
sb.append("]");
} else
localStringBuffer.append(addBefore).append(paramArrayOfObject[i]);
sb.append(addBefore).append(params[i]);
}
return localStringBuffer.toString();
return sb.toString();
}
public static boolean isEquals(String base, String to) {

View File

@ -30,7 +30,6 @@ public class JavaProcess {
private final List<String> commands;
private final Process process;
private final ArrayList<String> stdOutLines = new ArrayList<>();
private final ArrayList<String> stdErrLines = new ArrayList<>();
public JavaProcess(List<String> commands, Process process, ProcessManager pm) {
this.commands = commands;
@ -59,10 +58,6 @@ public class JavaProcess {
return this.stdOutLines;
}
public ArrayList<String> getStdErrLines() {
return this.stdErrLines;
}
public boolean isRunning() {
try {
this.process.exitValue();

View File

@ -20,9 +20,10 @@ package org.jackhuang.hellominecraft.util.system;
import java.util.Arrays;
import java.util.HashSet;
import org.jackhuang.hellominecraft.util.CollectionUtils;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.logging.Level;
/**
*
@ -51,31 +52,28 @@ public class JavaProcessMonitor {
this.p = p;
}
public JavaProcess getJavaProcess() {
return p;
}
public void start() {
Event<JavaProcess> event = (sender2, t) -> {
if (t.getExitCode() != 0)
ProcessThread a = new ProcessThread(p);
a.stopEvent.register((sender, t) -> {
HMCLog.log("Process exit code: " + t.getExitCode());
if (t.getExitCode() != 0 || StrUtils.containsOne(t.getStdOutLines(),
Arrays.asList("Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
applicationExitedAbnormallyEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender2, false);
if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(),
Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.",
"Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
jvmLaunchFailedEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender, false);
return true;
};
Event<JavaProcess> event2 = (sender3, p1) -> {
if (p1.getExitCode() != 0 && p1.getStdErrLines().size() > 0 && StrUtils.containsOne(p1.getStdErrLines(), Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.")))
jvmLaunchFailedEvent.execute(p1.getExitCode());
processThreadStopped((ProcessThread) sender3, false);
return true;
};
ProcessThread a = new ProcessThread(p, true, true);
a.stopEvent.register(event2);
a.start();
al.add(a);
a = new ProcessThread(p, false, true);
a.stopEvent.register(event2);
a.start();
al.add(a);
a = new ProcessThread(p, false, false);
a.stopEvent.register(event);
});
a.start();
al.add(a);
}

View File

@ -30,15 +30,12 @@ import org.jackhuang.hellominecraft.util.EventHandler;
public class ProcessThread extends Thread {
JavaProcess p;
boolean readError = false, enableReading = true;
public final EventHandler<String> printlnEvent = new EventHandler<>(this);
public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this);
public ProcessThread(JavaProcess process, boolean readError, boolean enableReading) {
public ProcessThread(JavaProcess process) {
p = process;
this.readError = readError;
this.enableReading = enableReading;
}
public JavaProcess getProcess() {
@ -47,58 +44,33 @@ public class ProcessThread extends Thread {
@Override
public void run() {
setName("ProcessMonitor");
InputStreamReader br = null;
try {
InputStreamReader br;
if (enableReading) {
InputStream in = readError ? p.getRawProcess().getErrorStream() : p.getRawProcess().getInputStream();
try {
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
} catch (UnsupportedEncodingException ex) {
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
br = new InputStreamReader(in);
}
} else
br = null;
InputStream in = p.getRawProcess().getInputStream();
try {
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
} catch (UnsupportedEncodingException ex) {
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
br = new InputStreamReader(in);
}
int ch;
String line = "";
while (p.isRunning())
if (br != null)
while ((ch = br.read()) != -1)
if (ch == '\n') {
printlnEvent.execute(line);
if (readError) {
System.err.println(line);
p.getStdErrLines().add(line);
} else {
System.out.println(line);
p.getStdOutLines().add(line);
}
line = "";
} else
line += (char) ch;
else
try {
Thread.sleep(1);
} catch (Exception e) {
}
if (br != null)
while ((ch = br.read()) != -1)
if (ch == '\n') {
printlnEvent.execute(line);
if (readError) {
System.err.println(line);
p.getStdErrLines().add(line);
} else {
System.out.println(line);
p.getStdOutLines().add(line);
}
System.out.println("Minecraft: " + line);
p.getStdOutLines().add(line);
line = "";
} else
line += (char) ch;
stopEvent.execute(p);
} catch (Exception e) {
e.printStackTrace();
HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally {
IOUtils.closeQuietly(br);
}
}
}

View File

@ -1,4 +1,4 @@
package org.jackhuang.hellominecraft.lookandfeel;
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Color;
import java.awt.Graphics;
@ -28,23 +28,23 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* value of that hint is obtained from the Graphics and stored as the value
* for the key in savedHints.
*
* @param g2d the graphics surface
* @param g2d the graphics surface
* @param hintsToSave the list of rendering hints to set on the graphics
* @param savedHints a set where to save the previous rendering hints, might
* be null
* @param savedHints a set where to save the previous rendering hints,
* might
* be null
*
* @return the previous set of rendering hints
*/
public static RenderingHints getRenderingHints(Graphics2D g2d,
Map<?, ?> hintsToSave,
RenderingHints savedHints) {
if (savedHints == null) {
Map<?, ?> hintsToSave,
RenderingHints savedHints) {
if (savedHints == null)
savedHints = new RenderingHints(null);
} else {
else
savedHints.clear();
}
if (hintsToSave.isEmpty()) {
if (hintsToSave.isEmpty())
return savedHints;
}
/* RenderingHints.keySet() returns Set */
for (Object o : hintsToSave.keySet()) {
RenderingHints.Key key = (RenderingHints.Key) o;
@ -77,17 +77,16 @@ public class GraphicsUtils extends SynthGraphicsUtils {
} else {
oldAA = g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
super.paintText(ss, g, text, x, y, mnemonicIndex);
if (oldHints != null) {
if (oldHints != null)
g2.addRenderingHints(oldHints);
} else if (oldAA != null) {
else if (oldAA != null)
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
oldAA);
}
oldAA);
}
/**
@ -96,6 +95,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* so that it can safely be used in a static context.
*
* @param imgName The name of the image to load, eg. "border.png"
*
* @return The loaded image
*/
public static BufferedImage loadImage(String imgName) {
@ -108,21 +108,25 @@ public class GraphicsUtils extends SynthGraphicsUtils {
return null;
}
public static String getColor(Color c) {
return Integer.toHexString(c.getRGB() & 0xFFFFFF);
}
/**
* Get a Color object from a web color string of the form "FF00AB" or
* "#FF00AB".
*
* @param c The color string
*
* @return The Color described
*/
public static Color getWebColor(String c) {
if (c.startsWith("#")) {
if (c.startsWith("#"))
c = c.substring(1);
}
return new Color(
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16)
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16)
);
}
@ -131,17 +135,17 @@ public class GraphicsUtils extends SynthGraphicsUtils {
* "#FF00AB".
*
* @param c The color string
*
* @return The Color described
*/
public static Color getWebColorWithAlpha(String c) {
if (c.startsWith("#")) {
if (c.startsWith("#"))
c = c.substring(1);
}
return new Color(
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16),
Integer.parseInt(c.substring(6, 8), 16)
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16),
Integer.parseInt(c.substring(6, 8), 16)
);
}
@ -151,6 +155,7 @@ public class GraphicsUtils extends SynthGraphicsUtils {
*
* @param c1 The first color string
* @param c2 The second color string
*
* @return The Color middle color
*/
public static Color getMidWebColor(String c1, String c2) {
@ -163,15 +168,14 @@ public class GraphicsUtils extends SynthGraphicsUtils {
*
* @param c1 The first color string
* @param c2 The second color string
*
* @return The Color middle color
*/
public static Color getMidWebColor(String c1, String c2, int percent) {
if (c1.startsWith("#")) {
if (c1.startsWith("#"))
c1 = c1.substring(1);
}
if (c2.startsWith("#")) {
if (c2.startsWith("#"))
c2 = c2.substring(1);
}
int rTop = Integer.parseInt(c1.substring(0, 2), 16);
int gTop = Integer.parseInt(c1.substring(2, 4), 16);
int bTop = Integer.parseInt(c1.substring(4, 6), 16);

View File

@ -33,31 +33,6 @@ public class LogWindowOutputStream extends OutputStream {
private final LogWindow txt;
private final Level sas;
/*
* private final CacheTask t = new CacheTask();
* private class CacheTask extends TimerTask {
* private final Object lock = new Object();
* private StringBuilder cachedString = new StringBuilder();
*
* @Override
* public void run() {
* synchronized(lock) {
* SwingUtilities.invokeLater(() -> {
* String t = txt.getText() + cachedString.toString().replace("\t", " ");
* txt.setText(t);
* txt.setCaretPosition(t.length());
* cachedString = new StringBuilder();
* });
* }
* }
*
* void cache(String s) {
* synchronized(lock) {
* cachedString.append(s);
* }
* }
* }
*/
public LogWindowOutputStream(LogWindow logWindow, Level l) {
txt = logWindow;
this.sas = l;

View File

@ -0,0 +1,85 @@
/*
* 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.util.ui;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.List;
import javax.swing.JFrame;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.logging.Level;
/**
*
* @author huangyuhui
*/
public class WebFrame extends JFrame {
public WebFrame(String... strs) {
this(("<html>" + StrUtils.parseParams(t -> ("<font color='#" + GraphicsUtils.getColor(Level.guessLevel((String) t, Level.INFO).COLOR) + "'>"), strs, t -> "</font><br />") + "</html>")
.replace(" ", "&nbsp;").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;"));
}
public WebFrame(String content) throws HeadlessException {
addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
boolean flag = false;
for (Frame f : Frame.getFrames()) {
if (f == WebFrame.this)
continue;
if (f.isVisible())
flag = true;
}
if (!flag)
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
add(new WebPage(content));
pack();
setLocationRelativeTo(null);
}
}

View File

@ -17,7 +17,7 @@
package org.jackhuang.hellominecraft.lookandfeel.comp;
import java.awt.Color;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
/**
*

View File

@ -30,7 +30,7 @@ import javax.swing.SwingUtilities;
import javax.swing.plaf.synth.SynthConstants;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthPainter;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import org.jackhuang.hellominecraft.lookandfeel.comp.ConstomButton;
/**

View File

@ -20,7 +20,7 @@
*/
package org.jackhuang.hellominecraft.lookandfeel.painter;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthPainter;

View File

@ -25,7 +25,7 @@ import javax.swing.plaf.synth.SynthPainter;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.plaf.synth.SynthConstants;
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
import org.jackhuang.hellominecraft.util.ui.GraphicsUtils;
/**
* TextFieldPainter

View File

@ -1,6 +1,6 @@
package org.jackhuang.hellominecraft.lookandfeel.ui;
import static org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils.loadImage;
import static org.jackhuang.hellominecraft.util.ui.GraphicsUtils.loadImage;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboBoxUI;

View File

@ -4,7 +4,7 @@
*/
package org.jackhuang.hellominecraft.lookandfeel.ui;
import static org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils.loadImage;
import static org.jackhuang.hellominecraft.util.ui.GraphicsUtils.loadImage;
import javax.swing.JButton;
import javax.swing.JComponent;

View File

@ -26,7 +26,7 @@
<color value="#9CC5D8" type="TEXT_BACKGROUND"/>
<font name="微软雅黑" size="12" />
</state>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
<graphicsUtils idref="GraphicsUtils"/>
</style>
<bind style="default" type="region" key=".*"/>

View File

@ -26,7 +26,7 @@
<color value="#9CC5D8" type="TEXT_BACKGROUND"/>
<font name="微软雅黑" size="12" />
</state>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils"/>
<object id="GraphicsUtils" class="org.jackhuang.hellominecraft.util.ui.GraphicsUtils"/>
<graphicsUtils idref="GraphicsUtils"/>
</style>
<bind style="default" type="region" key=".*"/>