commit
2f17aa5090
6
.gitignore
vendored
6
.gitignore
vendored
@ -2,13 +2,15 @@ target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
test/
|
||||
### IntelliJ IDEA ###
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### 此处忽略了json与xml后缀
|
||||
*.xml
|
||||
*.json
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
|
||||
@ -12,7 +12,6 @@ module org.jcnc.jnotepad {
|
||||
requires ch.qos.logback.core;
|
||||
requires ch.qos.logback.classic;
|
||||
requires com.ibm.icu;
|
||||
|
||||
exports org.jcnc.jnotepad.app.config;
|
||||
exports org.jcnc.jnotepad;
|
||||
exports org.jcnc.jnotepad.tool;
|
||||
|
||||
@ -7,20 +7,24 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import org.jcnc.jnotepad.app.config.LoadJnotepadConfig;
|
||||
import org.jcnc.jnotepad.app.config.LoadLanguageConfig;
|
||||
import org.jcnc.jnotepad.app.config.LoadShortcutKeyConfig;
|
||||
import org.jcnc.jnotepad.app.config.LocalizationConfig;
|
||||
import org.jcnc.jnotepad.constants.AppConstants;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
import org.jcnc.jnotepad.init.Config;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
import org.jcnc.jnotepad.view.init.View;
|
||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
*
|
||||
@ -31,25 +35,29 @@ public class LunchApp extends Application {
|
||||
* 线程池
|
||||
*/
|
||||
private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();
|
||||
|
||||
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
Controller controller = Controller.getInstance();
|
||||
Scene scene;
|
||||
/**
|
||||
* 配置文件数组
|
||||
*/
|
||||
static List<LoadJnotepadConfig<?>> loadJnotepadConfigs = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// 语言配置文件
|
||||
loadJnotepadConfigs.add(new LoadLanguageConfig());
|
||||
// 快捷键配置文件
|
||||
loadJnotepadConfigs.add(new LoadShortcutKeyConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
|
||||
Config config = new Config();
|
||||
Properties properties = config.readPropertiesFromFile();
|
||||
String title = properties.getProperty("title", "JNotepad");
|
||||
|
||||
|
||||
Pane root = new Pane();
|
||||
|
||||
double width = AppConstants.SCREEN_WIDTH;
|
||||
double length = AppConstants.SCREEN_LENGTH;
|
||||
String icon = AppConstants.APP_ICON;
|
||||
|
||||
|
||||
scene = new Scene(root, width, length);
|
||||
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
||||
scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/styles.css")).toExternalForm());
|
||||
@ -62,16 +70,16 @@ public class LunchApp extends Application {
|
||||
Platform.runLater(() -> controller.updateUiWithNewTextArea(textArea));
|
||||
}
|
||||
});
|
||||
primaryStage.setTitle(title);
|
||||
ViewManager viewManager = ViewManager.getInstance(scene);
|
||||
viewManager.initScreen(scene);
|
||||
// 加载配置文件
|
||||
View.getInstance().initJnotepadConfigs(loadJnotepadConfigs);
|
||||
primaryStage.setTitle(localizationConfig.getTitle());
|
||||
primaryStage.setWidth(width);
|
||||
primaryStage.setHeight(length);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource(icon)).toString()));
|
||||
primaryStage.show();
|
||||
ViewManager viewManager = ViewManager.getInstance(scene);
|
||||
viewManager.initScreen(scene);
|
||||
// 初始化快捷键
|
||||
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import org.jcnc.jnotepad.init.Config;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.TEXT_WRAP;
|
||||
|
||||
/**
|
||||
* 内存中,运行过程中的全局配置项
|
||||
@ -14,10 +9,9 @@ import static org.jcnc.jnotepad.constants.TextConstants.TEXT_WRAP;
|
||||
public class GlobalConfig {
|
||||
|
||||
private static final GlobalConfig APP_GLOBAL_CONFIG = new GlobalConfig();
|
||||
private final Properties properties;
|
||||
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
|
||||
private GlobalConfig() {
|
||||
properties = new Config().readPropertiesFromFile();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,12 +20,12 @@ public class GlobalConfig {
|
||||
* @return true, 自动换行;false,不自动换行
|
||||
*/
|
||||
public boolean getAutoLineConfig() {
|
||||
return Boolean.parseBoolean(properties.getProperty(TEXT_WRAP, "true"));
|
||||
return Boolean.parseBoolean(localizationConfig.getTextWrap());
|
||||
}
|
||||
|
||||
public void setAutoLineConfig(boolean isAutoLine) {
|
||||
String autoLineConfig = String.valueOf(isAutoLine);
|
||||
properties.setProperty(TEXT_WRAP, autoLineConfig);
|
||||
localizationConfig.setTextWrap(autoLineConfig);
|
||||
}
|
||||
|
||||
public static GlobalConfig getConfig() {
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import org.jcnc.jnotepad.app.entity.ShortcutKey;
|
||||
import org.jcnc.jnotepad.init.Config;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.jcnc.jnotepad.exception.AppException;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.tool.PopUpUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG;
|
||||
@ -25,80 +19,115 @@ import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG;
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public abstract class LoadJnotepadConfig {
|
||||
public abstract class LoadJnotepadConfig<T> {
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
public final void load() {
|
||||
String path = getConfigPath();
|
||||
if (!Files.exists(Paths.get(path))) {
|
||||
// 不存在则创建
|
||||
createConfig();
|
||||
/**
|
||||
* 返回json配置文件的json节点
|
||||
*
|
||||
* @param inputStream 输入流
|
||||
* @return java.lang.String
|
||||
* @apiNote
|
||||
* @since 2023/8/25 17:17
|
||||
*/
|
||||
protected JsonNode getConfigJson(InputStream inputStream) {
|
||||
StringBuffer jsonData = new StringBuffer();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
|
||||
}
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode jsonNode;
|
||||
try {
|
||||
jsonNode = objectMapper.readTree(jsonData.toString());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new AppException(e.getMessage());
|
||||
}
|
||||
return jsonNode;
|
||||
}
|
||||
|
||||
public final void load() {
|
||||
// 判断是否存在这个配置文件
|
||||
try (InputStream inputStream = new FileInputStream(getConfigPath())) {
|
||||
try (InputStream inputStream = new FileInputStream(CONFIG_NAME)) {
|
||||
logger.info("正在加载配置文件...");
|
||||
// 存在则加载
|
||||
loadConfig(inputStream);
|
||||
} catch (IOException e) {
|
||||
logger.info("未检测到配置文件!");
|
||||
// 不存在则创建
|
||||
createConfig();
|
||||
try {
|
||||
loadConfig(new FileInputStream(CONFIG_NAME));
|
||||
} catch (FileNotFoundException ex) {
|
||||
throw new AppException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createConfig() {
|
||||
List<ShortcutKey> shortcutKeyList = getShortcutKeys();
|
||||
JnotepadConfig.getInstance().setShortcutKeyList(shortcutKeyList);
|
||||
for (ShortcutKey shortcutKey : shortcutKeyList) {
|
||||
// 保证json的key必须和变量名一致
|
||||
MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.getButtonName());
|
||||
String shortKeyValue = shortcutKey.getShortcutKeyValue();
|
||||
if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) {
|
||||
continue;
|
||||
}
|
||||
// 动态添加快捷键
|
||||
menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue));
|
||||
}
|
||||
String jsonConfigPath = getConfigPath();
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(jsonConfigPath))) {
|
||||
/**
|
||||
* 解析配置文件
|
||||
*
|
||||
* @param inputStream 输入流
|
||||
* @return java.util.List<java.util.LinkedHashMap < java.lang.String, java.lang.String>>
|
||||
* @since 2023/8/25 15:18
|
||||
*/
|
||||
protected abstract T parseConfig(InputStream inputStream);
|
||||
|
||||
private void createConfig() {
|
||||
// List<ShortcutKey> shortcutKeyList = getShortcutKeys();
|
||||
// JnotepadConfig.getInstance().setShortcutKeyList(shortcutKeyList);
|
||||
// for (ShortcutKey shortcutKey : shortcutKeyList) {
|
||||
// // 保证json的key必须和变量名一致
|
||||
// MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.getButtonName());
|
||||
// String shortKeyValue = shortcutKey.getShortcutKeyValue();
|
||||
// if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) {
|
||||
// continue;
|
||||
// }
|
||||
// // 动态添加快捷键
|
||||
// menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue));
|
||||
// }
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(CONFIG_NAME))) {
|
||||
writer.write(JNOTEPAD_CONFIG);
|
||||
} catch (IOException e) {
|
||||
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
|
||||
}
|
||||
LocalizationConfig.getLocalizationConfig().initLocalizationConfig();
|
||||
}
|
||||
|
||||
private static String getConfigPath() {
|
||||
return Paths.get(new Config().getAppConfigDir(), CONFIG_NAME).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快捷键集合
|
||||
*
|
||||
* @return java.util.List<org.jcnc.jnotepad.app.entity.ShortcutKey> 快捷键集合
|
||||
* @since 2023/8/24 14:19
|
||||
*/
|
||||
private static List<ShortcutKey> getShortcutKeys() {
|
||||
List<ShortcutKey> shortcutKeyList = new ArrayList<>();
|
||||
// 打开文件
|
||||
ShortcutKey shortcutKeyOfOpen = new ShortcutKey("openItem", "ctrl+o");
|
||||
|
||||
// 新建
|
||||
ShortcutKey shortcutKeyOfNew = new ShortcutKey("newItem", "ctrl+n");
|
||||
|
||||
// 保存
|
||||
ShortcutKey shortcutKeyOfSave = new ShortcutKey("saveItem", "ctrl+s");
|
||||
|
||||
// 保存作为
|
||||
ShortcutKey shortcutKeyOfSaveAs = new ShortcutKey("saveAsItem", "ctrl+shift+s");
|
||||
|
||||
// 打开配置文件
|
||||
ShortcutKey shortcutKeyOfOpenConfig = new ShortcutKey("openConfigItem", "alt+s");
|
||||
|
||||
shortcutKeyList.add(shortcutKeyOfOpen);
|
||||
shortcutKeyList.add(shortcutKeyOfNew);
|
||||
shortcutKeyList.add(shortcutKeyOfSave);
|
||||
shortcutKeyList.add(shortcutKeyOfSaveAs);
|
||||
shortcutKeyList.add(shortcutKeyOfOpenConfig);
|
||||
return shortcutKeyList;
|
||||
}
|
||||
// /**
|
||||
// * 获取快捷键集合
|
||||
// *
|
||||
// * @return java.util.List<org.jcnc.jnotepad.app.entity.ShortcutKey> 快捷键集合
|
||||
// * @since 2023/8/24 14:19
|
||||
// */
|
||||
// private static List<ShortcutKey> getShortcutKeys() {
|
||||
// List<ShortcutKey> shortcutKeyList = new ArrayList<>();
|
||||
// // 打开文件
|
||||
// ShortcutKey shortcutKeyOfOpen = new ShortcutKey("openItem", "ctrl+o");
|
||||
//
|
||||
// // 新建
|
||||
// ShortcutKey shortcutKeyOfNew = new ShortcutKey("newItem", "ctrl+n");
|
||||
//
|
||||
// // 保存
|
||||
// ShortcutKey shortcutKeyOfSave = new ShortcutKey("saveItem", "ctrl+s");
|
||||
//
|
||||
// // 保存作为
|
||||
// ShortcutKey shortcutKeyOfSaveAs = new ShortcutKey("saveAsItem", "ctrl+shift+s");
|
||||
//
|
||||
// // 打开配置文件
|
||||
// ShortcutKey shortcutKeyOfOpenConfig = new ShortcutKey("openConfigItem", "alt+s");
|
||||
//
|
||||
// shortcutKeyList.add(shortcutKeyOfOpen);
|
||||
// shortcutKeyList.add(shortcutKeyOfNew);
|
||||
// shortcutKeyList.add(shortcutKeyOfSave);
|
||||
// shortcutKeyList.add(shortcutKeyOfSaveAs);
|
||||
// shortcutKeyList.add(shortcutKeyOfOpenConfig);
|
||||
// return shortcutKeyList;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 加载配置文件
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.LANGUAGE_FILE_MAP;
|
||||
|
||||
/**
|
||||
* 加载语言配置文件
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class LoadLanguageConfig extends LoadJnotepadConfig<String> {
|
||||
Logger log = LogUtil.getLogger(this.getClass());
|
||||
|
||||
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
|
||||
@Override
|
||||
protected String parseConfig(InputStream inputStream) {
|
||||
return getConfigJson(inputStream).get("language").asText();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadConfig(InputStream inputStream) {
|
||||
log.info("正在加载语言配置文件...");
|
||||
String language = parseConfig(inputStream);
|
||||
if (!"".equals(language) && language != null) {
|
||||
log.info("正在加载语言包:{}", language);
|
||||
localizationConfig.setLanguagePackName(LANGUAGE_FILE_MAP.get(language));
|
||||
// 刷新语言包
|
||||
localizationConfig.initLocalizationConfig();
|
||||
JNotepadMenuBar jNotepadMenuBar = JNotepadMenuBar.getMenuBar();
|
||||
// 刷新菜单栏
|
||||
jNotepadMenuBar.initMenuBar();
|
||||
jNotepadMenuBar.toggleLanguageCheck(language);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,13 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.tool.PopUpUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_SHORTCUT_KEY_NAME;
|
||||
@ -23,46 +17,36 @@ import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_SHORTCUT_KEY_NAME;
|
||||
*
|
||||
* @author gewuyou 一个大转盘
|
||||
*/
|
||||
public class LoadShortcutKeyConfig extends LoadJnotepadConfig {
|
||||
public class LoadShortcutKeyConfig extends LoadJnotepadConfig<List<LinkedHashMap<String, String>>> {
|
||||
Logger log = LogUtil.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void loadConfig(InputStream inputStream) {
|
||||
StringBuffer jsonData = new StringBuffer();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
|
||||
protected List<LinkedHashMap<String, String>> parseConfig(InputStream inputStream) {
|
||||
JsonNode shortcutKeyNode = getConfigJson(inputStream).get(CONFIG_SHORTCUT_KEY_NAME);
|
||||
if (shortcutKeyNode == null || !shortcutKeyNode.isArray()) {
|
||||
logger.error("未获取到主要配置文件!");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 转json对象
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, List<Object>> mainConfig = null;
|
||||
try {
|
||||
mainConfig = mapper.readValue(jsonData.toString(), new TypeReference<HashMap<String, List<Object>>>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
PopUpUtil.errorAlert("错误", "解析错误", "配置文件解析错误!");
|
||||
log.error("配置文件解析错误!", e);
|
||||
}
|
||||
if (mainConfig == null) {
|
||||
log.error("未获取到主要配置文件!");
|
||||
return;
|
||||
}
|
||||
List<LinkedHashMap<String, String>> objectList = mainConfig.get(CONFIG_SHORTCUT_KEY_NAME)
|
||||
.stream()
|
||||
.map(e -> {
|
||||
if (e instanceof LinkedHashMap) {
|
||||
return (LinkedHashMap<String, String>) e;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid element type");
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
List<LinkedHashMap<String, String>> shortcutKeyList = new ArrayList<>();
|
||||
for (JsonNode node : shortcutKeyNode) {
|
||||
if (node.isObject()) {
|
||||
LinkedHashMap<String, String> shortcutKey = new LinkedHashMap<>();
|
||||
Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
|
||||
while (fields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = fields.next();
|
||||
shortcutKey.put(entry.getKey(), entry.getValue().asText());
|
||||
|
||||
for (LinkedHashMap<String, String> shortcutKey : objectList) {
|
||||
}
|
||||
shortcutKeyList.add(shortcutKey);
|
||||
}
|
||||
}
|
||||
return shortcutKeyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadConfig(InputStream inputStream) {
|
||||
List<LinkedHashMap<String, String>> configData = parseConfig(inputStream);
|
||||
for (LinkedHashMap<String, String> shortcutKey : configData) {
|
||||
// 保证json的key必须和变量名一致
|
||||
MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.get("buttonName"));
|
||||
String shortKeyValue = shortcutKey.get("shortcutKeyValue");
|
||||
|
||||
@ -0,0 +1,317 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.APP_NAME;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.*;
|
||||
|
||||
/**
|
||||
* 本地化配置文件
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
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 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;
|
||||
}
|
||||
|
||||
public void setTextWrap(String textWrap) {
|
||||
this.textWrap = textWrap;
|
||||
properties.setProperty(TEXT_WRAP, textWrap);
|
||||
}
|
||||
}
|
||||
@ -18,20 +18,12 @@ public class AppConstants {
|
||||
* 初始高度
|
||||
*/
|
||||
public static final double SCREEN_LENGTH = 600;
|
||||
public static final String APP_NAME = "JNotepad";
|
||||
/**
|
||||
* logo地址
|
||||
*/
|
||||
public static final String APP_ICON = "/img/icon.png";
|
||||
|
||||
/**
|
||||
* 中文语言包
|
||||
*/
|
||||
public static final String CH_LANGUAGE_PACK_NAME = "ch_language_pack.txt";
|
||||
/**
|
||||
* 英文语言包
|
||||
*/
|
||||
public static final String EN_LANGUAGE_PACK_NAME = "en_language_pack.txt";
|
||||
|
||||
/**
|
||||
* 配置文件名
|
||||
*/
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
package org.jcnc.jnotepad.constants;
|
||||
|
||||
import org.jcnc.jnotepad.init.Config;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文本常量
|
||||
@ -14,35 +13,10 @@ import java.util.Properties;
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class TextConstants {
|
||||
|
||||
private TextConstants() {
|
||||
}
|
||||
|
||||
private static final Config CONFIG = new Config();
|
||||
private static final Properties PROPERTIES = CONFIG.readPropertiesFromFile();
|
||||
|
||||
///菜单栏文本常量
|
||||
|
||||
public static final String SAVA = PROPERTIES.getProperty("SAVA");
|
||||
|
||||
public static final String FILE = PROPERTIES.getProperty("FILE");
|
||||
|
||||
public static final String NEW = PROPERTIES.getProperty("NEW");
|
||||
|
||||
public static final String OPEN = PROPERTIES.getProperty("OPEN");
|
||||
|
||||
public static final String SAVA_AS = PROPERTIES.getProperty("SAVA_AS");
|
||||
|
||||
public static final String SET = PROPERTIES.getProperty("SET");
|
||||
|
||||
public static final String WORD_WRAP = PROPERTIES.getProperty("WORD_WRAP");
|
||||
|
||||
public static final String PLUGIN = PROPERTIES.getProperty("PLUGIN");
|
||||
|
||||
public static final String ADD_PLUGIN = PROPERTIES.getProperty("ADD_PLUGIN");
|
||||
|
||||
public static final String STATISTICS = PROPERTIES.getProperty("STATISTICS");
|
||||
|
||||
public static final String OPEN_CONFIGURATION_FILE = PROPERTIES.getProperty("OPEN_CONFIGURATION_FILE");
|
||||
|
||||
/// GlobalConfig文本常量
|
||||
/**
|
||||
@ -50,27 +24,43 @@ public class TextConstants {
|
||||
*/
|
||||
public static final String TEXT_WRAP = "text.wrap";
|
||||
|
||||
/// NewFile 文本常量
|
||||
|
||||
public static final String NEW_FILE = PROPERTIES.getProperty("NEW_FILE");
|
||||
public static final String TITLE = "title";
|
||||
public static final String SAVE = "SAVE";
|
||||
public static final String FILE = "FILE";
|
||||
public static final String NEW = "NEW";
|
||||
public static final String OPEN = "OPEN";
|
||||
public static final String SAVE_AS = "SAVE_AS";
|
||||
public static final String SET = "SET";
|
||||
public static final String WORD_WRAP = "WORD_WRAP";
|
||||
public static final String PLUGIN = "PLUGIN";
|
||||
public static final String ADD_PLUGIN = "ADD_PLUGIN";
|
||||
public static final String STATISTICS = "STATISTICS";
|
||||
public static final String OPEN_CONFIGURATION_FILE = "OPEN_CONFIGURATION_FILE";
|
||||
public static final String TOP = "TOP";
|
||||
public static final String LANGUAGE = "LANGUAGE";
|
||||
public static final String UPPER_CHINESE = "CHINESE";
|
||||
public static final String UPPER_ENGLISH = "ENGLISH";
|
||||
public static final String NEW_FILE = "NEW_FILE";
|
||||
public static final String UNKNOWN = "UNKNOWN";
|
||||
public static final String ROW = "ROW";
|
||||
public static final String COLUMN = "COLUMN";
|
||||
public static final String WORD_COUNT = "WORD_COUNT";
|
||||
public static final String ENCODE = "ENCODE";
|
||||
|
||||
/// Config 文本常量
|
||||
|
||||
public static final String JNOTEPAD_CH_LANGUAGE_PACK_NAME = PROPERTIES.getProperty("JNotepad ch_language_pack");
|
||||
public static final String JNOTEPAD_EN_LANGUAGE_PACK_NAME = PROPERTIES.getProperty("JNotepad en_language_pack");
|
||||
public static final String CH_LANGUAGE_PACK_NAME = "ch_language_pack.txt";
|
||||
public static final String EN_LANGUAGE_PACK_NAME = "en_language_pack.txt";
|
||||
|
||||
/// EncodingDetector 文本常量
|
||||
public static final String UNKNOWN = PROPERTIES.getProperty("UNKNOWN");
|
||||
public static final String ENGLISH = "english";
|
||||
|
||||
/// JNotepadStatusBox
|
||||
public static final String ROW = PROPERTIES.getProperty("ROW");
|
||||
|
||||
public static final String COLUMN = PROPERTIES.getProperty("COLUMN");
|
||||
|
||||
public static final String WORD_COUNT = PROPERTIES.getProperty("WORD_COUNT");
|
||||
|
||||
public static final String ENCODE = PROPERTIES.getProperty("ENCODE");
|
||||
public static final String CHINESE = "chinese";
|
||||
|
||||
/// 语言映射
|
||||
public static final Map<String, String> LANGUAGE_FILE_MAP = Map.of(
|
||||
CHINESE, CH_LANGUAGE_PACK_NAME,
|
||||
ENGLISH, EN_LANGUAGE_PACK_NAME
|
||||
);
|
||||
/// 配置文件文本常量
|
||||
/**
|
||||
* 内置配置文件
|
||||
@ -78,6 +68,7 @@ public class TextConstants {
|
||||
public static final String JNOTEPAD_CONFIG =
|
||||
"""
|
||||
{
|
||||
"language":"chinese",
|
||||
"shortcutKey":[
|
||||
{
|
||||
"buttonName": "newItem",
|
||||
|
||||
@ -2,14 +2,13 @@ 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.ui.LineNumberTextArea;
|
||||
import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.NEW_FILE;
|
||||
|
||||
|
||||
/**
|
||||
* 新建文件事件的事件处理程序。
|
||||
@ -35,7 +34,7 @@ public class NewFile implements EventHandler<ActionEvent> {
|
||||
// TODO: refactor:统一TextArea新建、绑定监听器入口
|
||||
ViewManager viewManager = ViewManager.getInstance();
|
||||
// 将Tab页添加到TabPane中
|
||||
JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(NEW_FILE
|
||||
JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(LocalizationConfig.getLocalizationConfig().getNewFile()
|
||||
+ viewManager.selfIncreaseAndGetTabIndex(),
|
||||
textArea));
|
||||
|
||||
|
||||
@ -22,11 +22,11 @@ public class OpenConfig extends OpenHandler {
|
||||
// 显示文件选择对话框,并获取选中的文件
|
||||
File file = new File(CONFIG_NAME);
|
||||
LogUtil.getLogger(this.getClass()).info("已调用打开配置文件功能");
|
||||
LogUtil.getLogger(this.getClass()).info("{}", file);
|
||||
// 创建打开文件的任务
|
||||
Task<Void> openFileTask = getVoidTask(controller, file);
|
||||
// 创建并启动线程执行任务
|
||||
Thread thread = new Thread(openFileTask);
|
||||
thread.start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package org.jcnc.jnotepad.controller.event.handler;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import org.jcnc.jnotepad.app.config.LoadLanguageConfig;
|
||||
import org.jcnc.jnotepad.app.config.LoadShortcutKeyConfig;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
@ -46,8 +47,12 @@ public class SaveFile implements EventHandler<ActionEvent> {
|
||||
selectedTab.save();
|
||||
// 如果该文件是配置文件则刷新快捷键
|
||||
if (CONFIG_NAME.equals(selectedTab.getText())) {
|
||||
|
||||
// 刷新语言包
|
||||
View.getInstance().initJnotepadConfig(new LoadLanguageConfig());
|
||||
logger.info("已刷新语言包!");
|
||||
// 初始化快捷键
|
||||
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
|
||||
View.getInstance().initJnotepadConfig(new LoadShortcutKeyConfig());
|
||||
logger.info("已刷新快捷键!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.jcnc.jnotepad.controller.manager;
|
||||
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.tool.EncodingDetector;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||
@ -17,8 +18,6 @@ import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.NEW_FILE;
|
||||
|
||||
/**
|
||||
* 控制器类,实现ControllerInterface接口,用于管理文本编辑器的各种操作和事件处理。
|
||||
* 包括打开关联文件、创建文本区域、处理行分隔、新建文件、打开文件、自动保存等功能。
|
||||
@ -89,7 +88,7 @@ public class Controller implements ControllerInterface {
|
||||
textBuilder.append(line).append("\n");
|
||||
}
|
||||
String text = textBuilder.toString();
|
||||
|
||||
LogUtil.getLogger(this.getClass()).info("已调用读取文件功能");
|
||||
Platform.runLater(() -> {
|
||||
textArea.getMainTextArea().setText(text);
|
||||
JNotepadTab tab = createNewTab(file.getName(), textArea, encoding);
|
||||
@ -112,7 +111,7 @@ public class Controller implements ControllerInterface {
|
||||
@Override
|
||||
public void updateUiWithNewTextArea(LineNumberTextArea textArea) {
|
||||
ViewManager viewManager = ViewManager.getInstance();
|
||||
String tabTitle = NEW_FILE + viewManager.selfIncreaseAndGetTabIndex();
|
||||
String tabTitle = LocalizationConfig.getLocalizationConfig().getNewFile() + viewManager.selfIncreaseAndGetTabIndex();
|
||||
JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(tabTitle, textArea));
|
||||
}
|
||||
|
||||
|
||||
@ -1,141 +0,0 @@
|
||||
package org.jcnc.jnotepad.init;
|
||||
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CH_LANGUAGE_PACK_NAME;
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.EN_LANGUAGE_PACK_NAME;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CH_LANGUAGE_PACK_NAME;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_EN_LANGUAGE_PACK_NAME;
|
||||
|
||||
/**
|
||||
* @author 许轲
|
||||
* 该类负责配置文件的读取和初始化操作。
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
private String languagePackName;
|
||||
|
||||
private String appConfigDir;
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
public Config() {
|
||||
appConfigDir = System.getProperty("user.home") + File.separator + ".jnotepad";
|
||||
Path path = Paths.get(appConfigDir);
|
||||
boolean isConfigDirReady = path.toFile().mkdirs();
|
||||
if (!isConfigDirReady && !Files.exists(path)) {
|
||||
appConfigDir = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件中读取属性配置。
|
||||
*
|
||||
* @return 包含从文件中读取的属性的 Properties 对象。
|
||||
*/
|
||||
public Properties readPropertiesFromFile() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
//设置语言包
|
||||
languagePackName = EN_LANGUAGE_PACK_NAME;
|
||||
String languageFilePath = Paths.get(appConfigDir, languagePackName).toString();
|
||||
|
||||
if (!Files.exists(Paths.get(languageFilePath))) {
|
||||
// 如果读取出错,则调用初始化方法
|
||||
initializePropertiesFile();
|
||||
}
|
||||
|
||||
try (InputStream inputStream = new FileInputStream(languageFilePath)) {
|
||||
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
|
||||
properties.load(reader);
|
||||
} catch (IOException ignored) {
|
||||
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化属性配置文件。
|
||||
* 如果属性文件不存在,将创建一个新的属性文件并设置默认属性。
|
||||
*/
|
||||
public void initializePropertiesFile() {
|
||||
Properties chLanguagePack = getChineseLanguagePack();
|
||||
|
||||
Properties enLanguagePack = getEnglishLanguagePack();
|
||||
|
||||
String chineseFilePath = Paths.get(appConfigDir, CH_LANGUAGE_PACK_NAME).toString();
|
||||
try (OutputStream outputStream = new FileOutputStream(chineseFilePath)) {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
|
||||
chLanguagePack.store(writer, JNOTEPAD_CH_LANGUAGE_PACK_NAME);
|
||||
|
||||
} catch (IOException ignored) {
|
||||
logger.info("未检测到中文语言包!");
|
||||
}
|
||||
|
||||
String enFilePath = Paths.get(appConfigDir, EN_LANGUAGE_PACK_NAME).toString();
|
||||
try (OutputStream outputStream = new FileOutputStream(enFilePath)) {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
|
||||
enLanguagePack.store(writer, JNOTEPAD_EN_LANGUAGE_PACK_NAME);
|
||||
|
||||
} catch (IOException ignored) {
|
||||
logger.info("未检测到英文语言包!");
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties getChineseLanguagePack() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.setProperty("TITLE", "JNotepad"); // 设置默认属性
|
||||
properties.setProperty("NEW_FILE", "新建文件");
|
||||
properties.setProperty("SAVA", "保存");
|
||||
properties.setProperty("FILE", "文件");
|
||||
properties.setProperty("NEW", "新建");
|
||||
properties.setProperty("OPEN", "打开");
|
||||
properties.setProperty("SAVA_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", "编码");
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static Properties getEnglishLanguagePack() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.setProperty("TITLE", "JNotepad");
|
||||
properties.setProperty("NEW_FILE", "New File");
|
||||
properties.setProperty("SAVA", "Save");
|
||||
properties.setProperty("FILE", "File");
|
||||
properties.setProperty("NEW", "New");
|
||||
properties.setProperty("OPEN", "Open");
|
||||
properties.setProperty("SAVA_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");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public String getAppConfigDir() {
|
||||
return appConfigDir;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package org.jcnc.jnotepad.tool;
|
||||
|
||||
import com.ibm.icu.text.CharsetDetector;
|
||||
import com.ibm.icu.text.CharsetMatch;
|
||||
import org.jcnc.jnotepad.app.config.LocalizationConfig;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -17,13 +18,14 @@ import java.nio.charset.Charset;
|
||||
* @author 许轲
|
||||
*/
|
||||
public class EncodingDetector {
|
||||
|
||||
static LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
private static final Logger LOG = LogUtil.getLogger(EncodingDetector.class);
|
||||
/**
|
||||
* 编码侦测概率,阈值:50%
|
||||
*/
|
||||
public static final int THRESHOLD_CONFIDENCE = 50;
|
||||
|
||||
|
||||
private EncodingDetector() {
|
||||
}
|
||||
|
||||
@ -39,11 +41,11 @@ public class EncodingDetector {
|
||||
charsetDetector.setText(inputStream);
|
||||
CharsetMatch[] matchList = charsetDetector.detectAll();
|
||||
if (matchList == null || matchList.length == 0) {
|
||||
return null;
|
||||
return localizationConfig.getUnknown();
|
||||
}
|
||||
CharsetMatch maxConfidence = matchList[0];
|
||||
if (maxConfidence.getConfidence() < THRESHOLD_CONFIDENCE) {
|
||||
return null;
|
||||
return localizationConfig.getUnknown();
|
||||
}
|
||||
for (int i = 1; i < matchList.length; i++) {
|
||||
CharsetMatch match = matchList[i];
|
||||
@ -57,7 +59,7 @@ public class EncodingDetector {
|
||||
} catch (Exception e) {
|
||||
LOG.error("", e);
|
||||
}
|
||||
return null;
|
||||
return localizationConfig.getUnknown();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +71,6 @@ public class EncodingDetector {
|
||||
public static Charset detectEncodingCharset(File file) {
|
||||
String charset = detectEncoding(file);
|
||||
try {
|
||||
assert charset != null;
|
||||
return Charset.forName(charset);
|
||||
} catch (Exception e) {
|
||||
return Charset.defaultCharset();
|
||||
|
||||
@ -40,6 +40,7 @@ public class FileUtil {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存页面方法
|
||||
*
|
||||
|
||||
@ -1,18 +1,22 @@
|
||||
package org.jcnc.jnotepad.ui.menu;
|
||||
|
||||
import javafx.scene.control.CheckMenuItem;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.Stage;
|
||||
import org.jcnc.jnotepad.app.config.GlobalConfig;
|
||||
import org.jcnc.jnotepad.app.config.LocalizationConfig;
|
||||
import org.jcnc.jnotepad.controller.event.handler.*;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.*;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.CHINESE;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.ENGLISH;
|
||||
|
||||
/**
|
||||
* 封装菜单栏组件。
|
||||
@ -27,10 +31,15 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
*/
|
||||
JNotepadTabPane jNotepadTabPane = JNotepadTabPane.getInstance();
|
||||
|
||||
JNotepadStatusBox jNotepadStatusBox = JNotepadStatusBox.getInstance();
|
||||
|
||||
private static final JNotepadMenuBar MENU_BAR = new JNotepadMenuBar();
|
||||
|
||||
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
private JNotepadMenuBar() {
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +47,7 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
*/
|
||||
private Menu fileMenu;
|
||||
/**
|
||||
* 插件菜单
|
||||
* 设置菜单
|
||||
*/
|
||||
private Menu setMenu;
|
||||
/**
|
||||
@ -46,6 +55,11 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
*/
|
||||
private Menu pluginMenu;
|
||||
|
||||
/**
|
||||
* 语言菜单
|
||||
*/
|
||||
private Menu languageMenu;
|
||||
|
||||
/// 菜单按钮
|
||||
|
||||
/**
|
||||
@ -80,39 +94,90 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
* 自动换行点击菜单按钮
|
||||
*/
|
||||
private CheckMenuItem lineFeedItem;
|
||||
/**
|
||||
* 置顶按钮
|
||||
*/
|
||||
private CheckMenuItem topItem;
|
||||
|
||||
|
||||
/**
|
||||
* 中文选项
|
||||
*/
|
||||
private RadioMenuItem chineseItem;
|
||||
/**
|
||||
* 英文选项
|
||||
*/
|
||||
private RadioMenuItem englishItem;
|
||||
private final Map<String, MenuItem> itemMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 设置当前语言选中状态
|
||||
*
|
||||
* @param language 语言
|
||||
* @since 2023/8/25 22:49
|
||||
*/
|
||||
public void toggleLanguageCheck(String language) {
|
||||
switch (language) {
|
||||
case CHINESE -> chineseItem.setSelected(true);
|
||||
case ENGLISH -> englishItem.setSelected(true);
|
||||
default -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化菜单栏
|
||||
*/
|
||||
private void init() {
|
||||
public void initMenuBar() {
|
||||
initFileMenu();
|
||||
initLanguageMenu();
|
||||
initSettingMenu();
|
||||
initPluginMenu();
|
||||
this.getMenus().clear();
|
||||
// 菜单栏
|
||||
this.getMenus().addAll(fileMenu, setMenu, pluginMenu);
|
||||
initEventHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化语言菜单
|
||||
*/
|
||||
private void initLanguageMenu() {
|
||||
logger.info("初始化语言菜单:{}", localizationConfig.getLanguage());
|
||||
// 语言菜单
|
||||
languageMenu = new Menu(localizationConfig.getLanguage());
|
||||
ToggleGroup languageToggleGroup = new ToggleGroup();
|
||||
|
||||
chineseItem = new RadioMenuItem(localizationConfig.getChinese());
|
||||
itemMap.put("chineseItem", chineseItem);
|
||||
languageToggleGroup.getToggles().add(chineseItem);
|
||||
|
||||
englishItem = new RadioMenuItem(localizationConfig.getEnglish());
|
||||
itemMap.put("englishItem", englishItem);
|
||||
languageToggleGroup.getToggles().add(englishItem);
|
||||
|
||||
languageMenu.getItems().addAll(chineseItem, englishItem);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化文件菜单
|
||||
*/
|
||||
private void initFileMenu() {
|
||||
logger.info("初始化文件菜单:{}", localizationConfig.getFile());
|
||||
// 文件菜单
|
||||
fileMenu = new Menu(FILE);
|
||||
fileMenu = new Menu(localizationConfig.getFile());
|
||||
|
||||
newItem = new MenuItem(NEW);
|
||||
newItem = new MenuItem(localizationConfig.getNewly());
|
||||
itemMap.put("newItem", newItem);
|
||||
|
||||
openItem = new MenuItem(OPEN);
|
||||
openItem = new MenuItem(localizationConfig.getOpen());
|
||||
itemMap.put("openItem", openItem);
|
||||
|
||||
saveItem = new MenuItem(SAVA);
|
||||
saveItem = new MenuItem(localizationConfig.getSava());
|
||||
itemMap.put("saveItem", saveItem);
|
||||
|
||||
saveAsItem = new MenuItem(SAVA_AS);
|
||||
saveAsItem = new MenuItem(localizationConfig.getSavaAs());
|
||||
itemMap.put("saveAsItem", saveAsItem);
|
||||
|
||||
fileMenu.getItems().addAll(newItem, openItem, saveItem, saveAsItem);
|
||||
@ -122,27 +187,35 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
* 初始化设置菜单
|
||||
*/
|
||||
private void initSettingMenu() {
|
||||
logger.info("初始化设置菜单:{}", localizationConfig.getSet());
|
||||
// 设置菜单
|
||||
setMenu = new Menu(SET);
|
||||
setMenu = new Menu(localizationConfig.getSet());
|
||||
|
||||
lineFeedItem = new CheckMenuItem(WORD_WRAP);
|
||||
lineFeedItem = new CheckMenuItem(localizationConfig.getWordWrap());
|
||||
itemMap.put("lineFeedItem", lineFeedItem);
|
||||
lineFeedItem.selectedProperty().set(true);
|
||||
openConfigItem = new MenuItem(OPEN_CONFIGURATION_FILE);
|
||||
|
||||
topItem = new CheckMenuItem(localizationConfig.getTop());
|
||||
itemMap.put("topItem", topItem);
|
||||
|
||||
openConfigItem = new MenuItem(localizationConfig.getOpenConfigurationFile());
|
||||
itemMap.put("openConfigItem", openConfigItem);
|
||||
setMenu.getItems().addAll(lineFeedItem, openConfigItem);
|
||||
|
||||
itemMap.put("languageMenu", languageMenu);
|
||||
setMenu.getItems().addAll(lineFeedItem, openConfigItem, topItem, languageMenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件菜单
|
||||
*/
|
||||
private void initPluginMenu() {
|
||||
logger.info("初始化插件菜单:{}", localizationConfig.getPlugin());
|
||||
// 插件菜单
|
||||
pluginMenu = new Menu(PLUGIN);
|
||||
addItem = new MenuItem(ADD_PLUGIN);
|
||||
pluginMenu = new Menu(localizationConfig.getPlugin());
|
||||
addItem = new MenuItem(localizationConfig.getAddPlugin());
|
||||
itemMap.put("addItem", addItem);
|
||||
|
||||
countItem = new MenuItem(STATISTICS);
|
||||
countItem = new MenuItem(localizationConfig.getStatistics());
|
||||
itemMap.put("countItem", countItem);
|
||||
|
||||
pluginMenu.getItems().addAll(addItem, countItem);
|
||||
@ -167,6 +240,25 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
// 2. 对当前tab生效配置
|
||||
jNotepadTabPane.fireTabSelected();
|
||||
});
|
||||
topItem.selectedProperty().addListener((observableValue, before, after) -> {
|
||||
// 获取窗口容器
|
||||
Stage primaryStage = (Stage) this.getScene().getWindow();
|
||||
// 设置窗口为置顶
|
||||
primaryStage.setAlwaysOnTop(after);
|
||||
});
|
||||
// todo 切换语言并将语言修改设置回本地
|
||||
englishItem.setOnAction(new OpenHandler() {
|
||||
@Override
|
||||
public void handle(ActionEvent actionEvent) {
|
||||
|
||||
}
|
||||
});
|
||||
chineseItem.setOnAction(new OpenHandler() {
|
||||
@Override
|
||||
public void handle(ActionEvent actionEvent) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<String, MenuItem> getItemMap() {
|
||||
|
||||
@ -4,13 +4,12 @@ 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.ui.tab.JNotepadTab;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.*;
|
||||
|
||||
/**
|
||||
* 状态栏组件封装。
|
||||
* 1. 文字统计
|
||||
@ -21,27 +20,31 @@ import static org.jcnc.jnotepad.constants.TextConstants.*;
|
||||
public class JNotepadStatusBox extends HBox {
|
||||
|
||||
private static final JNotepadStatusBox STATUS_BOX = new JNotepadStatusBox();
|
||||
|
||||
LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig();
|
||||
/**
|
||||
* 字数统计及光标
|
||||
*/
|
||||
private final Label statusLabel;
|
||||
private Label statusLabel;
|
||||
|
||||
/**
|
||||
* 显示文本编码
|
||||
*/
|
||||
private final Label enCodingLabel;
|
||||
private Label enCodingLabel;
|
||||
|
||||
private JNotepadStatusBox() {
|
||||
initStatusBox();
|
||||
}
|
||||
|
||||
public void initStatusBox() {
|
||||
this.getChildren().clear();
|
||||
// 创建状态栏
|
||||
statusLabel = new Label(ROW + ":1 \t" + COLUMN + ":1 \t" + WORD_COUNT + ":0 ");
|
||||
statusLabel = new Label(localizationConfig.getRow() + ":1 \t" + localizationConfig.getColumn() + ":1 \t" + localizationConfig.getWordCount() + ":0 ");
|
||||
// 创建新的标签以显示编码信息
|
||||
enCodingLabel = new Label();
|
||||
|
||||
updateEncodingLabel();
|
||||
this.getChildren().add(statusLabel);
|
||||
this.getChildren().add(enCodingLabel);
|
||||
this.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10));
|
||||
|
||||
}
|
||||
|
||||
public static JNotepadStatusBox getInstance() {
|
||||
@ -61,7 +64,7 @@ public class JNotepadStatusBox extends HBox {
|
||||
if (encoding == null) {
|
||||
encoding = Charset.defaultCharset().name();
|
||||
}
|
||||
this.enCodingLabel.setText("\t" + ENCODE + ": " + encoding);
|
||||
this.enCodingLabel.setText("\t" + localizationConfig.getEncode() + ": " + encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +80,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(ROW + ": " + row + " \t" + COLUMN + ": " + column + " \t" + WORD_COUNT + ": " + length);
|
||||
this.statusLabel.setText(localizationConfig.getRow() + ": " + row + " \t" + localizationConfig.getColumn() + ": " + column + " \t" + localizationConfig.getWordCount() + ": " + length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2,6 +2,8 @@ package org.jcnc.jnotepad.view.init;
|
||||
|
||||
import org.jcnc.jnotepad.app.config.LoadJnotepadConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author 许轲
|
||||
@ -14,14 +16,27 @@ public class View {
|
||||
private static final View INSTANCE = new View();
|
||||
|
||||
/**
|
||||
* 初始化快捷键
|
||||
* 初始化配置文件
|
||||
*
|
||||
* @param loadJnotepadConfig 加载配置文件
|
||||
* @param loadJnotepadConfigs 需要加载的配置文件数组
|
||||
* @since 2023/8/24 15:29
|
||||
*/
|
||||
public void initShortcutKey(LoadJnotepadConfig loadJnotepadConfig) {
|
||||
public void initJnotepadConfigs(List<LoadJnotepadConfig<?>> loadJnotepadConfigs) {
|
||||
for (LoadJnotepadConfig<?> loadJnotepadConfig : loadJnotepadConfigs) {
|
||||
initJnotepadConfig(loadJnotepadConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置文件
|
||||
*
|
||||
* @param loadJnotepadConfig 配置文件
|
||||
* @since 2023/8/24 15:29
|
||||
*/
|
||||
public void initJnotepadConfig(LoadJnotepadConfig<?> loadJnotepadConfig) {
|
||||
loadJnotepadConfig.load();
|
||||
}
|
||||
|
||||
public static View getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user