From 0660674f7f2d8a3ff307df458e9a343221803a12 Mon Sep 17 00:00:00 2001 From: octopus_yan Date: Fri, 20 Sep 2024 22:06:08 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20I18n=20=E8=87=AA=E5=8A=A8=E7=BB=91?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alistgui/base/BaseController.java | 47 +++++++++++++ .../octopusyan/alistgui/config/Context.java | 10 +-- .../cn/octopusyan/alistgui/config/I18n.java | 15 ++++ .../ObservableResourceBundleFactory.java | 12 +--- .../alistgui/controller/AboutController.java | 19 +++-- .../alistgui/controller/MainController.java | 70 +++++++++++++------ .../controller/PasswordController.java | 16 +++-- .../alistgui/controller/RootController.java | 37 +++++----- .../alistgui/controller/SetupController.java | 25 +++---- .../alistgui/manager/SystemTrayManager.java | 20 +++--- .../octopusyan/alistgui/view/PopupMenu.java | 20 ++++++ .../alistgui/viewModel/MainViewModel.java | 52 ++------------ src/main/resources/fxml/about-view.fxml | 4 +- src/main/resources/fxml/admin-panel.fxml | 6 +- src/main/resources/fxml/main-view.fxml | 4 +- src/main/resources/fxml/root-view.fxml | 6 +- src/main/resources/fxml/setup-view.fxml | 4 +- 17 files changed, 214 insertions(+), 153 deletions(-) create mode 100644 src/main/java/cn/octopusyan/alistgui/config/I18n.java diff --git a/src/main/java/cn/octopusyan/alistgui/base/BaseController.java b/src/main/java/cn/octopusyan/alistgui/base/BaseController.java index c1e48e7..5aacb1a 100644 --- a/src/main/java/cn/octopusyan/alistgui/base/BaseController.java +++ b/src/main/java/cn/octopusyan/alistgui/base/BaseController.java @@ -2,19 +2,28 @@ package cn.octopusyan.alistgui.base; import cn.octopusyan.alistgui.Application; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.util.FxmlUtil; import cn.octopusyan.alistgui.util.WindowsUtil; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Labeled; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Tab; import javafx.scene.layout.Pane; import javafx.stage.Stage; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.ResourceBundle; /** @@ -43,6 +52,29 @@ public abstract class BaseController implements Initia } } viewModel = vm; + + } + + /** + * 国际化绑定 + */ + private void bindI18n() { + // i18n 绑定 + try { + for (Field field : getAllField(this.getClass())) { + I18n i18n = field.getAnnotation(I18n.class); + if (i18n != null && StringUtils.isNoneEmpty(i18n.key())) { + switch (field.get(this)) { + case Labeled labeled -> labeled.textProperty().bind(Context.getLanguageBinding(i18n.key())); + case Tab tab -> tab.textProperty().bind(Context.getLanguageBinding(i18n.key())); + case MenuItem mi -> mi.textProperty().bind(Context.getLanguageBinding(i18n.key())); + default -> {} + } + } + } + } catch (IllegalAccessException e) { + logger.error("获取属性失败", e); + } } @FXML @@ -54,6 +86,9 @@ public abstract class BaseController implements Initia WindowsUtil.bindDragged(getRootPanel()); } + // 国际化绑定 + bindI18n(); + // 初始化数据 initData(); @@ -109,4 +144,16 @@ public abstract class BaseController implements Initia * 视图事件 */ public abstract void initViewAction(); + + + private static List getAllField(Class class1) { + List list = new ArrayList<>(); + while (class1 != Object.class) { + list.addAll(Arrays.stream(class1.getDeclaredFields()).toList()); + //获取父类 + class1 = class1.getSuperclass(); + } + return list; + } + } diff --git a/src/main/java/cn/octopusyan/alistgui/config/Context.java b/src/main/java/cn/octopusyan/alistgui/config/Context.java index e8a323b..316a1e8 100644 --- a/src/main/java/cn/octopusyan/alistgui/config/Context.java +++ b/src/main/java/cn/octopusyan/alistgui/config/Context.java @@ -10,7 +10,6 @@ import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.util.FxmlUtil; import cn.octopusyan.alistgui.util.ProcessesUtil; -import javafx.application.Platform; import javafx.beans.binding.StringBinding; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; @@ -161,14 +160,6 @@ public class Context { * @return Scene */ public static Scene initScene() { - // locale监听; 切换后,重新加载界面 - currentLocaleProperty().addListener((_, _, locale) -> Platform.runLater(Context::loadScene)); - // 加载 - loadScene(); - return scene; - } - - private static void loadScene() { try { FXMLLoader loader = FxmlUtil.load("root-view"); //底层面板 @@ -185,6 +176,7 @@ public class Context { } catch (Throwable e) { log.error("loadScene error", e); } + return scene; } public static int currentViewIndex() { diff --git a/src/main/java/cn/octopusyan/alistgui/config/I18n.java b/src/main/java/cn/octopusyan/alistgui/config/I18n.java new file mode 100644 index 0000000..8a3161e --- /dev/null +++ b/src/main/java/cn/octopusyan/alistgui/config/I18n.java @@ -0,0 +1,15 @@ +package cn.octopusyan.alistgui.config; + +import java.lang.annotation.*; + +/** + * 显示文本绑定 + * + * @author octopus_yan + */ +@Documented +@Target({ElementType.FIELD})//用此注解用在属性上。 +@Retention(RetentionPolicy.RUNTIME) +public @interface I18n { + String key() default ""; +} diff --git a/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java b/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java index 9b45a26..4e57f1c 100644 --- a/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java +++ b/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java @@ -1,5 +1,6 @@ package cn.octopusyan.alistgui.config; +import javafx.beans.binding.Bindings; import javafx.beans.binding.StringBinding; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; @@ -26,15 +27,6 @@ public class ObservableResourceBundleFactory { } public StringBinding getStringBinding(String key) { - return new StringBinding() { - { - bind(resourceBundleProperty); - } - - @Override - protected String computeValue() { - return getResourceBundle().getString(key); - } - }; + return Bindings.createStringBinding(() -> getResourceBundle().getString(key), resourceBundleProperty); } } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java b/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java index 17c45f5..a012854 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java @@ -1,10 +1,11 @@ package cn.octopusyan.alistgui.controller; import cn.octopusyan.alistgui.base.BaseController; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.view.alert.AlertUtil; import cn.octopusyan.alistgui.viewModel.AboutViewModule; -import javafx.fxml.FXML; +import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import org.slf4j.Logger; @@ -18,12 +19,22 @@ import org.slf4j.LoggerFactory; public class AboutController extends BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - @FXML public VBox aboutView; - @FXML public Label aListVersion; + @I18n(key = "about.alist.version") + public Label aListVersionLabel; + + @I18n(key = "about.app.version") + public Label appVersionLabel; + + @I18n(key = "about.app.update") + public Button checkAppVersion; + + @I18n(key = "about.alist.update") + public Button checkAListVersion; + @Override public VBox getRootPanel() { return aboutView; @@ -44,12 +55,10 @@ public class AboutController extends BaseController { aListVersion.textProperty().bindBidirectional(viewModel.aListVersionProperty()); } - @FXML public void checkAListUpdate() { viewModel.checkUpdate(ConfigManager.aList()); } - @FXML public void checkGuiUpdate() { // TODO 检查 gui 版本 AlertUtil.info("待开发。。。").show(); diff --git a/src/main/java/cn/octopusyan/alistgui/controller/MainController.java b/src/main/java/cn/octopusyan/alistgui/controller/MainController.java index a345d1d..7e14417 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/MainController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/MainController.java @@ -2,13 +2,16 @@ package cn.octopusyan.alistgui.controller; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.AListManager; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.util.FxmlUtil; import cn.octopusyan.alistgui.viewModel.MainViewModel; -import javafx.fxml.FXML; +import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.fxml.FXMLLoader; import javafx.scene.control.Button; +import javafx.scene.control.MenuButton; import javafx.scene.control.MenuItem; import javafx.scene.control.ScrollPane; import javafx.scene.layout.VBox; @@ -25,19 +28,34 @@ import java.io.IOException; public class MainController extends BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - @FXML public VBox mainView; - @FXML public VBox logArea; - @FXML public ScrollPane logAreaSp; - @FXML + + @I18n(key = "main.status.label-stop") public Button statusLabel; - @FXML + + @I18n(key = "main.control.start") public Button startButton; - @FXML + + @I18n(key = "main.control.password") + public Button passwordButton; + + @I18n(key = "main.control.restart") + public Button restartButton; + + @I18n(key = "main.control.more") + public MenuButton moreButton; + + @I18n(key = "main.more.browser") public MenuItem browserButton; + @I18n(key = "main.more.open-config") + public MenuItem configButton; + + @I18n(key = "main.more.open-log") + public MenuItem logButton; + private PasswordController controller; @Override @@ -52,19 +70,18 @@ public class MainController extends BaseController { @Override public void initViewStyle() { + // 运行状态监听 + viewModel.runningProperty().addListener((_, _, running) -> { + resetStatus(running); + browserButton.disableProperty().set(!running); + }); } @Override public void initViewAction() { - viewModel.startBtnStyleCssProperty().bindContentBidirectional(startButton.getStyleClass()); - viewModel.statusLabelStyleCssProperty().bindContentBidirectional(statusLabel.getStyleClass()); - viewModel.startBtnTextProperty().bindBidirectional(startButton.textProperty()); - viewModel.statusLabelTextProperty().bindBidirectional(statusLabel.textProperty()); - viewModel.browserButtonDisableProperty().bindBidirectional(browserButton.disableProperty()); } // start button - @FXML public void start() { if (AListManager.isRunning()) { AListManager.stop(); @@ -74,7 +91,6 @@ public class MainController extends BaseController { } // password button - @FXML public void adminPassword() throws IOException { if (controller == null) { FXMLLoader load = FxmlUtil.load("admin-panel"); @@ -85,29 +101,43 @@ public class MainController extends BaseController { } // restart button - @FXML public void restart() { AListManager.restart(); } // more button - @FXML public void openInBrowser() { AListManager.openScheme(); } - @FXML public void openLogFolder() { AListManager.openLogFolder(); } - @FXML public void openConfig() { AListManager.openConfig(); } - private String getText(String key) { - return Context.getLanguageBinding(key).get(); + /** + * 根据运行状态改变按钮样式 + * + * @param running 运行状态 + */ + private void resetStatus(boolean running) { + String removeStyle = running ? "success" : "danger"; + String addStyle = running ? "danger" : "success"; + StringBinding button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}"); + StringBinding status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}"); + + Platform.runLater(() -> { + startButton.getStyleClass().remove(removeStyle); + startButton.getStyleClass().add(addStyle); + startButton.textProperty().bind(button); + + statusLabel.getStyleClass().remove(addStyle); + statusLabel.getStyleClass().add(removeStyle); + statusLabel.textProperty().bind(status); + }); } } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java b/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java index 64134b9..ccb5546 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java @@ -4,12 +4,14 @@ import atlantafx.base.controls.Popover; import cn.hutool.core.swing.clipboard.ClipboardUtil; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.AListManager; import cn.octopusyan.alistgui.viewModel.AdminPanelViewModel; import javafx.beans.value.ChangeListener; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; @@ -23,20 +25,20 @@ import org.apache.commons.lang3.StringUtils; * @author octopus_yan */ public class PasswordController extends BaseController { - @FXML - private AnchorPane adminPanel; + public AnchorPane adminPanel; - @FXML + @I18n(key = "admin.pwd.toptip") + public Label toptip; + @I18n(key = "admin.pwd.user-field") + public Label usernameLabel; public TextField usernameField; @FXML public Button copyUsername; - @FXML + @I18n(key = "admin.pwd.pwd-field") + public Label passwordLabel; public PasswordField passwordField; - @FXML public Button refreshPassword; - @FXML public Button savePassword; - @FXML public Button copyPassword; private RootController root; diff --git a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java index 4f27e78..f9102d6 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java @@ -3,6 +3,7 @@ package cn.octopusyan.alistgui.controller; import atlantafx.base.controls.ModalPane; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.manager.SystemTrayManager; import cn.octopusyan.alistgui.util.WindowsUtil; @@ -11,10 +12,10 @@ import com.gluonhq.emoji.EmojiData; import com.gluonhq.emoji.util.EmojiImageUtils; import javafx.application.Platform; import javafx.css.PseudoClass; -import javafx.fxml.FXML; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Button; +import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; @@ -31,27 +32,28 @@ import java.util.Locale; */ public class RootController extends BaseController { // 布局 - @FXML - private StackPane rootPane; - @FXML - private HBox windowHeader; - @FXML - private FontIcon alwaysOnTopIcon; - @FXML - private FontIcon minimizeIcon; - @FXML - private FontIcon closeIcon; + public StackPane rootPane; + public HBox windowHeader; + public FontIcon alwaysOnTopIcon; + public FontIcon minimizeIcon; + public FontIcon closeIcon; // 界面 - @FXML - private TabPane tabPane; + public TabPane tabPane; + + @I18n(key = "root.tab.main") + public Tab mainTab; + @I18n(key = "root.tab.setup") + public Tab setupTab; + @I18n(key = "root.tab.about") + public Tab aboutTab; // footer - @FXML + @I18n(key = "root.foot.doc") public Button document; - @FXML + @I18n(key = "root.foot.github") public Button github; - @FXML + @I18n(key = "root.foot.sponsor") public Button sponsor; private final ModalPane modalPane = new ModalPane(); @@ -94,6 +96,7 @@ public class RootController extends BaseController { sponsor.setGraphic(juice); }); + // 遮罩 getRootPanel().getChildren().add(modalPane); modalPane.setId("modalPane"); // reset side and transition to reuse a single modal pane between different examples @@ -131,13 +134,11 @@ public class RootController extends BaseController { viewModel.currentViewIndexProperty().bind(tabPane.getSelectionModel().selectedIndexProperty()); } - @FXML public void openDocument() { String locale = Context.getCurrentLocale().equals(Locale.ENGLISH) ? "" : "zh/"; Context.openUrl(STR."https://alist.nn.ci/\{locale}"); } - @FXML public void openGithub() { Context.openUrl("https://github.com/alist-org/alist"); } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java index 7f3e299..b2b58bc 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java @@ -3,16 +3,14 @@ package cn.octopusyan.alistgui.controller; import atlantafx.base.theme.Theme; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.enums.ProxySetup; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.viewModel.SetupViewModel; import javafx.collections.FXCollections; import javafx.fxml.FXML; import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; -import javafx.scene.control.TextField; +import javafx.scene.control.*; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.util.StringConverter; @@ -32,26 +30,24 @@ public class SetupController extends BaseController implements I @FXML public VBox setupView; - @FXML + @I18n(key = "setup.auto-start.label") public CheckBox autoStartCheckBox; - @FXML + @I18n(key = "setup.silent-startup.label") public CheckBox silentStartupCheckBox; - @FXML + @I18n(key = "setup.close-to-tray.label") public CheckBox closeToTrayCheckBox; - @FXML public ComboBox languageComboBox; - @FXML public ComboBox themeComboBox; - @FXML public ComboBox proxySetupComboBox; - @FXML public Pane proxySetupPane; - @FXML + @I18n(key = "setup.proxy.test") public Button proxyCheck; - @FXML public TextField proxyHost; - @FXML public TextField proxyPort; + @I18n(key = "setup.proxy.host") + public Label hostLabel; + @I18n(key = "setup.proxy.port") + public Label portLabel; @Override public VBox getRootPanel() { @@ -103,7 +99,6 @@ public class SetupController extends BaseController implements I viewModel.proxySetupProperty().bind(proxySetupComboBox.getSelectionModel().selectedItemProperty()); } - @FXML public void proxyTest() { viewModel.proxyTest(); } diff --git a/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java b/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java index b2e9407..ee805d0 100644 --- a/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java +++ b/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java @@ -6,6 +6,7 @@ import cn.octopusyan.alistgui.config.Context; import cn.octopusyan.alistgui.util.WindowsUtil; import cn.octopusyan.alistgui.view.PopupMenu; import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.scene.control.MenuItem; import javafx.stage.Stage; import lombok.extern.slf4j.Slf4j; @@ -148,14 +149,15 @@ public class SystemTrayManager { if (popupMenu != null) return; MenuItem start = PopupMenu.menuItem( - getString(STR."main.control.\{running ? "stop" : "start"}"), + getStringBinding(STR."main.control.\{running ? "stop" : "start"}"), _ -> AListManager.openScheme() ); - MenuItem browser = PopupMenu.menuItem(getString("main.more.browser"), _ -> AListManager.openScheme()); + MenuItem browser = PopupMenu.menuItem(getStringBinding("main.more.browser"), _ -> AListManager.openScheme()); browser.setDisable(!running); AListManager.runningProperty().addListener((_, _, newValue) -> { - start.setText(getString(STR."main.control.\{newValue ? "stop" : "start"}")); + start.textProperty().unbind(); + start.textProperty().bind(getStringBinding(STR."main.control.\{newValue ? "stop" : "start"}")); browser.disableProperty().set(!newValue); toolTip(STR."AList \{newValue ? "running" : "stopped"}"); icon(STR."/assets/logo\{newValue ? "" : "-disabled"}.png"); @@ -172,16 +174,16 @@ public class SystemTrayManager { AListManager.start(); } }) - .addItem(getString("main.control.restart"), _ -> AListManager.restart()) - .addMenu(getString("main.control.more"), browser, - PopupMenu.menuItem(getString("main.more.open-config"), _ -> AListManager.openConfig()), - PopupMenu.menuItem(getString("main.more.open-log"), _ -> AListManager.openLogFolder())) + .addItem(getStringBinding("main.control.restart"), _ -> AListManager.restart()) + .addMenu(getStringBinding("main.control.more"), browser, + PopupMenu.menuItem(getStringBinding("main.more.open-config"), _ -> AListManager.openConfig()), + PopupMenu.menuItem(getStringBinding("main.more.open-log"), _ -> AListManager.openLogFolder())) .addSeparator() .addExitItem(); } - private static String getString(String key) { - return Context.getLanguageBinding(key).get(); + private static StringBinding getStringBinding(String key) { + return Context.getLanguageBinding(key); } private static Stage stage() { diff --git a/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java b/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java index bf15bd9..2eaaef3 100644 --- a/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java +++ b/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java @@ -4,6 +4,7 @@ import atlantafx.base.controls.CaptionMenuItem; import cn.octopusyan.alistgui.config.Constants; import cn.octopusyan.alistgui.util.WindowsUtil; import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; @@ -47,6 +48,12 @@ public class PopupMenu { return addItem(new MenuItem(label), handler); } + public PopupMenu addItem(StringBinding bind, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(bind); + return addItem(menuItem, handler); + } + public PopupMenu addItem(MenuItem node, EventHandler handler) { node.setOnAction(handler); return addItem(node); @@ -68,6 +75,12 @@ public class PopupMenu { return addMenu(new Menu(label), items); } + public PopupMenu addMenu(StringBinding label, MenuItem... items) { + Menu menu = new Menu(); + menu.textProperty().bind(label); + return addMenu(menu, items); + } + public PopupMenu addMenu(Menu menu, MenuItem... items) { menu.getItems().addAll(items); return addItem(menu); @@ -114,4 +127,11 @@ public class PopupMenu { menuItem.setOnAction(handler); return menuItem; } + + public static MenuItem menuItem(StringBinding stringBinding, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(stringBinding); + menuItem.setOnAction(handler); + return menuItem; + } } diff --git a/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java b/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java index 17fcf9e..1236429 100644 --- a/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java +++ b/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java @@ -1,11 +1,9 @@ package cn.octopusyan.alistgui.viewModel; import cn.octopusyan.alistgui.base.BaseViewModel; -import cn.octopusyan.alistgui.config.Context; import cn.octopusyan.alistgui.manager.AListManager; -import javafx.application.Platform; -import javafx.beans.property.*; -import javafx.collections.FXCollections; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; /** * 主界面VM @@ -13,56 +11,14 @@ import javafx.collections.FXCollections; * @author octopus_yan */ public class MainViewModel extends BaseViewModel { - private final ListProperty startBtnStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final StringProperty startBtnText = new SimpleStringProperty(); - private final ListProperty statusLabelStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final StringProperty statusLabelText = new SimpleStringProperty(); - private final BooleanProperty browserButtonDisable = new SimpleBooleanProperty(); private final BooleanProperty running = new SimpleBooleanProperty(); public MainViewModel() { - running.addListener((_, _, running) -> { - resetStatus(running); - browserButtonDisable.set(!running); - }); // 先添加监听再绑定,解决切换locale后,界面状态显示错误的问题 running.bind(AListManager.runningProperty()); } - public ListProperty startBtnStyleCssProperty() { - return startBtnStyleCss; - } - - public StringProperty startBtnTextProperty() { - return startBtnText; - } - - public ListProperty statusLabelStyleCssProperty() { - return statusLabelStyleCss; - } - - public StringProperty statusLabelTextProperty() { - return statusLabelText; - } - - public BooleanProperty browserButtonDisableProperty() { - return browserButtonDisable; - } - - public void resetStatus(boolean running) { - String removeStyle = running ? "success" : "danger"; - String addStyle = running ? "danger" : "success"; - String button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}").get(); - String status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}").get(); - - Platform.runLater(() -> { - startBtnStyleCss.remove(removeStyle); - startBtnStyleCss.add(addStyle); - startBtnText.set(button); - - statusLabelStyleCss.remove(addStyle); - statusLabelStyleCss.add(removeStyle); - statusLabelText.set(status); - }); + public BooleanProperty runningProperty() { + return running; } } diff --git a/src/main/resources/fxml/about-view.fxml b/src/main/resources/fxml/about-view.fxml index be018a1..0b9c817 100644 --- a/src/main/resources/fxml/about-view.fxml +++ b/src/main/resources/fxml/about-view.fxml @@ -22,11 +22,11 @@ - -