diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..106fade
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/jnotepad/LunchApp.java b/src/main/java/org/jcnc/jnotepad/LunchApp.java
index 9b16a84..863a9e6 100644
--- a/src/main/java/org/jcnc/jnotepad/LunchApp.java
+++ b/src/main/java/org/jcnc/jnotepad/LunchApp.java
@@ -9,10 +9,12 @@ import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import org.jcnc.jnotepad.app.config.LocalizationConfig;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
import org.jcnc.jnotepad.app.init.LoadJnotepadConfig;
import org.jcnc.jnotepad.app.init.LoadLanguageConfig;
import org.jcnc.jnotepad.app.init.LoadShortcutKeyConfig;
import org.jcnc.jnotepad.constants.AppConstants;
+import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.controller.manager.Controller;
import org.jcnc.jnotepad.manager.ThreadPoolManager;
import org.jcnc.jnotepad.ui.LineNumberTextArea;
@@ -82,7 +84,7 @@ public class LunchApp extends Application {
viewManager.initScreen(scene);
// 加载配置文件
View.getInstance().initJnotepadConfigs(LOAD_JNOTEPAD_CONFIGS);
- primaryStage.setTitle(localizationConfig.getTitle());
+ UIResourceBundle.bindStringProperty(primaryStage.titleProperty(), TextConstants.TITLE);
primaryStage.setWidth(width);
primaryStage.setHeight(length);
primaryStage.setScene(scene);
diff --git a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java
index fbaaa51..bd4c16c 100644
--- a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java
+++ b/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java
@@ -31,4 +31,5 @@ public class GlobalConfig {
public static GlobalConfig getConfig() {
return APP_GLOBAL_CONFIG;
}
+
}
diff --git a/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java
index 17c7861..62a1735 100644
--- a/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java
+++ b/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java
@@ -1,12 +1,13 @@
package org.jcnc.jnotepad.app.config;
import org.jcnc.jnotepad.LunchApp;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
import org.jcnc.jnotepad.tool.LogUtil;
import org.slf4j.Logger;
import java.io.*;
import java.nio.charset.StandardCharsets;
-import java.util.Properties;
+import java.util.*;
import static org.jcnc.jnotepad.constants.AppConstants.APP_NAME;
import static org.jcnc.jnotepad.constants.TextConstants.*;
@@ -14,300 +15,58 @@ import static org.jcnc.jnotepad.constants.TextConstants.*;
/**
* 本地化配置文件
* 注意:该配置文件必须先于快捷键配置文件加载
- * @see LunchApp
+ *
* @author gewuyou
+ * @see LunchApp
*/
public class LocalizationConfig {
- Logger logger = LogUtil.getLogger(this.getClass());
private static final LocalizationConfig LOCALIZATION_CONFIG = new LocalizationConfig();
private final Properties properties = new Properties();
- /**
- * 本地化语言包名,默认英文
- */
- private String languagePackName = EN_LANGUAGE_PACK_NAME;
+ private String language;
+
+ private static final Map SUPPORT_LOCALES;
+ private static final Map SUPPORT_LANGUAGES;
+
+ static {
+ Locale.setDefault(Locale.ENGLISH);
+ SUPPORT_LOCALES = new LinkedHashMap<>();
+ SUPPORT_LOCALES.put(CHINESE, Locale.CHINESE);
+ SUPPORT_LOCALES.put(ENGLISH, Locale.ENGLISH);
+
+ SUPPORT_LANGUAGES = new HashMap<>();
+ SUPPORT_LANGUAGES.put(Locale.CHINESE, CHINESE);
+ SUPPORT_LANGUAGES.put(Locale.ENGLISH, ENGLISH);
+ }
+
+ public static final Locale getCurrentLocal() {
+ return Locale.getDefault();
+ }
+
+ public static final void setCurrentLocal(Locale locale) {
+ Locale.setDefault(locale);
+ UIResourceBundle.getInstance().resetLocal();
+ LOCALIZATION_CONFIG.setLanguage(SUPPORT_LANGUAGES.get(locale));
+ }
+
+ public static final void setCurrentLocal(String language) {
+ Locale locale = SUPPORT_LOCALES.get(language);
+ if (locale != null) {
+ setCurrentLocal(locale);
+ }
+ }
private LocalizationConfig() {
}
- /**
- * 初始化本地化语言包
- *
- * @since 2023/8/25 18:18
- */
- public void initLocalizationConfig() {
- // 设置语言包
- try (InputStream inputStream = new FileInputStream(languagePackName)) {
- // 使用 UTF-8 编码
- InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
- properties.load(reader);
- } catch (IOException e) {
- logger.info("未检测到本地化语言包!");
- // 如果读取出错,则调用初始化方法
- initializePropertiesFile();
- }
- logger.info("初始化本地化语言包成功!");
- title = properties.getProperty(TITLE, APP_NAME);
- sava = properties.getProperty(SAVE);
- file = properties.getProperty(FILE);
- newly = properties.getProperty(NEW);
- open = properties.getProperty(OPEN);
- savaAs = properties.getProperty(SAVE_AS);
- set = properties.getProperty(SET);
- wordWrap = properties.getProperty(WORD_WRAP);
- plugin = properties.getProperty(PLUGIN);
- addPlugin = properties.getProperty(ADD_PLUGIN);
- statistics = properties.getProperty(STATISTICS);
- openConfigurationFile = properties.getProperty(OPEN_CONFIGURATION_FILE);
- top = properties.getProperty(TOP);
- language = properties.getProperty(LANGUAGE);
- chinese = properties.getProperty(UPPER_CHINESE);
- english = properties.getProperty(UPPER_ENGLISH);
- textWrap = properties.getProperty(TEXT_WRAP, "true");
- newFile = properties.getProperty(NEW_FILE);
- unknown = properties.getProperty(UNKNOWN);
- row = properties.getProperty(ROW);
- column = properties.getProperty(COLUMN);
- wordCount = properties.getProperty(WORD_COUNT);
- encode = properties.getProperty(ENCODE);
- }
-
- /**
- * 初始化属性配置文件。
- * 如果属性文件不存在,将创建一个新的属性文件并设置默认属性。
- */
- public void initializePropertiesFile() {
- switch (languagePackName) {
- case CH_LANGUAGE_PACK_NAME -> {
- setChineseLanguagePack();
- createLanguagePacks(languagePackName, properties);
- }
- case EN_LANGUAGE_PACK_NAME -> {
- setEnglishLanguagePack();
- createLanguagePacks(languagePackName, properties);
- }
- default -> logger.error("语言包加载错误!");
- }
-
- }
-
- private void createLanguagePacks(String languagePackName, Properties languagePack) {
- try (OutputStream outputStream = new FileOutputStream(languagePackName)) {
- // 使用 UTF-8 编码
- OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
- languagePack.store(writer, languagePackName);
- } catch (IOException ignored) {
- logger.info("未检测到语言包!");
- }
- }
-
- private void setChineseLanguagePack() {
- properties.clear();
- // 设置默认属性
- properties.setProperty(TITLE, APP_NAME);
- properties.setProperty(NEW_FILE, "新建文件");
- properties.setProperty(SAVE, "保存");
- properties.setProperty(FILE, "文件");
- properties.setProperty(NEW, "新建");
- properties.setProperty(OPEN, "打开");
- properties.setProperty(SAVE_AS, "另存为");
- properties.setProperty(SET, "设置");
- properties.setProperty(WORD_WRAP, "自动换行");
- properties.setProperty(OPEN_CONFIGURATION_FILE, "打开配置文件");
- properties.setProperty(PLUGIN, "插件");
- properties.setProperty(ADD_PLUGIN, "增加插件");
- properties.setProperty(STATISTICS, "统计字数");
- properties.setProperty(ROW, "行数");
- properties.setProperty(COLUMN, "列数");
- properties.setProperty(WORD_COUNT, "字数");
- properties.setProperty(ENCODE, "编码");
- properties.setProperty(TOP, "窗口置顶");
- properties.setProperty(LANGUAGE, "语言");
- properties.setProperty(UPPER_CHINESE, "中文");
- properties.setProperty(UPPER_ENGLISH, "英文");
- }
-
- private void setEnglishLanguagePack() {
- properties.clear();
- properties.setProperty(TITLE, APP_NAME);
- properties.setProperty(NEW_FILE, "New File");
- properties.setProperty(SAVE, "Save");
- properties.setProperty(FILE, "File");
- properties.setProperty(NEW, "New");
- properties.setProperty(OPEN, "Open");
- properties.setProperty(SAVE_AS, "Save As");
- properties.setProperty(SET, "Settings");
- properties.setProperty(WORD_WRAP, "Word Wrap");
- properties.setProperty(OPEN_CONFIGURATION_FILE, "Open Configuration File");
- properties.setProperty(PLUGIN, "Plugins");
- properties.setProperty(ADD_PLUGIN, "Add Plugin");
- properties.setProperty(STATISTICS, "Word Count");
- properties.setProperty(ROW, "Row");
- properties.setProperty(COLUMN, "Column");
- properties.setProperty(WORD_COUNT, "Word Count");
- properties.setProperty(ENCODE, "Encoding");
- properties.setProperty(TOP, "Window Top");
- properties.setProperty(LANGUAGE, "Language");
- properties.setProperty(UPPER_CHINESE, "Chinese");
- properties.setProperty(UPPER_ENGLISH, "English");
- }
-
private String textWrap;
- /// 应用程序文本
- private String title;
-
- ///菜单栏文本
-
- private String sava;
-
- private String file;
-
- private String newly;
-
- private String open;
-
- private String savaAs;
-
- private String set;
-
- private String wordWrap;
-
- private String plugin;
-
- private String addPlugin;
-
- private String statistics;
-
- private String openConfigurationFile;
-
- private String top;
-
- private String language;
-
- private String chinese;
-
- private String english;
-
- /// NewFile 文本常量
-
- private String newFile;
- /// EncodingDetector 文本常量
- /**
- * 未知
- */
- private String unknown;
-
- /// JNotepadStatusBox
-
- private String row;
-
- private String column;
-
- private String wordCount;
-
- private String encode;
public static LocalizationConfig getLocalizationConfig() {
return LOCALIZATION_CONFIG;
}
- public void setLanguagePackName(String languagePackName) {
- this.languagePackName = languagePackName;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getSava() {
- return sava;
- }
-
- public String getFile() {
- return file;
- }
-
- public String getNewly() {
- return newly;
- }
-
- public String getOpen() {
- return open;
- }
-
- public String getSavaAs() {
- return savaAs;
- }
-
- public String getSet() {
- return set;
- }
-
- public String getWordWrap() {
- return wordWrap;
- }
-
- public String getPlugin() {
- return plugin;
- }
-
- public String getAddPlugin() {
- return addPlugin;
- }
-
- public String getStatistics() {
- return statistics;
- }
-
- public String getOpenConfigurationFile() {
- return openConfigurationFile;
- }
-
- public String getTop() {
- return top;
- }
-
- public String getLanguage() {
- return language;
- }
-
- public String getChinese() {
- return chinese;
- }
-
- public String getEnglish() {
- return english;
- }
-
- public String getNewFile() {
- return newFile;
- }
-
- public String getUnknown() {
- return unknown;
- }
-
- public String getRow() {
- return row;
- }
-
- public String getColumn() {
- return column;
- }
-
- public String getWordCount() {
- return wordCount;
- }
-
- public String getEncode() {
- return encode;
- }
-
- public String getLanguagePackName() {
- return languagePackName;
- }
public String getTextWrap() {
return textWrap;
@@ -317,4 +76,12 @@ public class LocalizationConfig {
this.textWrap = textWrap;
properties.setProperty(TEXT_WRAP, textWrap);
}
+
+ private void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getLanguage() {
+ return this.language;
+ }
}
diff --git a/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java b/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java
new file mode 100644
index 0000000..dc17d43
--- /dev/null
+++ b/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java
@@ -0,0 +1,79 @@
+package org.jcnc.jnotepad.app.i18n;
+
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import org.jcnc.jnotepad.app.config.LocalizationConfig;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public class UIResourceBundle {
+
+ private static final UIResourceBundle INSTANCE = new UIResourceBundle();
+ private static final String BASENAME = "i18n/i18n";
+
+ private Locale currentLocale;
+
+ public static final UIResourceBundle getInstance() {
+ return INSTANCE;
+ }
+
+ private UIResourceBundle() {
+ this.resetLocal();
+ }
+
+ private ObjectProperty resources = new SimpleObjectProperty<>();
+
+ public ObjectProperty resourcesProperty() {
+ return resources;
+ }
+
+ public final ResourceBundle getResources() {
+ return resourcesProperty().get();
+ }
+
+ public final void setResources(ResourceBundle resources) {
+ resourcesProperty().set(resources);
+ }
+
+ public final void resetLocal() {
+ if (this.currentLocale == LocalizationConfig.getCurrentLocal()) {
+ return;
+ }
+ this.currentLocale = LocalizationConfig.getCurrentLocal();
+ ResourceBundle resourceBundle = ResourceBundle.getBundle(BASENAME, currentLocale);
+ this.setResources(resourceBundle);
+
+ }
+
+ public StringBinding getStringBinding(String key) {
+ return new StringBinding() {
+ {
+ bind(resourcesProperty());
+ }
+
+ @Override
+ public String computeValue() {
+ return getResources().getString(key);
+ }
+ };
+ }
+
+ public static void bindStringProperty(StringProperty stringProperty, String key) {
+ if (stringProperty == null) {
+ return;
+ }
+ stringProperty.bind(getInstance().getStringBinding(key));
+ }
+
+ public static String getContent(String key) {
+ return getInstance().getResources().getString(key);
+ }
+
+ public void addListener(ChangeListener super ResourceBundle> listener) {
+ this.resources.addListener(listener);
+ }
+}
diff --git a/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java b/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java
index ee5b91e..858fbf7 100644
--- a/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java
+++ b/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java
@@ -85,7 +85,6 @@ public abstract class LoadJnotepadConfig {
} catch (IOException e) {
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
}
- LocalizationConfig.getLocalizationConfig().initLocalizationConfig();
}
diff --git a/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java b/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java
index ab0808d..747faf5 100644
--- a/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java
+++ b/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java
@@ -8,8 +8,6 @@ import org.slf4j.Logger;
import java.io.InputStream;
-import static org.jcnc.jnotepad.constants.TextConstants.LANGUAGE_FILE_MAP;
-
/**
* 加载语言配置文件
*
@@ -31,12 +29,10 @@ public class LoadLanguageConfig extends LoadJnotepadConfig {
String language = parseConfig(inputStream);
if (!"".equals(language) && language != null) {
log.info("正在加载语言包:{}", language);
- localizationConfig.setLanguagePackName(LANGUAGE_FILE_MAP.get(language));
// 刷新语言包
- localizationConfig.initLocalizationConfig();
+ localizationConfig.setCurrentLocal(language);
JNotepadMenuBar jNotepadMenuBar = JNotepadMenuBar.getMenuBar();
// 刷新菜单栏
- jNotepadMenuBar.initMenuBar();
jNotepadMenuBar.toggleLanguageCheck(language);
JNotepadStatusBox.getInstance().initStatusBox();
}
diff --git a/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java
index 4242d75..c23864c 100644
--- a/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java
+++ b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java
@@ -66,13 +66,7 @@ public class TextConstants {
public static final String CHINESE = "chinese";
public static final String LOWER_LANGUAGE = "language";
- /**
- * 语言映射
- */
- public static final Map LANGUAGE_FILE_MAP = Map.of(
- CHINESE, CH_LANGUAGE_PACK_NAME,
- ENGLISH, EN_LANGUAGE_PACK_NAME
- );
+
/// 配置文件文本常量
/**
* 内置配置文件
diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java
index 5e56cca..c6bbcfa 100644
--- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java
+++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java
@@ -3,6 +3,8 @@ package org.jcnc.jnotepad.controller.event.handler;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import org.jcnc.jnotepad.app.config.LocalizationConfig;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
+import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
@@ -20,7 +22,6 @@ import org.jcnc.jnotepad.view.manager.ViewManager;
public class NewFile implements EventHandler {
/**
- *
* 处理新建文件事件。
*
* @param event 事件对象
@@ -34,7 +35,7 @@ public class NewFile implements EventHandler {
// TODO: refactor:统一TextArea新建、绑定监听器入口
ViewManager viewManager = ViewManager.getInstance();
// 将Tab页添加到TabPane中
- JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(LocalizationConfig.getLocalizationConfig().getNewFile()
+ JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(UIResourceBundle.getContent(TextConstants.NEW_FILE)
+ viewManager.selfIncreaseAndGetTabIndex(),
textArea));
diff --git a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java
index bd76b8f..e04b49c 100644
--- a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java
+++ b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java
@@ -4,6 +4,8 @@ import javafx.application.Platform;
import javafx.concurrent.Task;
import org.jcnc.jnotepad.Interface.ControllerInterface;
import org.jcnc.jnotepad.app.config.LocalizationConfig;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
+import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.manager.ThreadPoolManager;
import org.jcnc.jnotepad.tool.EncodingDetector;
import org.jcnc.jnotepad.tool.LogUtil;
@@ -114,7 +116,7 @@ public class Controller implements ControllerInterface {
@Override
public void updateUiWithNewTextArea(LineNumberTextArea textArea) {
ViewManager viewManager = ViewManager.getInstance();
- String tabTitle = LocalizationConfig.getLocalizationConfig().getNewFile() + viewManager.selfIncreaseAndGetTabIndex();
+ String tabTitle = UIResourceBundle.getContent(TextConstants.NEW_FILE) + viewManager.selfIncreaseAndGetTabIndex();
JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(tabTitle, textArea));
}
diff --git a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
index ef70411..628123b 100644
--- a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
+++ b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
@@ -41,11 +41,11 @@ public class EncodingDetector {
charsetDetector.setText(inputStream);
CharsetMatch[] matchList = charsetDetector.detectAll();
if (matchList == null || matchList.length == 0) {
- return localizationConfig.getUnknown();
+ return null;
}
CharsetMatch maxConfidence = matchList[0];
if (maxConfidence.getConfidence() < THRESHOLD_CONFIDENCE) {
- return localizationConfig.getUnknown();
+ return null;
}
for (int i = 1; i < matchList.length; i++) {
CharsetMatch match = matchList[i];
@@ -59,7 +59,7 @@ public class EncodingDetector {
} catch (Exception e) {
LOG.error("", e);
}
- return localizationConfig.getUnknown();
+ return null;
}
/**
diff --git a/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java b/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java
index 6ec15c9..356d282 100644
--- a/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java
+++ b/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java
@@ -8,6 +8,8 @@ import javafx.stage.Stage;
import org.jcnc.jnotepad.LunchApp;
import org.jcnc.jnotepad.app.config.GlobalConfig;
import org.jcnc.jnotepad.app.config.LocalizationConfig;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
+import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.controller.event.handler.*;
import org.jcnc.jnotepad.exception.AppException;
import org.jcnc.jnotepad.tool.JsonUtil;
@@ -20,6 +22,7 @@ import org.slf4j.Logger;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import static com.fasterxml.jackson.core.JsonEncoding.UTF8;
@@ -44,7 +47,7 @@ public class JNotepadMenuBar extends MenuBar {
Logger logger = LogUtil.getLogger(this.getClass());
private JNotepadMenuBar() {
-
+ initMenuBar();
}
/**
@@ -148,16 +151,21 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化语言菜单
*/
private void initLanguageMenu() {
- logger.info("初始化语言菜单:{}", localizationConfig.getLanguage());
+ logger.info("初始化语言菜单:{}", UIResourceBundle.getContent(LANGUAGE));
// 语言菜单
- languageMenu = new Menu(localizationConfig.getLanguage());
+ languageMenu = new Menu();
+ UIResourceBundle.bindStringProperty(languageMenu.textProperty(), LANGUAGE);
ToggleGroup languageToggleGroup = new ToggleGroup();
- chineseItem = new RadioMenuItem(localizationConfig.getChinese());
+ chineseItem = new RadioMenuItem();
+ UIResourceBundle.bindStringProperty(chineseItem.textProperty(), UPPER_CHINESE);
+ chineseItem.setUserData(Locale.CHINESE);
itemMap.put("chineseItem", chineseItem);
languageToggleGroup.getToggles().add(chineseItem);
- englishItem = new RadioMenuItem(localizationConfig.getEnglish());
+ englishItem = new RadioMenuItem();
+ UIResourceBundle.bindStringProperty(englishItem.textProperty(), UPPER_ENGLISH);
+ englishItem.setUserData(Locale.ENGLISH);
itemMap.put("englishItem", englishItem);
languageToggleGroup.getToggles().add(englishItem);
@@ -169,20 +177,26 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化文件菜单
*/
private void initFileMenu() {
- logger.info("初始化文件菜单:{}", localizationConfig.getFile());
+ logger.info("初始化文件菜单:{}", UIResourceBundle.getContent(FILE));
// 文件菜单
- fileMenu = new Menu(localizationConfig.getFile());
+ fileMenu = new Menu();
+ UIResourceBundle.bindStringProperty(fileMenu.textProperty(), FILE);
+
+ newItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(newItem.textProperty(), NEW);
- newItem = new MenuItem(localizationConfig.getNewly());
itemMap.put("newItem", newItem);
- openItem = new MenuItem(localizationConfig.getOpen());
+ openItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(openItem.textProperty(), OPEN);
itemMap.put("openItem", openItem);
- saveItem = new MenuItem(localizationConfig.getSava());
+ saveItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(saveItem.textProperty(), SAVE);
itemMap.put("saveItem", saveItem);
- saveAsItem = new MenuItem(localizationConfig.getSavaAs());
+ saveAsItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(saveAsItem.textProperty(), SAVE_AS);
itemMap.put("saveAsItem", saveAsItem);
fileMenu.getItems().addAll(newItem, openItem, saveItem, saveAsItem);
@@ -192,18 +206,22 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化设置菜单
*/
private void initSettingMenu() {
- logger.info("初始化设置菜单:{}", localizationConfig.getSet());
+ logger.info("初始化设置菜单:{}", UIResourceBundle.getContent(SET));
// 设置菜单
- setMenu = new Menu(localizationConfig.getSet());
+ setMenu = new Menu();
+ UIResourceBundle.bindStringProperty(setMenu.textProperty(), SET);
- lineFeedItem = new CheckMenuItem(localizationConfig.getWordWrap());
+ lineFeedItem = new CheckMenuItem();
+ UIResourceBundle.bindStringProperty(lineFeedItem.textProperty(), WORD_WRAP);
itemMap.put("lineFeedItem", lineFeedItem);
lineFeedItem.selectedProperty().set(true);
- topItem = new CheckMenuItem(localizationConfig.getTop());
+ topItem = new CheckMenuItem();
+ UIResourceBundle.bindStringProperty(topItem.textProperty(), TOP);
itemMap.put("topItem", topItem);
- openConfigItem = new MenuItem(localizationConfig.getOpenConfigurationFile());
+ openConfigItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(openConfigItem.textProperty(), OPEN_CONFIGURATION_FILE);
itemMap.put("openConfigItem", openConfigItem);
itemMap.put("languageMenu", languageMenu);
@@ -214,13 +232,17 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化插件菜单
*/
private void initPluginMenu() {
- logger.info("初始化插件菜单:{}", localizationConfig.getPlugin());
+ logger.info("初始化插件菜单:{}", UIResourceBundle.getContent(PLUGIN));
// 插件菜单
- pluginMenu = new Menu(localizationConfig.getPlugin());
- addItem = new MenuItem(localizationConfig.getAddPlugin());
+ pluginMenu = new Menu();
+ UIResourceBundle.bindStringProperty(pluginMenu.textProperty(), PLUGIN);
+
+ addItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(addItem.textProperty(), ADD_PLUGIN);
itemMap.put("addItem", addItem);
- countItem = new MenuItem(localizationConfig.getStatistics());
+ countItem = new MenuItem();
+ UIResourceBundle.bindStringProperty(countItem.textProperty(), STATISTICS);
itemMap.put("countItem", countItem);
pluginMenu.getItems().addAll(addItem, countItem);
@@ -254,8 +276,10 @@ public class JNotepadMenuBar extends MenuBar {
englishItem.setOnAction(new LocalizationHandler() {
@Override
public void handle(ActionEvent actionEvent) {
+
try {
setCurrentLanguage(ENGLISH);
+ toggleLanguage(actionEvent);
} catch (JsonProcessingException e) {
throw new AppException(e.getMessage());
@@ -267,7 +291,7 @@ public class JNotepadMenuBar extends MenuBar {
public void handle(ActionEvent actionEvent) {
try {
setCurrentLanguage(CHINESE);
-
+ toggleLanguage(actionEvent);
} catch (JsonProcessingException e) {
throw new AppException(e.getMessage());
}
@@ -275,6 +299,17 @@ public class JNotepadMenuBar extends MenuBar {
});
}
+ private void toggleLanguage(ActionEvent actionEvent) {
+ if (actionEvent == null) {
+ return;
+ }
+ RadioMenuItem languageItem = (RadioMenuItem) actionEvent.getSource();
+ if (languageItem == null) {
+ return;
+ }
+ LocalizationConfig.setCurrentLocal((Locale) languageItem.getUserData());
+ }
+
/**
* 设置当前语言
*
@@ -283,7 +318,7 @@ public class JNotepadMenuBar extends MenuBar {
*/
private void setCurrentLanguage(String language) throws JsonProcessingException {
// 如果当前已是该语言则不执行该方法
- if (localizationConfig.getLanguagePackName().equals(LANGUAGE_FILE_MAP.get(language))) {
+ if (localizationConfig.getLanguage().equals(language)) {
return;
}
boolean flag = false;
@@ -315,7 +350,7 @@ public class JNotepadMenuBar extends MenuBar {
writer.write(JsonUtil.toJsonString(json));
// 刷新文件
writer.flush();
- // 重新加载语言包和快捷键
+ // 重新加载快捷键
View.getInstance().initJnotepadConfigs(LunchApp.getLocalizationConfigs());
logger.info("已刷新语言包!");
logger.info("已刷新快捷键!");
diff --git a/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java b/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java
index 5839324..01c681f 100644
--- a/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java
+++ b/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java
@@ -1,14 +1,19 @@
package org.jcnc.jnotepad.ui.status;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import org.jcnc.jnotepad.app.config.LocalizationConfig;
+import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
+import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
import java.nio.charset.Charset;
+import java.util.ResourceBundle;
/**
* 状态栏组件封装。
@@ -20,16 +25,19 @@ import java.nio.charset.Charset;
public class JNotepadStatusBox extends HBox {
private static final JNotepadStatusBox STATUS_BOX = new JNotepadStatusBox();
- LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
/**
* 字数统计及光标
*/
private Label statusLabel;
+ private static final String STATUS_LABEL_FORMAT = "%s : %d \t%s: %d \t%s: %d \t";
+
/**
* 显示文本编码
*/
- private Label enCodingLabel;
+ private Label encodingLabel;
+ private final String ENCODING_LABEL_FORMAT = "\t%s : %s";
+
private JNotepadStatusBox() {
initStatusBox();
@@ -43,14 +51,23 @@ public class JNotepadStatusBox extends HBox {
public void initStatusBox() {
this.getChildren().clear();
// 创建状态栏
- statusLabel = new Label(localizationConfig.getRow() + ":1 \t" + localizationConfig.getColumn() + ":1 \t" + localizationConfig.getWordCount() + ":0 ");
+ statusLabel = new Label();
+ statusLabel.setText(getStatusBarFormattedText(0, 0, 1));
// 创建新的标签以显示编码信息
- enCodingLabel = new Label();
+ encodingLabel = new Label();
updateEncodingLabel();
updateWhenTabSelected();
this.getChildren().add(statusLabel);
- this.getChildren().add(enCodingLabel);
+ this.getChildren().add(encodingLabel);
this.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10));
+
+ UIResourceBundle.getInstance().addListener(new ChangeListener() {
+ @Override
+ public void changed(ObservableValue extends ResourceBundle> observable, ResourceBundle oldValue, ResourceBundle newValue) {
+ updateWhenTabSelected();
+ }
+ });
+
}
public static JNotepadStatusBox getInstance() {
@@ -70,7 +87,7 @@ public class JNotepadStatusBox extends HBox {
if (encoding == null) {
encoding = Charset.defaultCharset().name();
}
- this.enCodingLabel.setText("\t" + localizationConfig.getEncode() + ": " + encoding);
+ this.encodingLabel.setText(getEncodingFormattedText(encoding));
}
/**
@@ -86,7 +103,7 @@ public class JNotepadStatusBox extends HBox {
int row = getRow(caretPosition, textArea.getText());
int column = getColumn(caretPosition, textArea.getText());
int length = textArea.getLength();
- this.statusLabel.setText(localizationConfig.getRow() + ": " + row + " \t" + localizationConfig.getColumn() + ": " + column + " \t" + localizationConfig.getWordCount() + ": " + length);
+ this.statusLabel.setText(getStatusBarFormattedText(row, column, length));
}
/**
@@ -135,4 +152,21 @@ public class JNotepadStatusBox extends HBox {
return caretPosition - text.lastIndexOf("\n", caretPosition - 1);
}
+ protected String getStatusBarFormattedText(int row, int column, int wordCount) {
+ String rowText = UIResourceBundle.getContent(TextConstants.ROW);
+ String columnText = UIResourceBundle.getContent(TextConstants.COLUMN);
+ String wordCountText = UIResourceBundle.getContent(TextConstants.WORD_COUNT);
+ return String.format(STATUS_LABEL_FORMAT,
+ rowText,
+ row,
+ columnText,
+ column,
+ wordCountText,
+ wordCount
+ );
+ }
+
+ protected String getEncodingFormattedText(String encoding) {
+ return String.format(ENCODING_LABEL_FORMAT, UIResourceBundle.getContent(TextConstants.ENCODE), encoding);
+ }
}
diff --git a/src/main/resources/i18n/i18n.properties b/src/main/resources/i18n/i18n.properties
new file mode 100644
index 0000000..3c690ee
--- /dev/null
+++ b/src/main/resources/i18n/i18n.properties
@@ -0,0 +1,21 @@
+LANGUAGE=语言
+NEW_FILE=新建文件
+NEW=新建
+SET=设置
+ENGLISH=英文
+STATISTICS=统计字数
+COLUMN=列数
+PLUGIN=插件
+CHINESE=中文
+title=JNotepad
+OPEN=打开
+OPEN_CONFIGURATION_FILE=打开配置文件
+TOP=窗口置顶
+WORD_WRAP=自动换行
+WORD_COUNT=字数
+SAVE_AS=另存为
+SAVE=保存
+ROW=行数
+FILE=文件
+ADD_PLUGIN=增加插件
+ENCODE=编码
diff --git a/src/main/resources/i18n/i18n_en.properties b/src/main/resources/i18n/i18n_en.properties
new file mode 100644
index 0000000..a15edd1
--- /dev/null
+++ b/src/main/resources/i18n/i18n_en.properties
@@ -0,0 +1,21 @@
+LANGUAGE=Language
+NEW=New
+NEW_FILE=New File
+SET=Settings
+ENGLISH=English
+STATISTICS=Word Count
+COLUMN=Column
+PLUGIN=Plugins
+CHINESE=Chinese
+title=JNotepad
+OPEN=Open
+OPEN_CONFIGURATION_FILE=Open Configuration File
+TOP=Window Top
+WORD_WRAP=Word Wrap
+WORD_COUNT=Word Count
+SAVE_AS=Save As
+SAVE=Save
+ROW=Row
+FILE=File
+ADD_PLUGIN=Add Plugin
+ENCODE=Encoding
\ No newline at end of file
diff --git a/src/main/resources/i18n/i18n_zh_CN.properties b/src/main/resources/i18n/i18n_zh_CN.properties
new file mode 100644
index 0000000..3c690ee
--- /dev/null
+++ b/src/main/resources/i18n/i18n_zh_CN.properties
@@ -0,0 +1,21 @@
+LANGUAGE=语言
+NEW_FILE=新建文件
+NEW=新建
+SET=设置
+ENGLISH=英文
+STATISTICS=统计字数
+COLUMN=列数
+PLUGIN=插件
+CHINESE=中文
+title=JNotepad
+OPEN=打开
+OPEN_CONFIGURATION_FILE=打开配置文件
+TOP=窗口置顶
+WORD_WRAP=自动换行
+WORD_COUNT=字数
+SAVE_AS=另存为
+SAVE=保存
+ROW=行数
+FILE=文件
+ADD_PLUGIN=增加插件
+ENCODE=编码