From 0f390e63d38c5d054a5bd0e1faa208fd8abe810a Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Thu, 2 Mar 2017 13:18:25 +0800 Subject: [PATCH] Add progress of installing and game downloading --- HMCL/build.gradle | 2 +- .../jackhuang/hmcl/ui/GameDownloadPanel.java | 27 +++++- .../org/jackhuang/hmcl/ui/InstallerPanel.java | 38 ++++++-- .../download/MinecraftRemoteVersions.java | 14 ++- .../jackhuang/hmcl/util/task/DoubleTask.java | 7 ++ .../org/jackhuang/hmcl/util/task/Task.java | 12 ++- .../hmcl/laf/tab/BETabbedPaneUI.java | 46 ---------- .../jackhuang/hmcl/laf/utils/TMSchema.java | 91 +------------------ 8 files changed, 88 insertions(+), 149 deletions(-) diff --git a/HMCL/build.gradle b/HMCL/build.gradle index 3a3ebe2ae..985eef81f 100755 --- a/HMCL/build.gradle +++ b/HMCL/build.gradle @@ -42,7 +42,7 @@ buildnumber = "0" def versionroot = System.getenv("VERSION_ROOT") if (versionroot == null) -versionroot = "2.7.5" +versionroot = "2.7.6" String mavenGroupId = 'HMCL' String mavenVersion = versionroot + '.' + buildnumber diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/GameDownloadPanel.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/GameDownloadPanel.java index 00c3d31df..cc7ab80ba 100755 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/GameDownloadPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/GameDownloadPanel.java @@ -25,6 +25,8 @@ import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.util.C; import org.jackhuang.hmcl.util.MessageBox; import org.jackhuang.hmcl.util.StrUtils; +import org.jackhuang.hmcl.util.task.ProgressProviderListener; +import org.jackhuang.hmcl.util.task.Task; import org.jackhuang.hmcl.util.task.TaskWindow; import org.jackhuang.hmcl.util.ui.SwingUtils; @@ -32,7 +34,7 @@ import org.jackhuang.hmcl.util.ui.SwingUtils; * * @author huangyuhui */ -public class GameDownloadPanel extends Page { +public class GameDownloadPanel extends Page implements ProgressProviderListener { GameSettingsPanel gsp; @@ -108,16 +110,37 @@ public class GameDownloadPanel extends Page { }//GEN-LAST:event_btnRefreshGameDownloadsActionPerformed public void refreshDownloads() { + if (loading) + return; + loading = true; DefaultTableModel model = SwingUtils.clearDefaultTable(lstDownloads); model.addRow(new Object[] { C.i18n("message.loading"), "", "" }); MinecraftRemoteVersions.refreshRomoteVersions(Settings.getLastProfile().service().getDownloadType()) .reg((ver) -> model.addRow(new Object[] { ver.id, ver.releaseTime, ver.time, StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type })) .regDone(SwingUtils.invokeLater(() -> { + loading = false; lstDownloads.requestFocus(); if (model.getRowCount() > 0) model.removeRow(0); - })).runAsync(); + })).setProgressProviderListener(this).runAsync(); + } + + boolean loading = false; + + @Override + public void setProgress(Task task, int prog, int max) { + DefaultTableModel model = (DefaultTableModel) lstDownloads.getModel(); + if (model.getRowCount() > 0) + model.setValueAt(C.i18n("message.loading") + " " + (prog < 0 ? "???" : Integer.toString(prog * 100 / max) + "%"), 0, 0); + } + + @Override + public void setStatus(Task task, String sta) { + } + + @Override + public void onProgressProviderDone(Task task) { } void downloadMinecraft() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerPanel.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerPanel.java index 32eff4647..4ca40dc43 100755 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerPanel.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerPanel.java @@ -30,6 +30,7 @@ import org.jackhuang.hmcl.util.task.TaskRunnable; import org.jackhuang.hmcl.util.task.TaskWindow; import org.jackhuang.hmcl.util.MessageBox; import org.jackhuang.hmcl.util.StrUtils; +import org.jackhuang.hmcl.util.task.ProgressProviderListener; import org.jackhuang.hmcl.util.task.Task; import org.jackhuang.hmcl.util.ui.SwingUtils; @@ -37,7 +38,7 @@ import org.jackhuang.hmcl.util.ui.SwingUtils; * * @author huangyuhui */ -public class InstallerPanel extends Page { +public class InstallerPanel extends Page implements ProgressProviderListener { GameSettingsPanel gsp; @@ -124,11 +125,36 @@ public class InstallerPanel extends Page { InstallerType id; void refreshVersions() { - DefaultTableModel model = SwingUtils.clearDefaultTable(lstInstallers); - model.addRow(new Object[] { C.i18n("message.loading"), "", "" }); + if (loading) + return; Task t = list.refresh(new String[] { gsp.getMinecraftVersionFormatted() }); - if (t != null) - t.with(new TaskRunnable(this::loadVersions)).runAsync(); + if (t != null) { + loading = true; + DefaultTableModel model = SwingUtils.clearDefaultTable(lstInstallers); + model.addRow(new Object[] { C.i18n("message.loading"), "", "" }); + t.with(new TaskRunnable(this::loadVersions)).setProgressProviderListener(this).runAsync(); + } + } + + boolean loading = false; + + @Override + public void setProgress(Task task, int prog, int max) { + DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel(); + if (model.getRowCount() > 0) + model.setValueAt(C.i18n("message.loading") + " " + (prog < 0 ? "???" : Integer.toString(prog * 100 / max) + "%"), 0, 0); + } + + @Override + public void setStatus(Task task, String sta) { + } + + @Override + public void onProgressProviderDone(Task task) { + loading = false; + DefaultTableModel model = (DefaultTableModel) lstInstallers.getModel(); + if (model.getRowCount() > 0) + model.removeRow(0); } public synchronized InstallerVersionList.InstallerVersion getVersion(int idx) { @@ -158,8 +184,6 @@ public class InstallerPanel extends Page { for (InstallerVersionList.InstallerVersion v : versions) if (v != null) model.addRow(new Object[] { v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion }); - if (model.getRowCount() > 0) - model.removeRow(0); } }); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/core/download/MinecraftRemoteVersions.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/core/download/MinecraftRemoteVersions.java index 34135b71c..b788e7b7a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/core/download/MinecraftRemoteVersions.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/core/download/MinecraftRemoteVersions.java @@ -19,8 +19,12 @@ package org.jackhuang.hmcl.core.download; import com.google.gson.annotations.SerializedName; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import org.jackhuang.hmcl.util.C; +import org.jackhuang.hmcl.util.net.HTTPGetTask; import org.jackhuang.hmcl.util.net.NetUtils; +import org.jackhuang.hmcl.util.task.Task; import org.jackhuang.hmcl.util.task.TaskWorker; /** @@ -57,15 +61,23 @@ public class MinecraftRemoteVersions { public static class RemoteVersionsTask extends TaskWorker { + HTTPGetTask task; + @Override + public Collection getDependTasks() { + return Arrays.asList(task); + } + DownloadType type; public RemoteVersionsTask(DownloadType type) { this.type = type; + this.task = new HTTPGetTask(type.getProvider().getVersionsListDownloadURL()); } @Override public void executeTask(boolean b) throws Exception { - MinecraftRemoteVersions r = C.GSON.fromJson(NetUtils.get(type.getProvider().getVersionsListDownloadURL()), MinecraftRemoteVersions.class); + if (!b) throw new IllegalStateException("Previous http get task failed"); + MinecraftRemoteVersions r = C.GSON.fromJson(task.getResult(), MinecraftRemoteVersions.class); if (r != null && r.versions != null) { INSTANCE = r; send(r.versions.toArray(new MinecraftRemoteVersion[r.versions.size()])); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/DoubleTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/DoubleTask.java index da75f1dce..f89a4e123 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/DoubleTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/DoubleTask.java @@ -55,4 +55,11 @@ public class DoubleTask extends TaskInfo { throw new IllegalStateException("Depend tasks failed."); } + @Override + public Task setProgressProviderListener(ProgressProviderListener p) { + a.setProgressProviderListener(p); + b.setProgressProviderListener(p); + return this; + } + } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/Task.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/Task.java index 6649cd0d5..ad81e5637 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/Task.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/task/Task.java @@ -21,7 +21,7 @@ import java.util.Collection; import org.jackhuang.hmcl.util.AbstractSwingWorker; /** - * + * Create a new instance when you use a task anyway. * @author huangyuhui */ public abstract class Task { @@ -111,13 +111,19 @@ public abstract class Task { public void runWithException() throws Exception { Collection c = getDependTasks(); if (c != null) - for (Task t : c) + for (Task t : c) { + if (t.ppl == null) + t.setProgressProviderListener(this.ppl); t.runWithException(); + } executeTask(true); c = getAfterTasks(); if (c != null) - for (Task t : c) + for (Task t : c) { + if (t.ppl == null) + t.setProgressProviderListener(this.ppl); t.runWithException(); + } } public void runAsync() { diff --git a/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/BETabbedPaneUI.java b/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/BETabbedPaneUI.java index 5c74fcfe2..59cdae10f 100644 --- a/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/BETabbedPaneUI.java +++ b/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/tab/BETabbedPaneUI.java @@ -11,7 +11,6 @@ */ package org.jackhuang.hmcl.laf.tab; -import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; @@ -21,8 +20,6 @@ import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTabbedPaneUI; -import org.jackhuang.hmcl.laf.BEUtils; - /** * JTabbedPane的UI实现类. * @@ -245,49 +242,6 @@ public class BETabbedPaneUI extends BasicTabbedPaneUI { Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) { - Rectangle tabRect = rects[tabIndex]; - if (tabPane.hasFocus() && isSelected) { - int x, y, w, h; - g.setColor(focus); - switch (tabPlacement) { - case LEFT: - x = tabRect.x + 4;//父类中默认是+3 - y = tabRect.y + 6;//父类中默认是+3 - w = tabRect.width - 7;//父类中默认是 - 5 - h = tabRect.height - 12;//父类中默认是-6 - break; - case RIGHT: - x = tabRect.x + 4;//父类中默认是+ 2 - y = tabRect.y + 6;//父类中默认是+ 3 - w = tabRect.width - 9;//父类中默认是- 5 - h = tabRect.height - 12;//父类中默认是- 6 - break; - case BOTTOM: - x = tabRect.x + 6;//父类中默认是+ 3 - y = tabRect.y + 4;//父类中默认是+ 2 - w = tabRect.width - 12;//父类中默认是- 6 - h = tabRect.height - 9;//父类中默认是- 5 - break; - case TOP: - default: - //** modified by jb2011:根据整体效果进行偏移修正 - x = tabRect.x + 6;//父类中默认是+3 - //** modified by jb2011:根据整体效果进行偏移修正 - y = tabRect.y + 4;//父类中默认是+3 - //** modified by jb2011:根据整体效果进行偏移修正 - w = tabRect.width - 12;//父类中默认是-6 - //** modified by jb2011:-8的目的是使得焦点虚线框与选中底边保持一个像素的距离,否则挨在一起在视觉上效果会较差 - h = tabRect.height - 8;//父类中默认是 - 5 - } - - //** modified by jb2011:绘制虚线方法改成可以设置虚线步进的方法,步进设为2则更好看一点 -// BasicGraphicsUtils.drawDashedRect(g, x, y, w, h); - BEUtils.drawDashedRect(g, x, y, w, h); - // 绘制虚线框的半透明白色立体阴影(因主背景色较淡,效果不明显,但显然比没有要好) - g.setColor(new Color(255, 255, 255, 255));// TODO 此值可提炼成UIManager属性哦 - // 立体阴影就是向右下偏移一个像素实现的 - BEUtils.drawDashedRect(g, x + 1, y + 1, w, h); - } } /** diff --git a/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/utils/TMSchema.java b/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/utils/TMSchema.java index 8d1bc381a..345ac6a96 100644 --- a/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/utils/TMSchema.java +++ b/HMCLaF/src/main/java/org/jackhuang/hmcl/laf/utils/TMSchema.java @@ -208,6 +208,7 @@ public class TMSchema { return str + control.toString(); } + @Override public String toString() { return control.toString() + "." + name(); } @@ -295,7 +296,7 @@ public class TMSchema { private static EnumMap stateMap; private static synchronized void initStates() { - stateMap = new EnumMap(Part.class); + stateMap = new EnumMap<>(Part.class); stateMap.put(Part.EP_EDITTEXT, new State[] { @@ -453,92 +454,4 @@ public class TMSchema { } - /** - * An enumeration of the possible component attributes and the - * corresponding value type - */ - public static enum Prop { - COLOR(Color.class, 204), - SIZE(Dimension.class, 207), - FLATMENUS(Boolean.class, 1001), - BORDERONLY(Boolean.class, 2203), // only draw the border area of the image - - IMAGECOUNT(Integer.class, 2401), // the number of state images in an imagefile - BORDERSIZE(Integer.class, 2403), // the size of the border line for bgtype=BorderFill - - PROGRESSCHUNKSIZE(Integer.class, 2411), // size of progress control chunks - PROGRESSSPACESIZE(Integer.class, 2412), // size of progress control spaces - - TEXTSHADOWOFFSET(Point.class, 3402), // where char shadows are drawn, relative to orig. chars - - NORMALSIZE(Dimension.class, 3409), // size of dest rect that exactly source - - SIZINGMARGINS(Insets.class, 3601), // margins used for 9-grid sizing - CONTENTMARGINS(Insets.class, 3602), // margins that define where content can be placed - CAPTIONMARGINS(Insets.class, 3603), // margins that define where caption text can be placed - - BORDERCOLOR(Color.class, 3801), // color of borders for BorderFill - FILLCOLOR(Color.class, 3802), // color of bg fill - TEXTCOLOR(Color.class, 3803), // color text is drawn in - - TEXTSHADOWCOLOR(Color.class, 3818), // color of text shadow - - BGTYPE(Integer.class, 4001), // basic drawing type for each part - - TEXTSHADOWTYPE(Integer.class, 4010), // type of shadow to draw with text - - TRANSITIONDURATIONS(Integer.class, 6000); - - private final Class type; - private final int value; - - private Prop(Class type, int value) { - this.type = type; - this.value = value; - } - - public int getValue() { - return value; - } - - public String toString() { - return name() + "[" + type.getName() + "] = " + value; - } - } - - /** - * An enumeration of attribute values for some Props - */ - public static enum TypeEnum { - BT_IMAGEFILE(Prop.BGTYPE, "imagefile", 0), - BT_BORDERFILL(Prop.BGTYPE, "borderfill", 1), - TST_NONE(Prop.TEXTSHADOWTYPE, "none", 0), - TST_SINGLE(Prop.TEXTSHADOWTYPE, "single", 1), - TST_CONTINUOUS(Prop.TEXTSHADOWTYPE, "continuous", 2); - - private TypeEnum(Prop prop, String enumName, int value) { - this.prop = prop; - this.enumName = enumName; - this.value = value; - } - - private final Prop prop; - private final String enumName; - private final int value; - - public String toString() { - return prop + "=" + enumName + "=" + value; - } - - String getName() { - return enumName; - } - - static TypeEnum getTypeEnum(Prop prop, int enumval) { - for (TypeEnum e : TypeEnum.values()) - if (e.prop == prop && e.value == enumval) - return e; - return null; - } - } }