diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java index 692b1378e..bb13246d4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java @@ -17,6 +17,7 @@ */ package org.jackhuang.hmcl.ui.main; +import com.jfoenix.controls.JFXButton; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.WeakInvalidationListener; @@ -32,10 +33,12 @@ import org.jackhuang.hmcl.upgrade.RemoteVersion; import org.jackhuang.hmcl.upgrade.UpdateChannel; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; +import org.jackhuang.hmcl.util.Restarter; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.i18n.Locales; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.IOUtils; +import org.jackhuang.hmcl.util.logging.Level; import org.tukaani.xz.XZInputStream; import java.io.IOException; @@ -61,6 +64,8 @@ public final class SettingsPage extends SettingsView { private InvalidationListener updateListener; + private boolean ignoreLanguageChange = false; + public SettingsPage() { FXUtils.smoothScrolling(scroll); @@ -68,6 +73,39 @@ public final class SettingsPage extends SettingsView { cboLanguage.getItems().setAll(Locales.LOCALES); selectedItemPropertyFor(cboLanguage).bindBidirectional(config().localizationProperty()); + cboLanguage.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (ignoreLanguageChange) return; + + if (oldValue != null && newValue != null && !oldValue.equals(newValue)) { + JFXButton restartButton = new JFXButton(i18n("button.restart")); + restartButton.getStyleClass().add("dialog-accept"); + restartButton.setOnAction(e -> { + try { + Restarter.builder().restart(); + } catch (IOException ex) { + LOG.log(Level.WARNING, "Failed to restart", ex); + ignoreLanguageChange = true; + cboLanguage.getSelectionModel().select(oldValue); + ignoreLanguageChange = false; + } + }); + + Runnable cancelAction = () -> { + ignoreLanguageChange = true; + cboLanguage.getSelectionModel().select(newValue); + ignoreLanguageChange = false; + }; + + Controllers.confirmAction( + i18n("settings.launcher.language.restart"), + i18n("message.info"), + MessageType.INFO, + restartButton, + cancelAction + ); + } + }); + disableAutoGameOptionsPane.selectedProperty().bindBidirectional(config().disableAutoGameOptionsProperty()); // ==== diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/Restarter.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/Restarter.java new file mode 100644 index 000000000..fddc7f56c --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/Restarter.java @@ -0,0 +1,105 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2020 huangyuhui and contributors + * + * 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 . + */ +package org.jackhuang.hmcl.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.jackhuang.hmcl.EntryPoint; +import org.jackhuang.hmcl.java.JavaRuntime; +import org.jackhuang.hmcl.util.io.JarUtils; + +/** + *

A common restart tool class, used for:

+ * + */ +public final class Restarter { + + private final List jvmOptions = new ArrayList<>(); + private final List programArgs = new ArrayList<>(); + private Path jarPath; + + private Restarter() { } + + public static Restarter builder() { + return new Restarter(); + } + + public Restarter addSystemProperty(String key, String value) { + jvmOptions.add("-D" + key + "=" + value); + return this; + } + + public Restarter addProgramArguments(List args) { + programArgs.addAll(args); + return this; + } + + /** + *

+ * Set the JAR path to start + * If not, the current running JAR will be used by default + *

+ */ + public Restarter setJarPath(Path jarPath) { + this.jarPath = jarPath; + return this; + } + + public void restart() throws IOException { + Path jar = this.jarPath; + if (jar == null) { + jar = JarUtils.thisJarPath(); + } + if (jar == null) { + throw new IOException("Cannot locate JAR file"); + } + + List command = new ArrayList<>(); + command.add(JavaRuntime.getDefault().getBinary().toString()); + + for (Map.Entry e : System.getProperties().entrySet()) { + Object k = e.getKey(); + if (k instanceof String && ((String) k).startsWith("hmcl.")) { + command.add("-D" + k + "=" + e.getValue()); + } + } + + command.addAll(jvmOptions); + + command.add("-jar"); + command.add(jar.toAbsolutePath().toString()); + + command.addAll(programArgs); + + new ProcessBuilder(command) + .directory(new File(System.getProperty("user.dir"))) + .inheritIO() + .start(); + + EntryPoint.exit(0); + } +} diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 56064f3d5..75654fd83 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -195,6 +195,7 @@ button.save_as=Save As button.select_all=Select All button.view=View button.yes=Yes +button.restart=Restart chat=Join Group Chat @@ -1362,6 +1363,7 @@ settings.launcher.font.anti_aliasing.gray=Grayscale settings.launcher.font.anti_aliasing.lcd=Sub-pixel settings.launcher.general=General settings.launcher.language=Language (Applies After Restart) +settings.launcher.language.restart=Changing the language requires restarting the launcher to take effect. Restart now? settings.launcher.launcher_log.export=Export Launcher Logs settings.launcher.launcher_log.export.failed=Failed to export logs. settings.launcher.launcher_log.export.success=Logs have been exported to "%s". diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index ee0700dc7..39c3b112d 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -195,6 +195,7 @@ button.save_as=Guardar como button.select_all=Seleccionar todo button.view=Vista button.yes=Sí +button.restart=Reiniciar chat=Chat de grupo @@ -1358,6 +1359,7 @@ settings.launcher.font.anti_aliasing.gray=Escala de grises settings.launcher.font.anti_aliasing.lcd=Subpíxel settings.launcher.general=General settings.launcher.language=Idioma +settings.launcher.language.restart=¿Reiniciar ahora? El cambio de idioma requiere reiniciar el launcher para que surta efecto. settings.launcher.launcher_log.export=Exportar registros del launcher settings.launcher.launcher_log.export.failed=No se han podido exportar los registros settings.launcher.launcher_log.export.success=Los registros se han exportado a «%s» diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index e5c9e5e78..d51d86c41 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -156,6 +156,7 @@ button.save_as=名前を付けて保存 button.select_all=すべて選択 button.view=読む button.yes=はい +button.restart=再起動 chat=グループチャット @@ -852,6 +853,7 @@ settings.launcher.enable_game_list=メインページにバージョンリスト settings.launcher.font=フォント settings.launcher.general=全般的 settings.launcher.language=言語 +settings.launcher.language.restart=言語を変更するにはランチャーを再起動する必要があります。今すぐ再起動しますか? settings.launcher.launcher_log.export=ランチャーログのエクスポート settings.launcher.launcher_log.export.failed=ログのエクスポートに失敗しました settings.launcher.launcher_log.export.success=ログが %s にエクスポートされました diff --git a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties index b117bf296..aa8007a32 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties @@ -205,6 +205,7 @@ button.save_as=另存 button.select_all=悉擇之 button.view=覽 button.yes=然 +button.restart=復啟 chat=會集 diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 310a52a46..994923af5 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -196,6 +196,7 @@ button.save_as=Сохранить как button.select_all=Выбрать все button.view=Просмотреть button.yes=Да +button.restart=Перезагрузить chat=Групповой чат @@ -1358,6 +1359,7 @@ settings.launcher.font.anti_aliasing.gray=Оттенки серого settings.launcher.font.anti_aliasing.lcd=Субпиксель settings.launcher.general=Общие settings.launcher.language=Язык (Применится после перезапуска) +settings.launcher.language.restart=Для применения изменений языка требуется перезагрузка лаунчера. Перезагрузить сейчас? settings.launcher.launcher_log.export=Экспорт логов лаунчера settings.launcher.launcher_log.export.failed=Не удалось экспортировать логи settings.launcher.launcher_log.export.success=Логи экспортированы в %s diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index bf2a920e3..e4a3cf73e 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -193,6 +193,7 @@ button.save_as=Зберегти як button.select_all=Вибрати все button.view=Переглянути button.yes=Так +button.restart=Перезавантажити chat=Приєднатися до групового чату @@ -1299,6 +1300,7 @@ settings.launcher.font.anti_aliasing.gray=Відтінки сірого settings.launcher.font.anti_aliasing.lcd=Субпіксельне settings.launcher.general=Загальні settings.launcher.language=Мова (Застосовується після перезавантаження) +settings.launcher.language.restart=Для застосування зміни мови необхідно перезавантажити лаунчер. Перезавантажити зараз? settings.launcher.launcher_log.export=Експортувати журнали лаунчера settings.launcher.launcher_log.export.failed=Не вдалося експортувати журнали. settings.launcher.launcher_log.export.success=Журнали було експортовано до "%s". diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index d01764c5f..a550594fc 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -198,6 +198,7 @@ button.save_as=另存新檔 button.select_all=全選 button.view=查看 button.yes=是 +button.restart=重新啟動 chat=官方群組 @@ -1150,6 +1151,7 @@ settings.launcher.font.anti_aliasing.gray=灰階 settings.launcher.font.anti_aliasing.lcd=子像素 settings.launcher.general=一般 settings.launcher.language=語言 (重啟後生效) +settings.launcher.language.restart=切換語言需要重新啟動啟動器才能生效。是否立即重新啟動? settings.launcher.launcher_log.export=匯出啟動器日誌 settings.launcher.launcher_log.export.failed=無法匯出日誌。 settings.launcher.launcher_log.export.success=日誌已儲存到「%s」。 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 43603a3cb..c796249da 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -206,6 +206,7 @@ button.save_as=另存为 button.select_all=全选 button.view=查看 button.yes=是 +button.restart=立即重启 chat=官方群组 @@ -1161,6 +1162,7 @@ settings.launcher.font.anti_aliasing.gray=灰度 settings.launcher.font.anti_aliasing.lcd=子像素 settings.launcher.general=通用 settings.launcher.language=语言 (重启后生效) +settings.launcher.language.restart=切换语言需要重启启动器才能生效。是否立即重启? settings.launcher.launcher_log.export=导出启动器日志 settings.launcher.launcher_log.export.failed=无法导出日志 settings.launcher.launcher_log.export.success=日志已保存到“%s”