refactor: #I7W8LM 国际化和本地化使用i18n

This commit is contained in:
songdragon 2023-08-27 16:37:13 +08:00
parent 667222ce91
commit 2f78ab6632
16 changed files with 307 additions and 327 deletions

7
.idea/encodings.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -9,10 +9,12 @@ import javafx.scene.image.Image;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.jcnc.jnotepad.app.config.LocalizationConfig; 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.LoadJnotepadConfig;
import org.jcnc.jnotepad.app.init.LoadLanguageConfig; import org.jcnc.jnotepad.app.init.LoadLanguageConfig;
import org.jcnc.jnotepad.app.init.LoadShortcutKeyConfig; import org.jcnc.jnotepad.app.init.LoadShortcutKeyConfig;
import org.jcnc.jnotepad.constants.AppConstants; import org.jcnc.jnotepad.constants.AppConstants;
import org.jcnc.jnotepad.constants.TextConstants;
import org.jcnc.jnotepad.controller.manager.Controller; import org.jcnc.jnotepad.controller.manager.Controller;
import org.jcnc.jnotepad.manager.ThreadPoolManager; import org.jcnc.jnotepad.manager.ThreadPoolManager;
import org.jcnc.jnotepad.ui.LineNumberTextArea; import org.jcnc.jnotepad.ui.LineNumberTextArea;
@ -82,7 +84,7 @@ public class LunchApp extends Application {
viewManager.initScreen(scene); viewManager.initScreen(scene);
// 加载配置文件 // 加载配置文件
View.getInstance().initJnotepadConfigs(LOAD_JNOTEPAD_CONFIGS); View.getInstance().initJnotepadConfigs(LOAD_JNOTEPAD_CONFIGS);
primaryStage.setTitle(localizationConfig.getTitle()); UIResourceBundle.bindStringProperty(primaryStage.titleProperty(), TextConstants.TITLE);
primaryStage.setWidth(width); primaryStage.setWidth(width);
primaryStage.setHeight(length); primaryStage.setHeight(length);
primaryStage.setScene(scene); primaryStage.setScene(scene);

View File

@ -31,4 +31,5 @@ public class GlobalConfig {
public static GlobalConfig getConfig() { public static GlobalConfig getConfig() {
return APP_GLOBAL_CONFIG; return APP_GLOBAL_CONFIG;
} }
} }

View File

@ -1,12 +1,13 @@
package org.jcnc.jnotepad.app.config; package org.jcnc.jnotepad.app.config;
import org.jcnc.jnotepad.LunchApp; import org.jcnc.jnotepad.LunchApp;
import org.jcnc.jnotepad.app.i18n.UIResourceBundle;
import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.LogUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; 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.AppConstants.APP_NAME;
import static org.jcnc.jnotepad.constants.TextConstants.*; import static org.jcnc.jnotepad.constants.TextConstants.*;
@ -14,300 +15,58 @@ import static org.jcnc.jnotepad.constants.TextConstants.*;
/** /**
* 本地化配置文件<br> * 本地化配置文件<br>
* 注意该配置文件必须先于快捷键配置文件加载 * 注意该配置文件必须先于快捷键配置文件加载
* @see LunchApp *
* @author gewuyou * @author gewuyou
* @see LunchApp
*/ */
public class LocalizationConfig { public class LocalizationConfig {
Logger logger = LogUtil.getLogger(this.getClass());
private static final LocalizationConfig LOCALIZATION_CONFIG = new LocalizationConfig(); private static final LocalizationConfig LOCALIZATION_CONFIG = new LocalizationConfig();
private final Properties properties = new Properties(); private final Properties properties = new Properties();
/** private String language;
* 本地化语言包名默认英文
*/ private static final Map<String, Locale> SUPPORT_LOCALES;
private String languagePackName = EN_LANGUAGE_PACK_NAME; private static final Map<Locale, String> 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() { 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 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() { public static LocalizationConfig getLocalizationConfig() {
return LOCALIZATION_CONFIG; 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() { public String getTextWrap() {
return textWrap; return textWrap;
@ -317,4 +76,12 @@ public class LocalizationConfig {
this.textWrap = textWrap; this.textWrap = textWrap;
properties.setProperty(TEXT_WRAP, textWrap); properties.setProperty(TEXT_WRAP, textWrap);
} }
private void setLanguage(String language) {
this.language = language;
}
public String getLanguage() {
return this.language;
}
} }

View File

@ -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<ResourceBundle> resources = new SimpleObjectProperty<>();
public ObjectProperty<ResourceBundle> 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);
}
}

View File

@ -85,7 +85,6 @@ public abstract class LoadJnotepadConfig<T> {
} catch (IOException e) { } catch (IOException e) {
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!"); PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
} }
LocalizationConfig.getLocalizationConfig().initLocalizationConfig();
} }

View File

@ -8,8 +8,6 @@ import org.slf4j.Logger;
import java.io.InputStream; import java.io.InputStream;
import static org.jcnc.jnotepad.constants.TextConstants.LANGUAGE_FILE_MAP;
/** /**
* 加载语言配置文件 * 加载语言配置文件
* *
@ -31,12 +29,10 @@ public class LoadLanguageConfig extends LoadJnotepadConfig<String> {
String language = parseConfig(inputStream); String language = parseConfig(inputStream);
if (!"".equals(language) && language != null) { if (!"".equals(language) && language != null) {
log.info("正在加载语言包:{}", language); log.info("正在加载语言包:{}", language);
localizationConfig.setLanguagePackName(LANGUAGE_FILE_MAP.get(language));
// 刷新语言包 // 刷新语言包
localizationConfig.initLocalizationConfig(); localizationConfig.setCurrentLocal(language);
JNotepadMenuBar jNotepadMenuBar = JNotepadMenuBar.getMenuBar(); JNotepadMenuBar jNotepadMenuBar = JNotepadMenuBar.getMenuBar();
// 刷新菜单栏 // 刷新菜单栏
jNotepadMenuBar.initMenuBar();
jNotepadMenuBar.toggleLanguageCheck(language); jNotepadMenuBar.toggleLanguageCheck(language);
JNotepadStatusBox.getInstance().initStatusBox(); JNotepadStatusBox.getInstance().initStatusBox();
} }

View File

@ -66,13 +66,7 @@ public class TextConstants {
public static final String CHINESE = "chinese"; public static final String CHINESE = "chinese";
public static final String LOWER_LANGUAGE = "language"; public static final String LOWER_LANGUAGE = "language";
/**
* 语言映射
*/
public static final Map<String, String> LANGUAGE_FILE_MAP = Map.of(
CHINESE, CH_LANGUAGE_PACK_NAME,
ENGLISH, EN_LANGUAGE_PACK_NAME
);
/// 配置文件文本常量 /// 配置文件文本常量
/** /**
* 内置配置文件 * 内置配置文件

View File

@ -3,6 +3,8 @@ package org.jcnc.jnotepad.controller.event.handler;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import org.jcnc.jnotepad.app.config.LocalizationConfig; 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.LineNumberTextArea;
import org.jcnc.jnotepad.ui.status.JNotepadStatusBox; import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;
import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTab;
@ -20,7 +22,6 @@ import org.jcnc.jnotepad.view.manager.ViewManager;
public class NewFile implements EventHandler<ActionEvent> { public class NewFile implements EventHandler<ActionEvent> {
/** /**
*
* 处理新建文件事件 * 处理新建文件事件
* *
* @param event 事件对象 * @param event 事件对象
@ -34,7 +35,7 @@ public class NewFile implements EventHandler<ActionEvent> {
// TODO: refactor统一TextArea新建绑定监听器入口 // TODO: refactor统一TextArea新建绑定监听器入口
ViewManager viewManager = ViewManager.getInstance(); ViewManager viewManager = ViewManager.getInstance();
// 将Tab页添加到TabPane中 // 将Tab页添加到TabPane中
JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(LocalizationConfig.getLocalizationConfig().getNewFile() JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(UIResourceBundle.getContent(TextConstants.NEW_FILE)
+ viewManager.selfIncreaseAndGetTabIndex(), + viewManager.selfIncreaseAndGetTabIndex(),
textArea)); textArea));

View File

@ -4,6 +4,8 @@ import javafx.application.Platform;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import org.jcnc.jnotepad.Interface.ControllerInterface; import org.jcnc.jnotepad.Interface.ControllerInterface;
import org.jcnc.jnotepad.app.config.LocalizationConfig; 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.manager.ThreadPoolManager;
import org.jcnc.jnotepad.tool.EncodingDetector; import org.jcnc.jnotepad.tool.EncodingDetector;
import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.tool.LogUtil;
@ -114,7 +116,7 @@ public class Controller implements ControllerInterface {
@Override @Override
public void updateUiWithNewTextArea(LineNumberTextArea textArea) { public void updateUiWithNewTextArea(LineNumberTextArea textArea) {
ViewManager viewManager = ViewManager.getInstance(); 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)); JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(tabTitle, textArea));
} }

View File

@ -41,11 +41,11 @@ public class EncodingDetector {
charsetDetector.setText(inputStream); charsetDetector.setText(inputStream);
CharsetMatch[] matchList = charsetDetector.detectAll(); CharsetMatch[] matchList = charsetDetector.detectAll();
if (matchList == null || matchList.length == 0) { if (matchList == null || matchList.length == 0) {
return localizationConfig.getUnknown(); return null;
} }
CharsetMatch maxConfidence = matchList[0]; CharsetMatch maxConfidence = matchList[0];
if (maxConfidence.getConfidence() < THRESHOLD_CONFIDENCE) { if (maxConfidence.getConfidence() < THRESHOLD_CONFIDENCE) {
return localizationConfig.getUnknown(); return null;
} }
for (int i = 1; i < matchList.length; i++) { for (int i = 1; i < matchList.length; i++) {
CharsetMatch match = matchList[i]; CharsetMatch match = matchList[i];
@ -59,7 +59,7 @@ public class EncodingDetector {
} catch (Exception e) { } catch (Exception e) {
LOG.error("", e); LOG.error("", e);
} }
return localizationConfig.getUnknown(); return null;
} }
/** /**

View File

@ -8,6 +8,8 @@ import javafx.stage.Stage;
import org.jcnc.jnotepad.LunchApp; import org.jcnc.jnotepad.LunchApp;
import org.jcnc.jnotepad.app.config.GlobalConfig; import org.jcnc.jnotepad.app.config.GlobalConfig;
import org.jcnc.jnotepad.app.config.LocalizationConfig; 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.controller.event.handler.*;
import org.jcnc.jnotepad.exception.AppException; import org.jcnc.jnotepad.exception.AppException;
import org.jcnc.jnotepad.tool.JsonUtil; import org.jcnc.jnotepad.tool.JsonUtil;
@ -20,6 +22,7 @@ import org.slf4j.Logger;
import java.io.*; import java.io.*;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import static com.fasterxml.jackson.core.JsonEncoding.UTF8; import static com.fasterxml.jackson.core.JsonEncoding.UTF8;
@ -44,7 +47,7 @@ public class JNotepadMenuBar extends MenuBar {
Logger logger = LogUtil.getLogger(this.getClass()); Logger logger = LogUtil.getLogger(this.getClass());
private JNotepadMenuBar() { private JNotepadMenuBar() {
initMenuBar();
} }
/** /**
@ -148,16 +151,21 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化语言菜单 * 初始化语言菜单
*/ */
private void initLanguageMenu() { 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(); 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); itemMap.put("chineseItem", chineseItem);
languageToggleGroup.getToggles().add(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); itemMap.put("englishItem", englishItem);
languageToggleGroup.getToggles().add(englishItem); languageToggleGroup.getToggles().add(englishItem);
@ -169,20 +177,26 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化文件菜单 * 初始化文件菜单
*/ */
private void initFileMenu() { 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); itemMap.put("newItem", newItem);
openItem = new MenuItem(localizationConfig.getOpen()); openItem = new MenuItem();
UIResourceBundle.bindStringProperty(openItem.textProperty(), OPEN);
itemMap.put("openItem", openItem); itemMap.put("openItem", openItem);
saveItem = new MenuItem(localizationConfig.getSava()); saveItem = new MenuItem();
UIResourceBundle.bindStringProperty(saveItem.textProperty(), SAVE);
itemMap.put("saveItem", saveItem); itemMap.put("saveItem", saveItem);
saveAsItem = new MenuItem(localizationConfig.getSavaAs()); saveAsItem = new MenuItem();
UIResourceBundle.bindStringProperty(saveAsItem.textProperty(), SAVE_AS);
itemMap.put("saveAsItem", saveAsItem); itemMap.put("saveAsItem", saveAsItem);
fileMenu.getItems().addAll(newItem, openItem, saveItem, saveAsItem); fileMenu.getItems().addAll(newItem, openItem, saveItem, saveAsItem);
@ -192,18 +206,22 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化设置菜单 * 初始化设置菜单
*/ */
private void initSettingMenu() { 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); itemMap.put("lineFeedItem", lineFeedItem);
lineFeedItem.selectedProperty().set(true); lineFeedItem.selectedProperty().set(true);
topItem = new CheckMenuItem(localizationConfig.getTop()); topItem = new CheckMenuItem();
UIResourceBundle.bindStringProperty(topItem.textProperty(), TOP);
itemMap.put("topItem", topItem); 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("openConfigItem", openConfigItem);
itemMap.put("languageMenu", languageMenu); itemMap.put("languageMenu", languageMenu);
@ -214,13 +232,17 @@ public class JNotepadMenuBar extends MenuBar {
* 初始化插件菜单 * 初始化插件菜单
*/ */
private void initPluginMenu() { private void initPluginMenu() {
logger.info("初始化插件菜单:{}", localizationConfig.getPlugin()); logger.info("初始化插件菜单:{}", UIResourceBundle.getContent(PLUGIN));
// 插件菜单 // 插件菜单
pluginMenu = new Menu(localizationConfig.getPlugin()); pluginMenu = new Menu();
addItem = new MenuItem(localizationConfig.getAddPlugin()); UIResourceBundle.bindStringProperty(pluginMenu.textProperty(), PLUGIN);
addItem = new MenuItem();
UIResourceBundle.bindStringProperty(addItem.textProperty(), ADD_PLUGIN);
itemMap.put("addItem", addItem); itemMap.put("addItem", addItem);
countItem = new MenuItem(localizationConfig.getStatistics()); countItem = new MenuItem();
UIResourceBundle.bindStringProperty(countItem.textProperty(), STATISTICS);
itemMap.put("countItem", countItem); itemMap.put("countItem", countItem);
pluginMenu.getItems().addAll(addItem, countItem); pluginMenu.getItems().addAll(addItem, countItem);
@ -254,8 +276,10 @@ public class JNotepadMenuBar extends MenuBar {
englishItem.setOnAction(new LocalizationHandler() { englishItem.setOnAction(new LocalizationHandler() {
@Override @Override
public void handle(ActionEvent actionEvent) { public void handle(ActionEvent actionEvent) {
try { try {
setCurrentLanguage(ENGLISH); setCurrentLanguage(ENGLISH);
toggleLanguage(actionEvent);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new AppException(e.getMessage()); throw new AppException(e.getMessage());
@ -267,7 +291,7 @@ public class JNotepadMenuBar extends MenuBar {
public void handle(ActionEvent actionEvent) { public void handle(ActionEvent actionEvent) {
try { try {
setCurrentLanguage(CHINESE); setCurrentLanguage(CHINESE);
toggleLanguage(actionEvent);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new AppException(e.getMessage()); 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());
}
/** /**
* 设置当前语言<br> * 设置当前语言<br>
* *
@ -283,7 +318,7 @@ public class JNotepadMenuBar extends MenuBar {
*/ */
private void setCurrentLanguage(String language) throws JsonProcessingException { private void setCurrentLanguage(String language) throws JsonProcessingException {
// 如果当前已是该语言则不执行该方法 // 如果当前已是该语言则不执行该方法
if (localizationConfig.getLanguagePackName().equals(LANGUAGE_FILE_MAP.get(language))) { if (localizationConfig.getLanguage().equals(language)) {
return; return;
} }
boolean flag = false; boolean flag = false;
@ -315,7 +350,7 @@ public class JNotepadMenuBar extends MenuBar {
writer.write(JsonUtil.toJsonString(json)); writer.write(JsonUtil.toJsonString(json));
// 刷新文件 // 刷新文件
writer.flush(); writer.flush();
// 重新加载语言包和快捷键 // 重新加载快捷键
View.getInstance().initJnotepadConfigs(LunchApp.getLocalizationConfigs()); View.getInstance().initJnotepadConfigs(LunchApp.getLocalizationConfigs());
logger.info("已刷新语言包!"); logger.info("已刷新语言包!");
logger.info("已刷新快捷键!"); logger.info("已刷新快捷键!");

View File

@ -1,14 +1,19 @@
package org.jcnc.jnotepad.ui.status; package org.jcnc.jnotepad.ui.status;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import org.jcnc.jnotepad.app.config.LocalizationConfig; 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.JNotepadTab;
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ResourceBundle;
/** /**
* 状态栏组件封装 * 状态栏组件封装
@ -20,16 +25,19 @@ import java.nio.charset.Charset;
public class JNotepadStatusBox extends HBox { public class JNotepadStatusBox extends HBox {
private static final JNotepadStatusBox STATUS_BOX = new JNotepadStatusBox(); private static final JNotepadStatusBox STATUS_BOX = new JNotepadStatusBox();
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
/** /**
* 字数统计及光标 * 字数统计及光标
*/ */
private Label statusLabel; 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() { private JNotepadStatusBox() {
initStatusBox(); initStatusBox();
@ -43,14 +51,23 @@ public class JNotepadStatusBox extends HBox {
public void initStatusBox() { public void initStatusBox() {
this.getChildren().clear(); 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(); updateEncodingLabel();
updateWhenTabSelected(); updateWhenTabSelected();
this.getChildren().add(statusLabel); this.getChildren().add(statusLabel);
this.getChildren().add(enCodingLabel); this.getChildren().add(encodingLabel);
this.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10)); this.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10));
UIResourceBundle.getInstance().addListener(new ChangeListener<ResourceBundle>() {
@Override
public void changed(ObservableValue<? extends ResourceBundle> observable, ResourceBundle oldValue, ResourceBundle newValue) {
updateWhenTabSelected();
}
});
} }
public static JNotepadStatusBox getInstance() { public static JNotepadStatusBox getInstance() {
@ -70,7 +87,7 @@ public class JNotepadStatusBox extends HBox {
if (encoding == null) { if (encoding == null) {
encoding = Charset.defaultCharset().name(); 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 row = getRow(caretPosition, textArea.getText());
int column = getColumn(caretPosition, textArea.getText()); int column = getColumn(caretPosition, textArea.getText());
int length = textArea.getLength(); 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); 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);
}
} }

View File

@ -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=编码

View File

@ -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

View File

@ -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=编码