diff --git a/src/main/java/cn/octopusyan/dmt/Application.java b/src/main/java/cn/octopusyan/dmt/Application.java index f840ea0..090c893 100644 --- a/src/main/java/cn/octopusyan/dmt/Application.java +++ b/src/main/java/cn/octopusyan/dmt/Application.java @@ -71,9 +71,6 @@ public class Application extends javafx.application.Application { Context.setApplication(this); - // 初始化弹窗工具 - AlertUtil.initOwner(primaryStage); - // 全局异常处理 Thread.setDefaultUncaughtExceptionHandler(this::showErrorDialog); Thread.currentThread().setUncaughtExceptionHandler(this::showErrorDialog); @@ -86,13 +83,11 @@ public class Application extends javafx.application.Application { Scene scene = Context.initScene(); primaryStage.setScene(scene); primaryStage.show(); - - } private void showErrorDialog(Thread t, Throwable e) { logger.error("未知异常", e); - Platform.runLater(() -> AlertUtil.exception(new Exception(e)).show()); + Platform.runLater(() -> AlertUtil.getInstance(primaryStage).exception(new Exception(e)).show()); } @Override diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java index 2211134..e058f01 100644 --- a/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseBuilder.java @@ -51,7 +51,8 @@ public abstract class BaseBuilder, D extends Dialog< } public void close() { - if (dialog.isShowing()) - dialog.close(); + Platform.runLater(() -> { + if (dialog.isShowing()) dialog.close(); + }); } } diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java index 22e133b..d14f2a9 100644 --- a/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseController.java @@ -9,7 +9,6 @@ import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.layout.Pane; import javafx.stage.Stage; -import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +28,6 @@ import java.util.ResourceBundle; */ public abstract class BaseController implements Initializable { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Getter protected final VM viewModel; public BaseController() { @@ -97,7 +95,7 @@ public abstract class BaseController implements Initia return ""; } - protected Stage getWindow() { + public Stage getWindow() { try { return (Stage) getRootPanel().getScene().getWindow(); } catch (Throwable _) { diff --git a/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java b/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java index 799509a..4b1a26f 100644 --- a/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java +++ b/src/main/java/cn/octopusyan/dmt/common/base/BaseViewModel.java @@ -8,7 +8,7 @@ import lombok.Setter; * @author octopus_yan */ @Setter -public abstract class BaseViewModel, T extends BaseController> { +public abstract class BaseViewModel { protected T controller; diff --git a/src/main/java/cn/octopusyan/dmt/common/config/Context.java b/src/main/java/cn/octopusyan/dmt/common/config/Context.java index 1c9a4f4..8874323 100644 --- a/src/main/java/cn/octopusyan/dmt/common/config/Context.java +++ b/src/main/java/cn/octopusyan/dmt/common/config/Context.java @@ -60,17 +60,6 @@ public class Context { Context.application = application; } - /** - * 有此类所在路径决定相对路径 - * - * @param path 资源文件相对路径 - * @return 资源文件路径 - */ - // 加载资源文件 - public static URL load(String path) { - return Context.class.getResource(path); - } - /** * 初始化场景 * diff --git a/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java b/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java index 4204cb2..c209fcc 100644 --- a/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java +++ b/src/main/java/cn/octopusyan/dmt/common/manager/ConfigManager.java @@ -224,6 +224,11 @@ public class ConfigManager { getProxyInfo().setPort(port); } + /** + * 端口检查 + * + * @param consumer 检查结果,信息 + */ public static void checkProxy(BiConsumer consumer) { if (ProxySetup.SYSTEM.equals(proxySetup())) { consumer.accept(true, ""); diff --git a/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java b/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java index f08bc44..15f590d 100644 --- a/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java +++ b/src/main/java/cn/octopusyan/dmt/common/util/ViewUtil.java @@ -1,12 +1,20 @@ package cn.octopusyan.dmt.common.util; import cn.octopusyan.dmt.Application; +import cn.octopusyan.dmt.common.manager.ConfigManager; +import cn.octopusyan.dmt.view.alert.AlertUtil; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; import javafx.scene.layout.Pane; +import javafx.stage.Modality; import javafx.stage.Screen; import javafx.stage.Stage; +import javafx.stage.StageStyle; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * 工具 @@ -55,6 +63,35 @@ public class ViewUtil { }); } + public static void openDecorated(String title, String fxml) { + Stage open = Objects.requireNonNull(open(StageStyle.DECORATED, title, fxml)); + open.setResizable(false); + open.showAndWait(); + } + + public static Stage open(StageStyle style, String title, String fxml) { + FXMLLoader load = FxmlUtil.load(fxml); + try { + return open(style, title, (Pane) load.load()); + } catch (IOException e) { + AlertUtil.getInstance().exception(e).show(); + } + return null; + } + + public static Stage open(StageStyle style, String title, Pane pane) { + Stage stage = new Stage(); + stage.initOwner(Application.getPrimaryStage()); + stage.initStyle(style); + stage.initModality(Modality.WINDOW_MODAL); + stage.setTitle(title); + Scene scene = new Scene(pane); + scene.setUserAgentStylesheet(ConfigManager.theme().getUserAgentStylesheet()); + stage.setScene(scene); + stage.sizeToScene(); + return stage; + } + public static Stage getStage() { return Application.getPrimaryStage(); } diff --git a/src/main/java/cn/octopusyan/dmt/controller/MainController.java b/src/main/java/cn/octopusyan/dmt/controller/MainController.java index b9bd2f8..f9ff226 100644 --- a/src/main/java/cn/octopusyan/dmt/controller/MainController.java +++ b/src/main/java/cn/octopusyan/dmt/controller/MainController.java @@ -8,6 +8,7 @@ import cn.octopusyan.dmt.common.config.Context; import cn.octopusyan.dmt.common.manager.ConfigManager; import cn.octopusyan.dmt.common.util.ClipUtil; import cn.octopusyan.dmt.common.util.FxmlUtil; +import cn.octopusyan.dmt.common.util.ViewUtil; import cn.octopusyan.dmt.controller.component.WordEditController; import cn.octopusyan.dmt.model.WordItem; import cn.octopusyan.dmt.task.TranslateTask; @@ -95,12 +96,13 @@ public class MainController extends BaseController { @Override public void initData() { + // 信息 + ConsoleLog.init(logArea); // 界面样式 List list = ConfigManager.THEME_LIST.stream().map(this::createViewStyleItem).toList(); viewStyle.getItems().addAll(list); - // 信息 - ConsoleLog.init(logArea); + fileNameLabel.textProperty().bind(viewModel.fileNameProperty()); } @Override @@ -202,23 +204,15 @@ public class MainController extends BaseController { /** * 打开代理设置 */ - public void openSetupProxy() throws IOException { - FXMLLoader load = FxmlUtil.load("setup/proxy-view"); - AlertUtil.builder(false) - .title("网络代理设置") - .content((Pane) load.load()) - .show(); + public void openSetupProxy() { + ViewUtil.openDecorated("网络代理设置", "setup/proxy-view"); } /** * 打开翻译设置 */ - public void openSetupTranslate() throws IOException { - FXMLLoader load = FxmlUtil.load("setup/translate-view"); - AlertUtil.builder(false) - .title("翻译设置") - .content((Pane) load.load()) - .show(); + public void openSetupTranslate() { + ViewUtil.openDecorated("翻译设置", "setup/translate-view"); } public void setFileName(String name) { @@ -288,7 +282,7 @@ public class MainController extends BaseController { FileUtils.copyFile(packFile, file); } catch (IOException e) { consoleLog.error("保存文件失败!", e); - Platform.runLater(() -> AlertUtil.exception(e).content("保存文件失败!").show()); + Platform.runLater(() -> AlertUtil.getInstance(getWindow()).exception(e).content("保存文件失败!").show()); } } diff --git a/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java b/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java index ddcbe2c..9a1b664 100644 --- a/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java +++ b/src/main/java/cn/octopusyan/dmt/controller/component/WordEditController.java @@ -55,7 +55,7 @@ public class WordEditController extends BaseController { String result = TranslateFactoryImpl.getInstance().translate(ConfigManager.translateApi(), original.getText()); Platform.runLater(() -> chinese.setText(result)); } catch (Exception e) { - Platform.runLater(() -> AlertUtil.exception(e).show()); + Platform.runLater(() -> AlertUtil.getInstance(getWindow()).exception(e).show()); } Platform.runLater(() -> progress.setVisible(false)); }); diff --git a/src/main/java/cn/octopusyan/dmt/controller/ProxyController.java b/src/main/java/cn/octopusyan/dmt/controller/setup/ProxyController.java similarity index 98% rename from src/main/java/cn/octopusyan/dmt/controller/ProxyController.java rename to src/main/java/cn/octopusyan/dmt/controller/setup/ProxyController.java index b0e1cec..c12d6bf 100644 --- a/src/main/java/cn/octopusyan/dmt/controller/ProxyController.java +++ b/src/main/java/cn/octopusyan/dmt/controller/setup/ProxyController.java @@ -1,4 +1,4 @@ -package cn.octopusyan.dmt.controller; +package cn.octopusyan.dmt.controller.setup; import cn.octopusyan.dmt.common.base.BaseController; import cn.octopusyan.dmt.common.enums.ProxySetup; diff --git a/src/main/java/cn/octopusyan/dmt/controller/TranslateController.java b/src/main/java/cn/octopusyan/dmt/controller/setup/TranslateController.java similarity index 94% rename from src/main/java/cn/octopusyan/dmt/controller/TranslateController.java rename to src/main/java/cn/octopusyan/dmt/controller/setup/TranslateController.java index a879ab1..653056a 100644 --- a/src/main/java/cn/octopusyan/dmt/controller/TranslateController.java +++ b/src/main/java/cn/octopusyan/dmt/controller/setup/TranslateController.java @@ -1,4 +1,4 @@ -package cn.octopusyan.dmt.controller; +package cn.octopusyan.dmt.controller.setup; import cn.octopusyan.dmt.common.base.BaseController; import cn.octopusyan.dmt.common.manager.ConfigManager; @@ -81,7 +81,8 @@ public class TranslateController extends BaseController { ConfigManager.translateQps(source, qps); if (source.needApiKey()) { if (StringUtils.isBlank(apikey) || StringUtils.isBlank(appid)) { - AlertUtil.error("认证信息不能为空"); + AlertUtil.getInstance(getWindow()).error("认证信息不能为空").show(); + return; } ConfigManager.translateApikey(source, apikey); diff --git a/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java b/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java index 795c4fc..5a052f9 100644 --- a/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java +++ b/src/main/java/cn/octopusyan/dmt/task/listener/DefaultTaskListener.java @@ -22,7 +22,7 @@ public abstract class DefaultTaskListener implements Listener { * 加载弹窗 */ @Getter - final ProgressBuilder progress = AlertUtil.progress(); + final ProgressBuilder progress = AlertUtil.getInstance().progress(); /** * 是否展示加载弹窗 diff --git a/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java b/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java index e7dc838..bce9ef5 100644 --- a/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java +++ b/src/main/java/cn/octopusyan/dmt/translate/ApiKey.java @@ -1,13 +1,10 @@ package cn.octopusyan.dmt.translate; -import lombok.Getter; - /** * API 密钥配置 * * @author octopus_yan@foxmail.com */ -@Getter public record ApiKey(String appid, String apiKey) { } diff --git a/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java b/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java index 79597de..90c919f 100644 --- a/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java +++ b/src/main/java/cn/octopusyan/dmt/view/alert/AlertUtil.java @@ -1,5 +1,6 @@ package cn.octopusyan.dmt.view.alert; +import cn.octopusyan.dmt.Application; import cn.octopusyan.dmt.view.alert.builder.*; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; @@ -12,44 +13,56 @@ import javafx.stage.Window; * @author octopus_yan@foxmail.com */ public class AlertUtil { - private static Window mOwner; + private final Window mOwner; + private static volatile AlertUtil alertUtil; - public static void initOwner(Stage stage) { - AlertUtil.mOwner = stage; + private AlertUtil(Window mOwner) { + this.mOwner = mOwner; } - public static DefaultBuilder builder() { + public static synchronized AlertUtil getInstance() { + if (alertUtil == null) { + alertUtil = new AlertUtil(Application.getPrimaryStage()); + } + return alertUtil; + } + + public static AlertUtil getInstance(Stage stage) { + return new AlertUtil(stage); + } + + public DefaultBuilder builder() { return new DefaultBuilder(mOwner, true); } - public static DefaultBuilder builder(boolean transparent) { + public DefaultBuilder builder(boolean transparent) { return new DefaultBuilder(mOwner, transparent); } - public static AlertBuilder info(String content) { + public AlertBuilder info(String content) { return info().content(content).header(null); } - public static AlertBuilder info() { + public AlertBuilder info() { return alert(Alert.AlertType.INFORMATION); } - public static AlertBuilder error(String message) { + public AlertBuilder error(String message) { return alert(Alert.AlertType.ERROR).header(null).content(message); } - public static AlertBuilder warning() { + public AlertBuilder warning() { return alert(Alert.AlertType.WARNING); } - public static AlertBuilder exception(Exception ex) { + public AlertBuilder exception(Exception ex) { return alert(Alert.AlertType.ERROR).exception(ex); } /** * 确认对话框 */ - public static AlertBuilder confirm() { + public AlertBuilder confirm() { return alert(Alert.AlertType.CONFIRMATION); } @@ -58,32 +71,32 @@ public class AlertUtil { * * @param buttons "Cancel" OR "取消" 为取消按钮 */ - public static AlertBuilder confirm(String... buttons) { + public AlertBuilder confirm(String... buttons) { return confirm().buttons(buttons); } - public static AlertBuilder confirm(ButtonType... buttons) { + public AlertBuilder confirm(ButtonType... buttons) { return confirm().buttons(buttons); } - public static AlertBuilder alert(Alert.AlertType type) { + public AlertBuilder alert(Alert.AlertType type) { return new AlertBuilder(mOwner, type); } - public static TextInputBuilder input(String content) { + public TextInputBuilder input(String content) { return new TextInputBuilder(mOwner); } - public static TextInputBuilder input(String content, String defaultResult) { + public TextInputBuilder input(String content, String defaultResult) { return new TextInputBuilder(mOwner, defaultResult).content(content); } @SafeVarargs - public static ChoiceBuilder choices(String hintText, T... choices) { + public final ChoiceBuilder choices(String hintText, T... choices) { return new ChoiceBuilder<>(mOwner, choices).content(hintText); } - public static ProgressBuilder progress() { + public ProgressBuilder progress() { return new ProgressBuilder(mOwner); } diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java index 2e3a0f0..6437068 100644 --- a/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java +++ b/src/main/java/cn/octopusyan/dmt/viewModel/MainViewModel.java @@ -1,5 +1,6 @@ package cn.octopusyan.dmt.viewModel; +import atlantafx.base.theme.Styles; import cn.octopusyan.dmt.common.base.BaseViewModel; import cn.octopusyan.dmt.controller.MainController; import cn.octopusyan.dmt.model.WordItem; @@ -11,6 +12,8 @@ import cn.octopusyan.dmt.translate.DelayWord; import cn.octopusyan.dmt.translate.TranslateUtil; import cn.octopusyan.dmt.view.ConsoleLog; import javafx.application.Platform; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; import javafx.concurrent.Worker; import javafx.scene.control.ProgressIndicator; import org.apache.commons.lang3.StringUtils; @@ -28,7 +31,7 @@ import java.util.regex.Pattern; * * @author octopus_yan */ -public class MainViewModel extends BaseViewModel { +public class MainViewModel extends BaseViewModel { private static final ConsoleLog consoleLog = ConsoleLog.getInstance(MainViewModel.class); /** * 解包任务 @@ -38,9 +41,7 @@ public class MainViewModel extends BaseViewModel * 翻译任务 */ private TranslateTask translateTask; - private DelayQueue delayQueue; - private String unpackPath; private int total; @@ -48,13 +49,19 @@ public class MainViewModel extends BaseViewModel FontIcon pauseIcon = new FontIcon(Feather.PAUSE); private List wordItems; + private final StringProperty fileName = new SimpleStringProperty(); + + public StringProperty fileNameProperty() { + return fileName; + } + /** * 加载PBO文件 */ public void selectFile(File pboFile) { if (pboFile == null) return; - controller.setFileName(pboFile.getAbsolutePath()); + fileName.setValue(pboFile.getAbsolutePath()); unpackTask = new UnpackTask(pboFile); } @@ -185,6 +192,7 @@ public class MainViewModel extends BaseViewModel private void resetProgress() { translateTask = null; controller.translate.setGraphic(startIcon); + Styles.toggleStyleClass(controller.translateProgress, Styles.SMALL); controller.translateProgress.progressProperty().unbind(); controller.translateProgress.setProgress(0); controller.translateProgress.setVisible(false); diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java index 61348b1..67d3b93 100644 --- a/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java +++ b/src/main/java/cn/octopusyan/dmt/viewModel/ProxyViewModel.java @@ -4,7 +4,7 @@ import cn.octopusyan.dmt.common.base.BaseViewModel; import cn.octopusyan.dmt.common.enums.ProxySetup; import cn.octopusyan.dmt.common.manager.ConfigManager; import cn.octopusyan.dmt.common.manager.http.HttpUtil; -import cn.octopusyan.dmt.controller.ProxyController; +import cn.octopusyan.dmt.controller.setup.ProxyController; import cn.octopusyan.dmt.task.ProxyCheckTask; import cn.octopusyan.dmt.task.listener.DefaultTaskListener; import cn.octopusyan.dmt.view.alert.AlertUtil; @@ -16,20 +16,22 @@ import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import org.apache.commons.lang3.StringUtils; +import java.net.URI; + /** * 设置 * * @author octopus_yan */ -public class ProxyViewModel extends BaseViewModel { +public class ProxyViewModel extends BaseViewModel { private final StringProperty proxyHost = new SimpleStringProperty(ConfigManager.proxyHost()); private final StringProperty proxyPort = new SimpleStringProperty(ConfigManager.proxyPort()); private final ObjectProperty proxySetup = new SimpleObjectProperty<>(ConfigManager.proxySetup()); - private final StringProperty proxyTestUrl = new SimpleStringProperty(ConfigManager.proxyTestUrl()); + private final AlertUtil alertUtil = AlertUtil.getInstance(); public ProxyViewModel() { + proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue)); - proxyTestUrl.addListener((_, _, newValue) -> ConfigManager.proxyTestUrl(newValue)); proxyHost.addListener((_, _, newValue) -> { ConfigManager.proxyHost(newValue); setProxy(); @@ -53,30 +55,43 @@ public class ProxyViewModel extends BaseViewModel { Platform.runLater(progress::close); if (!success) { final var tmp = "连接问题: "; - AlertUtil.error(STR."\{tmp}\{msg}").show(); + alertUtil.error(STR."\{tmp}\{msg}").show(); return; } - HttpUtil.getInstance().proxy(ConfigManager.proxySetup(), ConfigManager.getProxyInfo()); + // 代理检查任务 getProxyCheckTask(checkUrl).execute(); }); } + private boolean checkUrl(String checkUrl) { + try { + //noinspection ResultOfMethodCallIgnored + URI.create(checkUrl); + return true; + } catch (Exception e) { + return false; + } + } + private void setProxy() { ConfigManager.checkProxy((success, msg) -> { if (!success) { @@ -87,19 +102,19 @@ public class ProxyViewModel extends BaseViewModel { +public class TranslateViewModel extends BaseViewModel { private final ObjectProperty source = new SimpleObjectProperty<>(ConfigManager.translateApi()) { { diff --git a/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java b/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java index c1754d7..1cc702d 100644 --- a/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java +++ b/src/main/java/cn/octopusyan/dmt/viewModel/WordEditViewModel.java @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; */ @EqualsAndHashCode(callSuper = true) @Data -public class WordEditViewModel extends BaseViewModel { +public class WordEditViewModel extends BaseViewModel { private WordItem data; /** diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index e52e70a..8369d15 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -24,5 +24,7 @@ module cn.octopusyan.dmt { opens cn.octopusyan.dmt.common.base to javafx.fxml; opens cn.octopusyan.dmt.controller to javafx.fxml; opens cn.octopusyan.dmt.controller.component to javafx.fxml; + opens cn.octopusyan.dmt.controller.setup to javafx.fxml; + opens cn.octopusyan.dmt.controller.help to javafx.fxml; opens cn.octopusyan.dmt.view.filemanager to javafx.fxml; } \ No newline at end of file diff --git a/src/main/resources/fxml/main-view.fxml b/src/main/resources/fxml/main-view.fxml index 6bdaddb..895dfed 100644 --- a/src/main/resources/fxml/main-view.fxml +++ b/src/main/resources/fxml/main-view.fxml @@ -5,7 +5,7 @@ - + @@ -55,7 +55,7 @@