From a4289d6eae792bbedaf30e6957fe2af4da032cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=9E=E5=BA=90?= <109708109+Ciilu@users.noreply.github.com> Date: Sun, 8 Mar 2026 09:08:07 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E6=97=B6=E5=AF=B9?= =?UTF-8?q?=E4=BC=9A=E4=B8=A2=E5=A4=B1=E6=B8=B8=E6=88=8F=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=E6=B7=BB=E5=8A=A0=2010=20=E7=A7=92?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jackhuang/hmcl/Launcher.java | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index a2c583e6f6..8b89ab6b52 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -17,35 +17,35 @@ */ package org.jackhuang.hmcl; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; import javafx.application.Application; import javafx.application.Platform; import javafx.beans.value.ObservableBooleanValue; import javafx.geometry.Rectangle2D; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.input.Clipboard; import javafx.scene.input.DataFormat; import javafx.stage.Screen; import javafx.stage.Stage; +import javafx.util.Duration; import org.jackhuang.hmcl.setting.ConfigHolder; import org.jackhuang.hmcl.setting.SambaException; -import org.jackhuang.hmcl.ui.FXUtils; -import org.jackhuang.hmcl.util.FileSaver; import org.jackhuang.hmcl.task.AsyncTaskExecutor; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.ui.Controllers; +import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; import org.jackhuang.hmcl.util.CrashReporter; +import org.jackhuang.hmcl.util.FileSaver; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.JarUtils; -import org.jackhuang.hmcl.util.platform.Architecture; -import org.jackhuang.hmcl.util.platform.CommandBuilder; -import org.jackhuang.hmcl.util.platform.NativeUtils; -import org.jackhuang.hmcl.util.platform.OperatingSystem; -import org.jackhuang.hmcl.util.platform.SystemInfo; +import org.jackhuang.hmcl.util.platform.*; import java.io.File; import java.io.IOException; @@ -65,8 +65,8 @@ import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.util.DataSizeUnit.MEGABYTES; -import static org.jackhuang.hmcl.util.logging.Logger.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; public final class Launcher extends Application { public static final CookieManager COOKIE_MANAGER = new CookieManager(); @@ -111,7 +111,7 @@ public void start(Stage primaryStage) { if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS && ConfigHolder.isNewlyCreated() && System.getProperty("user.dir").startsWith("/private/var/folders/")) { - if (showAlert(AlertType.WARNING, i18n("fatal.mac_app_translocation"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) + if (showAlertWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) return; } else { checkConfigInTempDir(); @@ -182,6 +182,35 @@ private static ButtonType showAlert(AlertType alertType, String contentText, But return new Alert(alertType, contentText, buttons).showAndWait().orElse(null); } + private static ButtonType showAlertWithCountdown(Alert.AlertType alertType, String contentText, ButtonType... buttons) { + Alert alert = new Alert(alertType, contentText, buttons); + + Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.YES); + + okButton.setDisable(true); + + int delaySeconds = 10; + + Timeline timeline = new Timeline(); + for (int i = 0; i <= delaySeconds; i++) { + int remaining = delaySeconds - i; + KeyFrame keyFrame = new KeyFrame(Duration.seconds(i), event -> { + if (remaining > 0) { + okButton.setText(String.format(i18n("button.yes") + " (%d)", remaining)); + } else { + okButton.setText(i18n("button.yes")); + okButton.setDisable(false); + } + }); + timeline.getKeyFrames().add(keyFrame); + } + + alert.setOnShown(e -> timeline.play()); + alert.setOnCloseRequest(e -> timeline.stop()); + + return alert.showAndWait().orElse(null); + } + private static boolean isConfigInTempDir() { String configPath = ConfigHolder.configLocation().toString(); @@ -221,7 +250,7 @@ private static boolean isConfigInTempDir() { private static void checkConfigInTempDir() { if (ConfigHolder.isNewlyCreated() && isConfigInTempDir() - && showAlert(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) { + && showAlertWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) { EntryPoint.exit(0); } } From 019ddb8e6881c1e024e66e9d2ffbcbd34c54a336 Mon Sep 17 00:00:00 2001 From: Glavo Date: Fri, 13 Mar 2026 21:50:19 +0800 Subject: [PATCH 2/3] update --- .../java/org/jackhuang/hmcl/Launcher.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index 8b89ab6b52..7bf1dc01c9 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -18,6 +18,7 @@ package org.jackhuang.hmcl; import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.application.Application; import javafx.application.Platform; @@ -111,7 +112,7 @@ public void start(Stage primaryStage) { if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS && ConfigHolder.isNewlyCreated() && System.getProperty("user.dir").startsWith("/private/var/folders/")) { - if (showAlertWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) + if (showAlertWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), 5, ButtonType.YES, ButtonType.NO) == ButtonType.NO) return; } else { checkConfigInTempDir(); @@ -182,29 +183,23 @@ private static ButtonType showAlert(AlertType alertType, String contentText, But return new Alert(alertType, contentText, buttons).showAndWait().orElse(null); } - private static ButtonType showAlertWithCountdown(Alert.AlertType alertType, String contentText, ButtonType... buttons) { + private static ButtonType showAlertWithCountdown(Alert.AlertType alertType, String contentText, int seconds, ButtonType... buttons) { Alert alert = new Alert(alertType, contentText, buttons); Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.YES); okButton.setDisable(true); - int delaySeconds = 10; - - Timeline timeline = new Timeline(); - for (int i = 0; i <= delaySeconds; i++) { - int remaining = delaySeconds - i; - KeyFrame keyFrame = new KeyFrame(Duration.seconds(i), event -> { - if (remaining > 0) { - okButton.setText(String.format(i18n("button.yes") + " (%d)", remaining)); - } else { - okButton.setText(i18n("button.yes")); - okButton.setDisable(false); - } - }); - timeline.getKeyFrames().add(keyFrame); + KeyFrame[] keyFrames = new KeyFrame[seconds + 1]; + for (int i = 0; i < seconds; i++) { + keyFrames[i] = new KeyFrame(Duration.seconds(i), + new KeyValue(okButton.textProperty(), i18n("button.ok.countdown", seconds - i))); } + keyFrames[seconds] = new KeyFrame(Duration.seconds(seconds), + new KeyValue(okButton.textProperty(), i18n("button.ok")), + new KeyValue(okButton.disableProperty(), false)); + Timeline timeline = new Timeline(keyFrames); alert.setOnShown(e -> timeline.play()); alert.setOnCloseRequest(e -> timeline.stop()); @@ -250,7 +245,7 @@ private static boolean isConfigInTempDir() { private static void checkConfigInTempDir() { if (ConfigHolder.isNewlyCreated() && isConfigInTempDir() - && showAlertWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), ButtonType.YES, ButtonType.NO) == ButtonType.NO) { + && showAlertWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), 5, ButtonType.YES, ButtonType.NO) == ButtonType.NO) { EntryPoint.exit(0); } } From 2638c7c9dfcc5b52852fdcdbdd70d117e9f9c943 Mon Sep 17 00:00:00 2001 From: Glavo Date: Fri, 13 Mar 2026 22:03:39 +0800 Subject: [PATCH 3/3] Refactor alert countdown method to return boolean --- HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index 7bf1dc01c9..bfaa0f5aa4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -112,7 +112,7 @@ public void start(Stage primaryStage) { if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS && ConfigHolder.isNewlyCreated() && System.getProperty("user.dir").startsWith("/private/var/folders/")) { - if (showAlertWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), 5, ButtonType.YES, ButtonType.NO) == ButtonType.NO) + if (!confirmWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), 5)) return; } else { checkConfigInTempDir(); @@ -183,9 +183,8 @@ private static ButtonType showAlert(AlertType alertType, String contentText, But return new Alert(alertType, contentText, buttons).showAndWait().orElse(null); } - private static ButtonType showAlertWithCountdown(Alert.AlertType alertType, String contentText, int seconds, ButtonType... buttons) { - Alert alert = new Alert(alertType, contentText, buttons); - + private static boolean confirmWithCountdown(Alert.AlertType alertType, String contentText, int seconds) { + Alert alert = new Alert(alertType, contentText, ButtonType.YES, ButtonType.NO); Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.YES); okButton.setDisable(true); @@ -202,8 +201,7 @@ private static ButtonType showAlertWithCountdown(Alert.AlertType alertType, Stri Timeline timeline = new Timeline(keyFrames); alert.setOnShown(e -> timeline.play()); alert.setOnCloseRequest(e -> timeline.stop()); - - return alert.showAndWait().orElse(null); + return alert.showAndWait().orElse(null) == ButtonType.YES; } private static boolean isConfigInTempDir() { @@ -245,7 +243,7 @@ private static boolean isConfigInTempDir() { private static void checkConfigInTempDir() { if (ConfigHolder.isNewlyCreated() && isConfigInTempDir() - && showAlertWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), 5, ButtonType.YES, ButtonType.NO) == ButtonType.NO) { + && !confirmWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), 5)) { EntryPoint.exit(0); } }