!38 #I7W8LM 国际化和本地化使用i18n

Merge pull request !38 from songdragon/refactor-I7W8LM
This commit is contained in:
格物方能致知 2023-08-27 09:12:39 +00:00 committed by Gitee
commit 2eb71bece8
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
16 changed files with 348 additions and 338 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.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);

View File

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

View File

@ -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.*;
/**
* 本地化配置文件<br>
* 注意该配置文件必须先于快捷键配置文件加载
* @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<String, Locale> SUPPORT_LOCALES;
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() {
}
/**
* 初始化本地化语言包
*
* @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;
}
}

View File

@ -0,0 +1,119 @@
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;
/**
* UI资源绑定用于加载语言文件
*
* @author songdragon
*/
public class UIResourceBundle {
private static final UIResourceBundle INSTANCE = new UIResourceBundle();
/**
* resource目录下的i18n/i18nXXX.properties
*/
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<>();
/**
* 获取当前资源文件
* @return
*/
public ObjectProperty<ResourceBundle> resourcesProperty() {
return resources;
}
public final ResourceBundle getResources() {
return resourcesProperty().get();
}
public final void setResources(ResourceBundle resources) {
resourcesProperty().set(resources);
}
/**
* 重置当前local
*/
public final void resetLocal() {
if (this.currentLocale == LocalizationConfig.getCurrentLocal()) {
return;
}
this.currentLocale = LocalizationConfig.getCurrentLocal();
ResourceBundle resourceBundle = ResourceBundle.getBundle(BASENAME, currentLocale);
this.setResources(resourceBundle);
}
/**
* 获取key对应的绑定属性内容
* @param key key
* @return key对应的内容
*/
public StringBinding getStringBinding(String key) {
return new StringBinding() {
{
bind(resourcesProperty());
}
@Override
public String computeValue() {
return getResources().getString(key);
}
};
}
/**
* 工具方法绑定StringProperty和Key对应的内容
* @param stringProperty
* @param key
*/
public static void bindStringProperty(StringProperty stringProperty, String key) {
if (stringProperty == null) {
return;
}
stringProperty.bind(getInstance().getStringBinding(key));
}
/**
* 获取当前资源中的key值
* @param key
* @return
*/
public static String getContent(String key) {
return getInstance().getResources().getString(key);
}
/**
* 注册资源变更监听器
* @param listener
*/
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) {
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
}
LocalizationConfig.getLocalizationConfig().initLocalizationConfig();
}

View File

@ -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> {
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();
}

View File

@ -10,14 +10,8 @@ import org.jcnc.jnotepad.json.DataGenerator;
import org.jcnc.jnotepad.json.MyData;
import org.jcnc.jnotepad.tool.JsonUtil;
import java.util.Map;
/**
* 文本常量
* <p>
* 任何string请都在此处readPropertiesFromFile,然后在
* src/main/java/org/jcnc/jnotepad/init/Config.java的getXXXXXLanguagePack
* 注册配置文件,设置多语言语言包
* 文本常量被多处使用的常量放到此处如果只有一个class使用在class中使用private static final声明
*
* @author gewuyou
*/
@ -57,22 +51,12 @@ public class TextConstants {
public static final String ENCODE = "ENCODE";
/// Config 文本常量
public static final String CH_LANGUAGE_PACK_NAME = "ch_language_pack.txt";
public static final String EN_LANGUAGE_PACK_NAME = "en_language_pack.txt";
public static final String ENGLISH = "english";
public static final String CHINESE = "chinese";
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.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<ActionEvent> {
/**
*
* 处理新建文件事件
*
* @param event 事件对象
@ -34,7 +35,7 @@ public class NewFile implements EventHandler<ActionEvent> {
// 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));

View File

@ -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));
}

View File

@ -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;
}
/**

View File

@ -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());
}
/**
* 设置当前语言<br>
*
@ -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("已刷新快捷键!");

View File

@ -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<ResourceBundle>() {
@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);
}
}

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