From db08b61cfa85f3a70e27cfac63be8d760f15e86f Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Mon, 5 Mar 2018 19:02:13 +0800 Subject: [PATCH] Fix #301 --- .../jackhuang/hmcl/game/LauncherHelper.java | 22 +++++---- .../org/jackhuang/hmcl/ui/Controllers.java | 8 +++- .../java/org/jackhuang/hmcl/ui/Decorator.java | 30 +++++++++---- .../hmcl/ui/InstallerController.java | 3 +- .../jackhuang/hmcl/ui/LeftPaneController.java | 2 +- .../java/org/jackhuang/hmcl/ui/MainPage.java | 11 +++-- .../hmcl/ui/construct/StackContainerPane.java | 45 +++++++++++++++++++ .../hmcl/upgrade/AppDataUpgrader.java | 11 ++--- .../main/resources/assets/fxml/decorator.fxml | 1 - .../java/org/jackhuang/hmcl/task/Task.java | 7 +++ 10 files changed, 104 insertions(+), 36 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/StackContainerPane.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 2f5596e5d..3fa53c0c1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -100,7 +100,6 @@ public final class LauncherHelper { } } catch (AuthenticationException e) { variables.set("account", DialogController.logIn(account)); - JFXUtilities.runInFX(() -> Controllers.dialog(launchingStepsPane)); } })) .then(Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.LAUNCHING))) @@ -132,8 +131,10 @@ public final class LauncherHelper { Controllers.closeDialog(); }); } else - Platform.runLater(() -> - Controllers.dialog(Launcher.i18n("version.launch_script.success", scriptFile.getAbsolutePath()))); + Platform.runLater(() -> { + Controllers.closeDialog(); + Controllers.dialog(Launcher.i18n("version.launch_script.success", scriptFile.getAbsolutePath())); + }); })) .executor(); @@ -153,12 +154,11 @@ public final class LauncherHelper { public void onStop(boolean success, TaskExecutor executor) { if (!success) { Platform.runLater(() -> { + Controllers.closeDialog(); if (executor.getLastException() != null) Controllers.dialog(I18nException.getStackTrace(executor.getLastException()), scriptFile == null ? Launcher.i18n("launch.failed") : Launcher.i18n("version.launch_script.failed"), MessageBox.ERROR_MESSAGE, Controllers::closeDialog); - else - Controllers.closeDialog(); }); } launchingStepsPane.setExecutor(null); @@ -180,28 +180,28 @@ public final class LauncherHelper { flag = true; } - if (java.getParsedVersion() < JavaVersion.JAVA_8) { + if (!flag && java.getParsedVersion() < JavaVersion.JAVA_8) { Controllers.dialog(Launcher.i18n("launch.advice.newer_java"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept); flag = true; } - if (java.getParsedVersion() >= JavaVersion.JAVA_9 && gameVersion.compareTo(VersionNumber.asVersion("1.12.5")) < 0 && version.getMainClass().contains("launchwrapper")) { + if (!flag && java.getParsedVersion() >= JavaVersion.JAVA_9 && gameVersion.compareTo(VersionNumber.asVersion("1.12.5")) < 0 && version.getMainClass().contains("launchwrapper")) { Controllers.dialog(Launcher.i18n("launch.advice.java9"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE, null); suggest = false; flag = true; } - if (java.getPlatform() == org.jackhuang.hmcl.util.Platform.BIT_32 && + if (!flag && java.getPlatform() == org.jackhuang.hmcl.util.Platform.BIT_32 && org.jackhuang.hmcl.util.Platform.IS_64_BIT) { Controllers.dialog(Launcher.i18n("launch.advice.different_platform"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept); flag = true; } - if (java.getPlatform() == org.jackhuang.hmcl.util.Platform.BIT_32 && + if (!flag && java.getPlatform() == org.jackhuang.hmcl.util.Platform.BIT_32 && setting.getMaxMemory() > 1.5 * 1024) { Controllers.dialog(Launcher.i18n("launch.advice.too_large_memory_for_32bit"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept); flag = true; } - if (OperatingSystem.TOTAL_MEMORY > 0 && OperatingSystem.TOTAL_MEMORY < setting.getMaxMemory()) { + if (!flag && OperatingSystem.TOTAL_MEMORY > 0 && OperatingSystem.TOTAL_MEMORY < setting.getMaxMemory()) { Controllers.dialog(Launcher.i18n("launch.advice.not_enough_space", OperatingSystem.TOTAL_MEMORY), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE, onAccept); flag = true; } @@ -219,10 +219,8 @@ public final class LauncherHelper { } public void emitStatus(LoadingState state) { - launchingStepsPane.setTitle(state.getLocalizedMessage()); launchingStepsPane.setSubtitle((state.ordinal() + 1) + " / " + LoadingState.values().length); - Controllers.dialog(launchingStepsPane); } private void checkExit(LauncherVisibility v) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index cbca99630..52dad1769 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -33,6 +33,7 @@ import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; import org.jackhuang.hmcl.util.JavaVersion; +import org.jackhuang.hmcl.util.Lang; import java.util.function.Consumer; @@ -122,7 +123,7 @@ public final class Controllers { public static JFXDialog dialog(Region content) { // TODO: temp fix - decorator.showDialog(new Region()); + decorator.showDialog(Lang.apply(new Region(), region -> region.getProperties().put("controllers", true))); return decorator.showDialog(content); } @@ -150,12 +151,15 @@ public final class Controllers { dialog(new InputDialogPane(text, decorator.getDialog(), onResult)); } + public static void taskDialog(TaskExecutor executor, String title, String subtitle) { + taskDialog(executor, title, subtitle, null); + } + public static void taskDialog(TaskExecutor executor, String title, String subtitle, Runnable onCancel) { TaskExecutorDialogPane pane = new TaskExecutorDialogPane(onCancel); pane.setTitle(title); pane.setSubtitle(subtitle); pane.setExecutor(executor); - executor.start(); dialog(pane); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java index a903880e4..863fb4c3d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Decorator.java @@ -17,6 +17,7 @@ */ package org.jackhuang.hmcl.ui; +import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXDialog; import com.jfoenix.controls.JFXDrawer; @@ -53,6 +54,7 @@ import org.jackhuang.hmcl.ui.animation.AnimationProducer; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionHandler; import org.jackhuang.hmcl.ui.construct.AdvancedListBox; +import org.jackhuang.hmcl.ui.construct.StackContainerPane; import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogWizardDisplayer; import org.jackhuang.hmcl.ui.wizard.*; import org.jackhuang.hmcl.util.FileUtils; @@ -82,11 +84,13 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza private final boolean max, min; private final WizardController wizardController = new WizardController(this); private final Queue cancelQueue = new ConcurrentLinkedQueue<>(); + private final JFXDialog dialog; private double xOffset, yOffset, newX, newY, initX, initY; - private boolean allowMove, isDragging, dialogShown, maximized; + private boolean allowMove, isDragging, maximized; private BoundingBox originalBox, maximizedBox; private final TransitionHandler animationHandler; + private final StackContainerPane dialogPane = new StackContainerPane(); @FXML private StackPane contentPlaceHolder; @@ -119,8 +123,6 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza @FXML private JFXHamburger titleBurger; @FXML - private JFXDialog dialog; - @FXML private JFXButton btnMin; @FXML private JFXButton btnMax; @@ -165,9 +167,21 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza btnMax.fire(); }); + dialog = new JFXDialog() { + @Override + public void close() { + dialogPane.pop(); + if (dialogPane.getChildren().isEmpty()) + Platform.runLater(() -> { + if (dialogPane.getChildren().isEmpty()) + super.close(); + }); + } + }; + dialog.setOverlayClose(false); + drawerWrapper.getChildren().add(0, dialog); dialog.setDialogContainer(drawerWrapper); - dialog.setOnDialogClosed(e -> dialogShown = false); - dialog.setOnDialogOpened(e -> dialogShown = true); + dialog.setContent(dialogPane); if (!min) buttonsContainer.getChildren().remove(btnMin); if (!max) buttonsContainer.getChildren().remove(btnMax); @@ -531,10 +545,10 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza } } - public JFXDialog showDialog(Region content) { - dialog.setContent(content); - if (!dialogShown) + public JFXDialog showDialog(Node node) { + if (dialogPane.isEmpty()) dialog.show(); + dialogPane.push(node); return dialog; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java index 10c614e0d..4a5ce5886 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerController.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui; import javafx.fxml.FXML; import javafx.scene.control.ScrollPane; import javafx.scene.layout.VBox; +import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.download.MaintainTask; import org.jackhuang.hmcl.download.game.VersionJsonSaveTask; import org.jackhuang.hmcl.game.GameVersion; @@ -89,7 +90,7 @@ public class InstallerController { Optional gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)); if (!gameVersion.isPresent()) - Controllers.dialog("version.cannot_read"); + Controllers.dialog(Launcher.i18n("version.cannot_read")); else Controllers.getDecorator().startWizard(new InstallerWizardProvider(profile, gameVersion.get(), version, forge, liteLoader, optiFine)); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java index 2ca95b0bf..3f02eaa97 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java @@ -208,7 +208,7 @@ public final class LeftPaneController { .with(Task.of(Schedulers.javafx(), () -> { Controllers.closeDialog(); checkAccount(); - })).executor(), + })).executor(true), Launcher.i18n("modpack.installing"), "", null); flag = false; } catch (UnsupportedModpackException ignore) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java index 9b1eb0ea3..7c5ea4805 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java @@ -147,19 +147,18 @@ public final class MainPage extends StackPane implements DecoratorPage { chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(Launcher.i18n("modpack"), "*.zip")); File selectedFile = chooser.showOpenDialog(Controllers.getStage()); if (selectedFile != null) { - TaskExecutorDialogPane pane = new TaskExecutorDialogPane(null); try { TaskExecutor executor = ModpackHelper.getUpdateTask(profile, selectedFile, id, ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(id))) - .then(Task.of(Schedulers.javafx(), Controllers::closeDialog)).executor(); - pane.setExecutor(executor); - pane.setTitle(Launcher.i18n("modpack.update")); - executor.start(); - Controllers.dialog(pane); + .then(Task.of(Schedulers.javafx(), Controllers::closeDialog)).executor(true); + Controllers.taskDialog(executor, Launcher.i18n("modpack.update"), "", null); } catch (UnsupportedModpackException e) { + Controllers.closeDialog(); Controllers.dialog(Launcher.i18n("modpack.unsupported"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE); } catch (MismatchedModpackTypeException e) { + Controllers.closeDialog(); Controllers.dialog(Launcher.i18n("modpack.mismatched_type"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE); } catch (IOException e) { + Controllers.closeDialog(); Controllers.dialog(Launcher.i18n("modpack.invalid"), Launcher.i18n("message.error"), MessageBox.ERROR_MESSAGE); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/StackContainerPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/StackContainerPane.java new file mode 100644 index 000000000..78f2a75d0 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/StackContainerPane.java @@ -0,0 +1,45 @@ +/* + * Hello Minecraft! Launcher. + * Copyright (C) 2017 huangyuhui + * + * 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.hmcl.ui.construct; + +import javafx.scene.Node; +import javafx.scene.layout.StackPane; + +import java.util.Stack; + +public class StackContainerPane extends StackPane { + private final Stack stack = new Stack<>(); + + public void push(Node node) { + if (node.getProperties().containsKey("controllers")) + stack.push(node); + getChildren().setAll(node); + } + + public void pop() { + stack.pop(); + if (stack.isEmpty()) + getChildren().setAll(); + else + getChildren().setAll(stack.peek()); + } + + public boolean isEmpty() { + return stack.isEmpty(); + } +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/AppDataUpgrader.java b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/AppDataUpgrader.java index eca7caf91..5ac4d50d1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/AppDataUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/AppDataUpgrader.java @@ -24,6 +24,7 @@ import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.util.*; @@ -130,13 +131,15 @@ public class AppDataUpgrader extends IUpgrader { String hash = null; if (map.containsKey("packsha1")) hash = map.get("packsha1"); - JFXUtilities.runInFX(() -> Controllers.dialog(Launcher.i18n("message.downloading"))); - if (new AppDataUpgraderPackGzTask(NetworkUtils.toURL(map.get("pack")), version.toString(), hash).test()) { + Task task = new AppDataUpgraderPackGzTask(NetworkUtils.toURL(map.get("pack")), version.toString(), hash); + TaskExecutor executor = task.executor(); + JFXUtilities.runInFX(() -> Controllers.taskDialog(executor, Launcher.i18n("message.downloading"), "", null)); + if (executor.test()) { new ProcessBuilder(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath(), "-jar", AppDataUpgraderPackGzTask.getSelf(version.toString()).getAbsolutePath()) .directory(new File("").getAbsoluteFile()).start(); System.exit(0); } - Controllers.closeDialog(); + JFXUtilities.runInFX(Controllers::closeDialog); } catch (IOException ex) { Logging.LOG.log(Level.SEVERE, "Failed to create upgrader", ex); } @@ -147,8 +150,6 @@ public class AppDataUpgrader extends IUpgrader { url = map.get(OperatingSystem.CURRENT_OS.getCheckedName()); else if (map.containsKey(OperatingSystem.UNKNOWN.getCheckedName())) url = map.get(OperatingSystem.UNKNOWN.getCheckedName()); - if (url == null) - url = Launcher.PUBLISH; try { java.awt.Desktop.getDesktop().browse(new URI(url)); } catch (URISyntaxException | IOException e) { diff --git a/HMCL/src/main/resources/assets/fxml/decorator.fxml b/HMCL/src/main/resources/assets/fxml/decorator.fxml index c59288d70..fdbda6f8f 100644 --- a/HMCL/src/main/resources/assets/fxml/decorator.fxml +++ b/HMCL/src/main/resources/assets/fxml/decorator.fxml @@ -20,7 +20,6 @@ maxWidth="800">
- diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java index 1f614007b..281fb3dd0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/Task.java @@ -205,6 +205,13 @@ public abstract class Task { return new TaskExecutor(this); } + public final TaskExecutor executor(boolean start) { + TaskExecutor executor = new TaskExecutor(this); + if (start) + executor.start(); + return executor; + } + public final TaskExecutor executor(TaskListener taskListener) { TaskExecutor executor = new TaskExecutor(this); executor.addTaskListener(taskListener);