From 82d383bc3e90847b89e75e0aacac948b1036cb35 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Sun, 8 Sep 2024 00:07:27 +0800 Subject: [PATCH 01/16] feat: Add multi-language support for main interface - Simplified/Traditional Chinese, English --- .../controller/MainController.java | 96 +++++++++++++++++-- .../service/impl/FileServiceImpl.java | 12 +-- .../zzhow/magicencoding/ui/Application.java | 10 ++ .../zzhow/magicencoding/utils/MessageBox.java | 5 +- .../resources/MessagesBundle_en.properties | 24 +++++ .../MessagesBundle_zh_Hans.properties | 22 +++++ .../MessagesBundle_zh_Hant.properties | 24 +++++ .../com/zzhow/magicencoding/ui/main-view.fxml | 48 +++++----- 8 files changed, 200 insertions(+), 41 deletions(-) create mode 100644 src/main/resources/MessagesBundle_en.properties create mode 100644 src/main/resources/MessagesBundle_zh_Hans.properties create mode 100644 src/main/resources/MessagesBundle_zh_Hant.properties diff --git a/src/main/java/com/zzhow/magicencoding/controller/MainController.java b/src/main/java/com/zzhow/magicencoding/controller/MainController.java index 01454c3..543eb44 100644 --- a/src/main/java/com/zzhow/magicencoding/controller/MainController.java +++ b/src/main/java/com/zzhow/magicencoding/controller/MainController.java @@ -3,33 +3,59 @@ import com.zzhow.magicencoding.service.FileService; import com.zzhow.magicencoding.service.impl.FileServiceImpl; import com.zzhow.magicencoding.ui.About; +import com.zzhow.magicencoding.ui.Application; import com.zzhow.magicencoding.utils.MessageBox; import javafx.fxml.FXML; import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.input.DragEvent; import javafx.scene.input.TransferMode; -import java.io.File; +import java.io.*; import java.util.List; +import java.util.ResourceBundle; public class MainController { // 文件服务类 private final FileService fileService = FileServiceImpl.getInstance(); + @FXML + private Label Label1; + @FXML + private Label Label2; + @FXML + private Label Label3; + @FXML + private Label Label4; + @FXML + private Label Label5; + @FXML + private Label Label6; + @FXML + private Label Label7; + @FXML + private Button Button1; + @FXML + private Button Button2; + @FXML + private Button Button3; + @FXML + private Button Button4; @FXML private ChoiceBox originChoiceBox; @FXML private ChoiceBox targetChoiceBox; @FXML + private ChoiceBox languageSelector; + @FXML private TextField pathTextField; @FXML private TextField endWithTextField; @FXML private ListView filesListView; @FXML - private Label fileNumber; - @FXML private CheckBox isOverwriteCheckBox; public void clearFilesPath() { @@ -43,6 +69,22 @@ private void initialize() { originChoiceBox.setValue("GBK"); targetChoiceBox.getItems().addAll("UTF-8", "GBK"); targetChoiceBox.setValue("UTF-8"); + languageSelector.getItems().addAll("简体中文", "繁體中文", "English"); + File config = new File(System.getProperty("user.dir") + "/MagicEncoding.conf"); + try (BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(config)))) { + String language = bf.readLine().split("=")[1]; + language = switch (language) { + case "zh_Hans" -> "简体中文"; + case "zh_Hant" -> "繁體中文"; + case "en" -> "English"; + default -> "简体中文"; + }; + languageSelector.setValue(language); + Application.language = language; + switchLanguage(); + } catch (IOException e) { + languageSelector.setValue("简体中文"); + } } @FXML @@ -67,7 +109,7 @@ private void onReset() { this.clearFilesPath(); pathTextField.setText(""); endWithTextField.setText(""); - fileNumber.setText("文件数目:0"); + Label7.setText(Application.bundle.getString("Label7") + "0"); } @FXML @@ -77,7 +119,8 @@ private void onFindFiles() { String endWith = endWithTextField.getText(); filesListView.setItems(fileService.findFiles(absolutePath, endWith)); - fileNumber.setText("文件数目:" + fileService.getTargetFileList().size()); + Label7.setText(Application.bundle.getString("Label7") + + fileService.getTargetFileList().size()); } @FXML @@ -88,10 +131,13 @@ private void onTransform() { boolean isOverwrite = this.isOverwriteCheckBox.isSelected(); if (fileService.transform(absolutePath, originCharset, targetCharset, isOverwrite)) { - MessageBox.success("执行成功", "已将" + fileService.getTargetFileList().size() - + "个文件从 \"" + originCharset + "\" 转为 \"" + targetCharset + "\""); + MessageBox.success(Application.bundle.getString("success1_headerText"), + "\"" + originCharset + "\" → \"" + targetCharset + "\"" + + Application.bundle.getString("success1_contentText") + + fileService.getTargetFileList().size()); } else { - MessageBox.error("执行失败", "请重试"); + MessageBox.error(Application.bundle.getString("error3_headerText") + , Application.bundle.getString("error3_contentText")); } } @@ -100,4 +146,38 @@ private void onAbout() { About.open(); } + @FXML + private void switchLanguage() { + String selectorValue = languageSelector.getValue(); + selectorValue = switch (selectorValue) { + case "简体中文" -> "zh_Hans"; + case "繁體中文" -> "zh_Hant"; + case "English" -> "en"; + default -> "zh_Hans"; + }; + + Application.setLanguage(selectorValue); + File config = new File(System.getProperty("user.dir") + "/MagicEncoding.conf"); + try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(config, false)))) { + bw.write("language=" + selectorValue); + } catch (IOException e) { + throw new RuntimeException(e); + } + + ResourceBundle bundle = Application.bundle; + + // 更新界面上的文本 + Label1.setText(bundle.getString("Label1")); + Label2.setText(bundle.getString("Label2")); + Label3.setText(bundle.getString("Label3")); + Label4.setText(bundle.getString("Label4")); + Label5.setText(bundle.getString("Label5")); + Label6.setText(bundle.getString("Label6")); + Label7.setText(bundle.getString("Label7") + fileService.getTargetFileList().size()); + Button1.setText(bundle.getString("Button1")); + Button2.setText(bundle.getString("Button2")); + Button3.setText(bundle.getString("Button3")); + Button4.setText(bundle.getString("Button4")); + isOverwriteCheckBox.setText(bundle.getString("isOverwriteCheckBox")); + } } \ No newline at end of file diff --git a/src/main/java/com/zzhow/magicencoding/service/impl/FileServiceImpl.java b/src/main/java/com/zzhow/magicencoding/service/impl/FileServiceImpl.java index 1b1be13..e4c1f2c 100644 --- a/src/main/java/com/zzhow/magicencoding/service/impl/FileServiceImpl.java +++ b/src/main/java/com/zzhow/magicencoding/service/impl/FileServiceImpl.java @@ -1,6 +1,7 @@ package com.zzhow.magicencoding.service.impl; import com.zzhow.magicencoding.service.FileService; +import com.zzhow.magicencoding.ui.Application; import com.zzhow.magicencoding.utils.MessageBox; import com.zzhow.magicencoding.utils.MyFiles; import javafx.collections.FXCollections; @@ -40,7 +41,8 @@ public ObservableList findFiles(String absolutePath, String endWith) { File[] files = currentFolder.listFiles(); if (files == null || files.length == 0) { - MessageBox.error("当前路径下没有满足条件的文件", "请检查设置的条件"); + MessageBox.error(Application.bundle.getString("error1_headerText") + , Application.bundle.getString("error1_contentText")); return null; } @@ -63,7 +65,8 @@ public boolean transform(String absolutePath, String originCharset, String targe absolutePath = absolutePath.replace("\\", "/"); if (targetFileList.isEmpty()) { - MessageBox.error("当前没有命中的文件", "请先查找文件"); + MessageBox.error(Application.bundle.getString("error2_headerText") + , Application.bundle.getString("error2_contentText")); return false; } @@ -76,11 +79,8 @@ public boolean transform(String absolutePath, String originCharset, String targe outputFolder.delete(); } - if (!outputFolder.mkdir()) { - MessageBox.error("创建输出文件夹失败", "请重试"); - + if (!outputFolder.mkdir()) return false; - } for (String originPath : targetFileList) { originPath = originPath.replace("\\", "/"); diff --git a/src/main/java/com/zzhow/magicencoding/ui/Application.java b/src/main/java/com/zzhow/magicencoding/ui/Application.java index 14ec309..9832968 100644 --- a/src/main/java/com/zzhow/magicencoding/ui/Application.java +++ b/src/main/java/com/zzhow/magicencoding/ui/Application.java @@ -7,9 +7,19 @@ import javafx.stage.Stage; import java.io.IOException; +import java.util.Locale; import java.util.Objects; +import java.util.ResourceBundle; public class Application extends javafx.application.Application { + public static String language; + public static ResourceBundle bundle; + + public static void setLanguage(String language) { + Application.language = language; + bundle = ResourceBundle.getBundle("MessagesBundle", new Locale(language)); + } + @Override public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(Application.class.getResource("main-view.fxml")); diff --git a/src/main/java/com/zzhow/magicencoding/utils/MessageBox.java b/src/main/java/com/zzhow/magicencoding/utils/MessageBox.java index 20cc47d..076fff7 100644 --- a/src/main/java/com/zzhow/magicencoding/utils/MessageBox.java +++ b/src/main/java/com/zzhow/magicencoding/utils/MessageBox.java @@ -1,6 +1,7 @@ package com.zzhow.magicencoding.utils; import com.zzhow.magicencoding.MainClass; +import com.zzhow.magicencoding.ui.Application; import javafx.scene.control.Alert; import javafx.scene.image.Image; import javafx.stage.Stage; @@ -28,14 +29,14 @@ public static void alert(Alert.AlertType type, String title, String headerText, public static void error(String headerText, String contentText) { alert(Alert.AlertType.ERROR, - "错误", + Application.bundle.getString("error"), headerText, contentText); } public static void success(String headerText, String contentText) { alert(Alert.AlertType.INFORMATION, - "成功", + Application.bundle.getString("success"), headerText, contentText); } diff --git a/src/main/resources/MessagesBundle_en.properties b/src/main/resources/MessagesBundle_en.properties new file mode 100644 index 0000000..0ee71dd --- /dev/null +++ b/src/main/resources/MessagesBundle_en.properties @@ -0,0 +1,24 @@ +Label1=Drag the folder to the gray area to get the path. Multiple suffixes can be separated by & +Label2=Folder: +Label3=Suffix: +Label4=Character set: +Label5=\u2192 +Label6=Hit files: +Label7=Number of files: +Button1=Reset +Button2=Find files +Button3=Start conversion +Button4=About +isOverwriteCheckBox=Overwrite the original file + +error=error +error1_headerText=There is no file that meets the conditions in the current folder +error1_contentText=Please check the conditions set +error2_headerText=There are currently no hit files +error2_contentText=Please try again +error3_headerText=Execution failed +error3_contentText=Please try again + +success=success +success1_headerText=Execution Success +success1_contentText=, number of files: \ No newline at end of file diff --git a/src/main/resources/MessagesBundle_zh_Hans.properties b/src/main/resources/MessagesBundle_zh_Hans.properties new file mode 100644 index 0000000..434de79 --- /dev/null +++ b/src/main/resources/MessagesBundle_zh_Hans.properties @@ -0,0 +1,22 @@ +Label1=\u5c06\u6587\u4ef6\u5939\u62d6\u62fd\u81f3\u7070\u8272\u533a\u57df\u4ee5\u83b7\u53d6\u8def\uff0c\u591a\u4e2a\u540e\u7f00\u540d\u53ef\u7528\u0026\u5206\u9694 +Label2=\u6587\u4ef6\u5939\uff1a +Label3=\u540e\u7f00\u540d\uff1a +Label4=\u5b57\u7b26\u96c6\uff1a +Label5=\u2192 +Label6=\u547d\u4e2d\u7684\u6587\u4ef6\uff1a +Label7=\u6587\u4ef6\u6570\u76ee\uff1a +Button1=\u91cd\u7f6e +Button2=\u67e5\u627e\u6587\u4ef6 +Button3=\u5f00\u59cb\u8f6c\u6362 +Button4=\u5173\u4e8e +isOverwriteCheckBox=\u8986\u76d6\u539f\u6587\u4ef6 +error=\u9519\u8bef +error1_headerText=\u5f53\u524d\u6587\u4ef6\u5939\u4e0b\u6ca1\u6709\u6ee1\u8db3\u6761\u4ef6\u7684\u6587\u4ef6 +error1_contentText=\u8bf7\u68c0\u67e5\u8bbe\u7f6e\u7684\u6761\u4ef6 +error2_headerText=\u5f53\u524d\u6ca1\u6709\u547d\u4e2d\u7684\u6587\u4ef6 +error2_contentText=\u8bf7\u91cd\u8bd5 +error3_headerText=\u6267\u884c\u5931\u8d25 +error3_contentText=\u8bf7\u91cd\u8bd5 +success=\u6267\u884c\u6210\u529f +success1_headerText=\u6267\u884c\u6210\u529f +success1_contentText=\uff0c\u6587\u4ef6\u6570\u76ee\uff1a \ No newline at end of file diff --git a/src/main/resources/MessagesBundle_zh_Hant.properties b/src/main/resources/MessagesBundle_zh_Hant.properties new file mode 100644 index 0000000..3a6b5bd --- /dev/null +++ b/src/main/resources/MessagesBundle_zh_Hant.properties @@ -0,0 +1,24 @@ +Label1=\u5c07\u8cc7\u6599\u593e\u62d6\u66f3\u81f3\u7070\u8272\u5340\u57df\u4ee5\u53d6\u5f97\u8def\uff0c\u591a\u500b\u5f8c\u7db4\u540d\u53ef\u7528\u0026\u5206\u9694 +Label2=\u8cc7\u6599\u593e\uff1a +Label3=\u5f8c\u7db4\u540d\uff1a +Label4=\u5b57\u5143\u96c6\uff1a +Label5=\u2192 +Label6=\u547d\u4e2d\u7684\u6a94\u6848\uff1a +Label7=\u6587\u4ef6\u6578\u76ee\uff1a +Button1=\u91cd\u7f6e +Button2=\u67e5\u627e\u6587\u4ef6 +Button3=\u958b\u59cb\u8f49\u63db +Button4=\u95dc\u65bc +isOverwriteCheckBox=\u8986\u84cb\u539f\u6587\u4ef6 + +error=\u932f\u8aa4 +error1_headerText=\u7576\u524d\u8cc7\u6599\u593e\u4e0b\u6c92\u6709\u6eff\u8db3\u689d\u4ef6\u7684\u6587\u4ef6 +error1_contentText=\u8acb\u6aa2\u67e5\u8a2d\u5b9a\u7684\u689d\u4ef6 +error2_headerText=\u76ee\u524d\u6c92\u6709\u547d\u4e2d\u7684\u6587\u4ef6 +error2_contentText=\u8acb\u91cd\u8a66 +error3_headerText=\u57f7\u884c\u5931\u6557 +error3_contentText=\u8acb\u91cd\u8a66 + +success=\u57f7\u884c\u6210\u529f +success1_headerText=\u57f7\u884c\u6210\u529f +success1_contentText=\uff0c\u6587\u4ef6\u6578\u76ee\uff1a \ No newline at end of file diff --git a/src/main/resources/com/zzhow/magicencoding/ui/main-view.fxml b/src/main/resources/com/zzhow/magicencoding/ui/main-view.fxml index 1cd3482..dccd119 100644 --- a/src/main/resources/com/zzhow/magicencoding/ui/main-view.fxml +++ b/src/main/resources/com/zzhow/magicencoding/ui/main-view.fxml @@ -10,38 +10,36 @@ - + - + - + -