diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 29ee8d9bf97e1f9c88d8fcecb02db430911f3e66..13e0e4fed413fab5788687adf633aa5dfea9a2f0 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -18,13 +18,9 @@ module org.jcnc.jnotepad { exports org.jcnc.jnotepad.Interface; exports org.jcnc.jnotepad.controller.event.handler; exports org.jcnc.jnotepad.controller.manager; - exports org.jcnc.jnotepad.view.init; exports org.jcnc.jnotepad.view.manager; exports org.jcnc.jnotepad.constants; exports org.jcnc.jnotepad.ui; - exports org.jcnc.jnotepad.app.init; - // 导出 JSON 相关的包,以便 Jackson 库可以访问 - exports org.jcnc.jnotepad.json; - // 打开 JSON 相关的包,以便 Jackson 库可以使用反射 - opens org.jcnc.jnotepad.json; + exports org.jcnc.jnotepad.controller.i18n; + opens org.jcnc.jnotepad.app.config; } \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java b/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java index 66c4175f5eb73327f926f7db71000fc08e08393f..c0f68f7ea342844400260fb7741f7ab9e636101a 100644 --- a/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java +++ b/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java @@ -7,6 +7,7 @@ import java.util.List; /** * 控制器接口类 + * * @author 许轲 */ public interface ControllerInterface { @@ -17,7 +18,7 @@ public interface ControllerInterface { * @param rawParameters 原始参数列表 * @return 创建的 TextArea */ - LineNumberTextArea openAssociatedFileAndCreateTextArea(List rawParameters); + void openAssociatedFileAndCreateTextArea(List rawParameters); /** * 打开关联文件 @@ -26,20 +27,4 @@ public interface ControllerInterface { */ void openAssociatedFile(String filePath); - /** - * 获取文件内容 - * - * @param file 文件 - */ - void getText(File file); - - /** - * 更新UI和标签页 - * - * @param textArea 文本域 - * @apiNote - * @since 2023/8/20 12:40 - */ - - void updateUiWithNewTextArea(LineNumberTextArea textArea); } diff --git a/src/main/java/org/jcnc/jnotepad/LunchApp.java b/src/main/java/org/jcnc/jnotepad/LunchApp.java index 03759ddeb9d779da9cf1d9fa5ee015b2181b2fbb..24b90d53c640ba9cc439643d3f0af87898b9729a 100644 --- a/src/main/java/org/jcnc/jnotepad/LunchApp.java +++ b/src/main/java/org/jcnc/jnotepad/LunchApp.java @@ -3,24 +3,18 @@ package org.jcnc.jnotepad; import atlantafx.base.theme.PrimerLight; import javafx.application.Application; -import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.layout.Pane; import javafx.stage.Stage; 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.i18n.LocalizationController; import org.jcnc.jnotepad.controller.manager.Controller; import org.jcnc.jnotepad.manager.ThreadPoolManager; -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.concurrent.ExecutorService; @@ -38,26 +32,6 @@ public class LunchApp extends Application { private final ExecutorService threadPool = ThreadPoolManager.getThreadPool(); Controller controller = Controller.getInstance(); Scene scene; - /** - * 配置文件数组 - */ - private static final List> LOAD_JNOTEPAD_CONFIGS = new ArrayList<>(); - - static { - // 语言配置文件 - LOAD_JNOTEPAD_CONFIGS.add(new LoadLanguageConfig()); - // 快捷键配置文件 - LOAD_JNOTEPAD_CONFIGS.add(new LoadShortcutKeyConfig()); - } - - /** - * 获取配置文件数组 - * - * @since 2023/8/26 16:05 - */ - public static List> getLocalizationConfigs() { - return LOAD_JNOTEPAD_CONFIGS; - } @Override public void start(Stage primaryStage) { @@ -68,19 +42,9 @@ public class LunchApp extends Application { scene = new Scene(root, width, length); Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet()); scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/styles.css")).toExternalForm()); + initUIComponents(); + - // 使用线程池加载关联文件并创建文本区域 - List rawParameters = getParameters().getRaw(); - threadPool.execute(() -> { - LineNumberTextArea textArea = controller.openAssociatedFileAndCreateTextArea(rawParameters); - if (!Objects.isNull(textArea)) { - Platform.runLater(() -> controller.updateUiWithNewTextArea(textArea)); - } - }); - ViewManager viewManager = ViewManager.getInstance(scene); - viewManager.initScreen(scene); - // 加载配置文件 - View.getInstance().initJnotepadConfigs(LOAD_JNOTEPAD_CONFIGS); UIResourceBundle.bindStringProperty(primaryStage.titleProperty(), TextConstants.TITLE); primaryStage.setWidth(width); primaryStage.setHeight(length); @@ -89,6 +53,20 @@ public class LunchApp extends Application { primaryStage.show(); } + private void initUIComponents() { + + //1. 加载语言 + LocalizationController.initLocal(); + + //2. 加载组件 + ViewManager viewManager = ViewManager.getInstance(scene); + viewManager.initScreen(scene); + + // 使用线程池加载关联文件并创建文本区域 + List rawParameters = getParameters().getRaw(); + controller.openAssociatedFileAndCreateTextArea(rawParameters); + } + @Override public void stop() { // 关闭线程池 diff --git a/src/main/java/org/jcnc/jnotepad/json/DataGenerator.java b/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java similarity index 41% rename from src/main/java/org/jcnc/jnotepad/json/DataGenerator.java rename to src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java index add2a267d67adb2876092a5ccbb88e7c9aef4cca..677f3b70e0e3b66e6b467896bd964e52bc19610b 100644 --- a/src/main/java/org/jcnc/jnotepad/json/DataGenerator.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java @@ -1,18 +1,62 @@ -package org.jcnc.jnotepad.json; +package org.jcnc.jnotepad.app.config; + +import com.fasterxml.jackson.annotation.JsonIgnore; import java.util.ArrayList; import java.util.List; /** - * 数据生成类,用于生成示例数据。 + * 数据模型类,用于表示 MyData 对象的数据结构。 + * * @author 许轲 */ -public class DataGenerator { +public class AppConfig { + private String language; + + @JsonIgnore + private boolean textWrap; + + private List shortcutKey; + + /** + * ShortcutKey 类,用于表示快捷键信息。 + */ + public static class ShortcutKey { + private String buttonName; + private String shortcutKeyValue; + public String getButtonName() { + return buttonName; + } - private DataGenerator() { + public void setButtonName(String buttonName) { + this.buttonName = buttonName; + } + + public String getShortcutKeyValue() { + return shortcutKeyValue; + } + + public void setShortcutKeyValue(String shortcutKeyValue) { + this.shortcutKeyValue = shortcutKeyValue; + } + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public List getShortcutKey() { + return shortcutKey; + } + + public void setShortcutKey(List shortcutKey) { + this.shortcutKey = shortcutKey; } - /// 快捷键常量 private static final String CTRL_N = "ctrl+n"; private static final String CTRL_O = "ctrl+o"; @@ -21,15 +65,16 @@ public class DataGenerator { private static final String ALT_S = "alt+s"; /** - * 生成示例 MyData 对象。 + * 生成默认应用配置对象。 * - * @return 示例 MyData 对象 + * @return 默认应用配置对象 */ - public static MyData generateMyData() { - MyData myData = new MyData(); + public static AppConfig generateDefaultAppConfig() { + AppConfig myData = new AppConfig(); myData.setLanguage("chinese"); + myData.setTextWrap(false); - List shortcutKeys = new ArrayList<>(); + List shortcutKeys = new ArrayList<>(); shortcutKeys.add(createShortcutKey("newItem", CTRL_N)); shortcutKeys.add(createShortcutKey("openItem", CTRL_O)); shortcutKeys.add(createShortcutKey("saveItem", CTRL_S)); @@ -50,10 +95,18 @@ public class DataGenerator { * @param shortcutKeyValue 快捷键值 * @return ShortcutKey 对象 */ - private static MyData.ShortcutKey createShortcutKey(String buttonName, String shortcutKeyValue) { - MyData.ShortcutKey shortcutKey = new MyData.ShortcutKey(); + private static AppConfig.ShortcutKey createShortcutKey(String buttonName, String shortcutKeyValue) { + AppConfig.ShortcutKey shortcutKey = new AppConfig.ShortcutKey(); shortcutKey.setButtonName(buttonName); shortcutKey.setShortcutKeyValue(shortcutKeyValue); return shortcutKey; } + + public boolean isTextWrap() { + return textWrap; + } + + public void setTextWrap(boolean textWrap) { + this.textWrap = textWrap; + } } diff --git a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java deleted file mode 100644 index bd4c16c482955d49210ec66749b6f224aadf1af6..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.jcnc.jnotepad.app.config; - - -/** - * 内存中,运行过程中的全局配置项 - * - * @author zhaoteng.song - */ -public class GlobalConfig { - - private static final GlobalConfig APP_GLOBAL_CONFIG = new GlobalConfig(); - LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig(); - - private GlobalConfig() { - } - - /** - * 获取自动换行设置,默认自动换行 - * - * @return true, 自动换行;false,不自动换行 - */ - public boolean getAutoLineConfig() { - return Boolean.parseBoolean(localizationConfig.getTextWrap()); - } - - public void setAutoLineConfig(boolean isAutoLine) { - String autoLineConfig = String.valueOf(isAutoLine); - localizationConfig.setTextWrap(autoLineConfig); - } - - public static GlobalConfig getConfig() { - return APP_GLOBAL_CONFIG; - } - -} diff --git a/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java b/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java index 6be7af69098ac4223c55e2b5a13ef13c153d42f7..a0ec1737dd3090bea1b18979a47df93dff8585ec 100644 --- a/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java +++ b/src/main/java/org/jcnc/jnotepad/app/i18n/UIResourceBundle.java @@ -6,7 +6,6 @@ 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; @@ -34,7 +33,7 @@ public class UIResourceBundle { } private UIResourceBundle() { - this.resetLocal(); + } /** @@ -62,11 +61,11 @@ public class UIResourceBundle { /** * 重置当前local */ - public final void resetLocal() { - if (this.currentLocale == LocalizationConfig.getCurrentLocal()) { + public final void resetLocal(Locale toLocal) { + if (this.currentLocale == toLocal) { return; } - this.currentLocale = LocalizationConfig.getCurrentLocal(); + this.currentLocale = toLocal; ResourceBundle resourceBundle = ResourceBundle.getBundle(BASENAME, currentLocale); this.setResources(resourceBundle); diff --git a/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java b/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java deleted file mode 100644 index 52f3a94615b13e980b161b1f8f0958c84fbcf4f5..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/app/init/LoadJnotepadConfig.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.jcnc.jnotepad.app.init; - -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.slf4j.Logger; - -import java.io.*; - -import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME; -import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG; - -/** - * 加载应用配置类 - *
空出了加载文件的具体实现 - * - * @author gewuyou - */ -public abstract class LoadJnotepadConfig { - Logger logger = LogUtil.getLogger(this.getClass()); - - /** - * 返回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(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()); - } - } - } - - /** - * 解析配置文件 - * - * @param inputStream 输入流 - * @return T - * @since 2023/8/25 15:18 - */ - protected abstract T parseConfig(InputStream inputStream); - - private void createConfig() { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(CONFIG_NAME))) { - writer.write(JNOTEPAD_CONFIG); - } catch (IOException e) { - PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!"); - } - } - - - /** - * 加载配置文件 - * - * @param inputStream 配置文件的输入流 - */ - protected abstract void loadConfig(InputStream inputStream); -} diff --git a/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java b/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java deleted file mode 100644 index daab4bc44894fefc066fba0130d01850b3be071a..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/app/init/LoadLanguageConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.jcnc.jnotepad.app.init; - -import org.jcnc.jnotepad.app.config.LocalizationConfig; -import org.jcnc.jnotepad.tool.LogUtil; -import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar; -import org.jcnc.jnotepad.ui.status.JNotepadStatusBox; -import org.slf4j.Logger; - -import java.io.InputStream; - -/** - * 加载语言配置文件 - * - * @author gewuyou - */ -public class LoadLanguageConfig extends LoadJnotepadConfig { - Logger log = LogUtil.getLogger(this.getClass()); - - @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.setCurrentLocal(language); - JNotepadMenuBar jNotepadMenuBar = JNotepadMenuBar.getMenuBar(); - // 刷新菜单栏 - jNotepadMenuBar.toggleLanguageCheck(language); - JNotepadStatusBox.getInstance().initStatusBox(); - } - } -} diff --git a/src/main/java/org/jcnc/jnotepad/app/init/LoadShortcutKeyConfig.java b/src/main/java/org/jcnc/jnotepad/app/init/LoadShortcutKeyConfig.java deleted file mode 100644 index ffa8a96b75a8f48bc680eb8ce904e094cb51c280..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/app/init/LoadShortcutKeyConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.jcnc.jnotepad.app.init; - -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.ui.menu.JNotepadMenuBar; -import org.slf4j.Logger; - -import java.io.InputStream; -import java.util.*; - -import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_SHORTCUT_KEY_NAME; - -/** - * 加载快捷键实现 - * - * @author gewuyou 一个大转盘 - */ -public class LoadShortcutKeyConfig extends LoadJnotepadConfig>> { - Logger log = LogUtil.getLogger(this.getClass()); - - @Override - protected List> parseConfig(InputStream inputStream) { - JsonNode shortcutKeyNode = getConfigJson(inputStream).get(CONFIG_SHORTCUT_KEY_NAME); - if (shortcutKeyNode == null || !shortcutKeyNode.isArray()) { - logger.error("未获取到主要配置文件!"); - return Collections.emptyList(); - } - List> shortcutKeyList = new ArrayList<>(); - for (JsonNode node : shortcutKeyNode) { - if (node.isObject()) { - LinkedHashMap shortcutKey = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); - shortcutKey.put(entry.getKey(), entry.getValue().asText()); - - } - shortcutKeyList.add(shortcutKey); - } - } - return shortcutKeyList; - } - - @Override - protected void loadConfig(InputStream inputStream) { - List> configData = parseConfig(inputStream); - for (LinkedHashMap shortcutKey : configData) { - // 保证json的key必须和变量名一致 - MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.get("buttonName")); - String shortKeyValue = shortcutKey.get("shortcutKeyValue"); - if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) { - continue; - } - log.info("功能名称:{}->快捷键:{}", menuItem.getText(), shortKeyValue); - // 动态添加快捷键 - menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue)); - } - } -} diff --git a/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java b/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java index b2d91d758ad406de0c5620db98b857d07b35db80..7ef55e666a87d348e98ef31dd824436ad6188fa0 100644 --- a/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java +++ b/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java @@ -23,13 +23,4 @@ public class AppConstants { */ public static final String APP_ICON = "/img/icon.png"; - /** - * 配置文件名 - */ - public static final String CONFIG_NAME = "jnotepadConfig.json"; - /** - * 快捷键 - */ - public static final String CONFIG_SHORTCUT_KEY_NAME = "shortcutKey"; - } diff --git a/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java b/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java deleted file mode 100644 index b4b08374b82e5a4262ce6d961d38973cc4df703c..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.jcnc.jnotepad.constants; - -/** - * 路径常量
- * @author gewuyou - */ -public class PathConstants { - private PathConstants() { - } -} diff --git a/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java index 9f1e551f8d29dbc20afc19f60f2173d0394ad0af..2796c7b5e841ed3bf3255200557ca81787e3793e 100644 --- a/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java +++ b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java @@ -1,15 +1,6 @@ package org.jcnc.jnotepad.constants; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.jcnc.jnotepad.exception.AppException; -import org.jcnc.jnotepad.json.DataGenerator; -import org.jcnc.jnotepad.json.MyData; -import org.jcnc.jnotepad.tool.JsonUtil; - /** * 文本常量,被多处使用的常量放到此处。如果只有一个class使用,在class中使用private static final声明。 * @@ -50,38 +41,4 @@ public class TextConstants { public static final String CHINESE = "chinese"; - public static final String LOWER_LANGUAGE = "language"; - - /// 配置文件文本常量 - /** - * 内置配置文件 - */ - public static final String JNOTEPAD_CONFIG; - - static { - try { - JNOTEPAD_CONFIG = createShortcutKeyJsonString(); - } catch (JsonProcessingException e) { - throw new AppException(e); - } - } - - private static String createShortcutKeyJsonString() throws JsonProcessingException { - return JsonUtil.toJsonString(createShortcutKeyJson()); - } - - public static ObjectNode createShortcutKeyJson() throws JsonProcessingException { - MyData myData = DataGenerator.generateMyData(); - - // 创建 ObjectMapper 和 ObjectWriter 来将对象转换为 JSON - ObjectMapper objectMapper = new ObjectMapper(); - ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter(); - - // 将 MyData 对象转换为 JSON 字符串 - String json = writer.writeValueAsString(myData); - - // 将 JSON 字符串转换为 ObjectNode 对象 - - return objectMapper.readValue(json, ObjectNode.class); - } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java new file mode 100644 index 0000000000000000000000000000000000000000..99cfcdc5d0af5f64e936c97f4512c2c67d16de7a --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java @@ -0,0 +1,154 @@ +package org.jcnc.jnotepad.controller.config; + +import org.jcnc.jnotepad.app.config.AppConfig; +import org.jcnc.jnotepad.exception.AppException; +import org.jcnc.jnotepad.tool.JsonUtil; +import org.jcnc.jnotepad.tool.LogUtil; +import org.jcnc.jnotepad.tool.PopUpUtil; +import org.slf4j.Logger; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +public class AppConfigController { + + private static final Logger logger = LogUtil.getLogger(AppConfigController.class); + + private static final AppConfigController INSTANCE = new AppConfigController(); + + public static AppConfigController getInstance() { + return INSTANCE; + } + + /** + * 配置文件名 + */ + public static final String CONFIG_NAME = "jnotepadConfig.json"; + + private AppConfig appConfig; + private String dir; + + private AppConfigController() { + setDir(Paths.get(System.getProperty("user.home"), ".jnotepad").toString()); + loadConfig(); + } + + /** + * 加载配置文件内容 + */ + public void loadConfig() { + createConfigIfNotExists(); + Path configPath = getConfigPath(); + + try { + logger.info("正在加载配置文件..."); + // 存在则加载 + String configContent = Files.readString(configPath); + appConfig = JsonUtil.OBJECT_MAPPER.readValue(configContent, AppConfig.class); + } catch (Exception e) { + logger.error("加载配置文件错误", e); + throw new AppException(e); + } + } + + /** + * 配置文件持久化 + */ + public void writeAppConfig() { + createConfigIfNotExists(); + writeAppConfig(this.appConfig); + } + + /** + * 将appConfig对象持久化到配置文件中 + * + * @param appConfig 应用配置对象 + */ + private void writeAppConfig(AppConfig appConfig) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(getConfigPath().toString()))) { + if (appConfig == null) { + appConfig = createShortcutKeyJson(); + } + writer.write(JsonUtil.toJsonString(appConfig)); + } catch (Exception e) { + logger.error("", e); + PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!"); + } + } + + public void createConfigIfNotExists() { + Path configPath = getConfigPath(); + if (configPath.toFile().exists()) { + return; + } + File directory = new File(dir); + if (!directory.exists()) { + directory.mkdirs(); + } + writeAppConfig(null); + } + + public Path getConfigPath() { + return Paths.get(getDir(), CONFIG_NAME); + } + + private AppConfig createShortcutKeyJson() { + return AppConfig.generateDefaultAppConfig(); + } + + /** + * 获取当前配置文件所在目录 + * + * @return + */ + public String getDir() { + return dir; + } + + public void setDir(String dir) { + this.dir = dir; + } + + private AppConfig getAppConfig() { + return appConfig; + } + + /** + * 获取自动换行设置,默认自动换行 + * + * @return true, 自动换行;false,不自动换行 + */ + public boolean getAutoLineConfig() { + return getAppConfig().isTextWrap(); + } + + public void setAutoLineConfig(boolean isAutoLine) { + getAppConfig().setTextWrap(isAutoLine); + } + + /** + * 更新配置文件中的语言设置 + * + * @param language 更新后的语言设置 + */ + public void updateLanguage(String language) { + if (getLanguage().equals(language)) { + return; + } + this.appConfig.setLanguage(language); + writeAppConfig(); + } + + public String getLanguage() { + return this.appConfig.getLanguage(); + } + + public List getShortcutKey() { + return this.appConfig.getShortcutKey(); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/LocalizationHandler.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/LocalizationHandler.java deleted file mode 100644 index 5ce1472c2c37e086ca583e7c8c5d0afc0743bfca..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/LocalizationHandler.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.jcnc.jnotepad.controller.event.handler; - -import javafx.event.ActionEvent; -import javafx.event.EventHandler; - -/** - * 本地化处理抽象类 - * - * @author gewuyou - */ -public abstract class LocalizationHandler implements EventHandler { - -} diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java index a568a37eebea07078f4eaf0260ee1ee485c5ce8f..9bc2952607bea6a37d1540ba091eb68501605e33 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/NewFile.java @@ -27,10 +27,15 @@ public class NewFile implements EventHandler { */ @Override public void handle(ActionEvent event) { + addNewFileTab(); + } + + public void addNewFileTab() { // 创建一个新的文本编辑区 LineNumberTextArea textArea = new LineNumberTextArea(); - + // 设置当前标签页与本地文件无关联 + textArea.setRelevance(false); // TODO: refactor:统一TextArea新建、绑定监听器入口 ViewManager viewManager = ViewManager.getInstance(); // 将Tab页添加到TabPane中 diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenConfig.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenConfig.java index 6419c4a6ec91ec30c9d9c7752de59c56f274a22b..e159683504132c7bd47d94a2bac6198a1a03b460 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenConfig.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenConfig.java @@ -1,30 +1,24 @@ package org.jcnc.jnotepad.controller.event.handler; import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import org.jcnc.jnotepad.controller.manager.Controller; -import org.jcnc.jnotepad.manager.ThreadPoolManager; +import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.tool.LogUtil; import java.io.File; -import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME; - /** * 打开配置文件事件 * * @author gewuyou */ -public class OpenConfig implements EventHandler { +public class OpenConfig extends OpenFile { @Override public void handle(ActionEvent actionEvent) { - Controller controller = Controller.getInstance(); // 显示文件选择对话框,并获取配置文件 - File file = new File(CONFIG_NAME); - LogUtil.getLogger(this.getClass()).info("已调用打开配置文件功能"); - LogUtil.getLogger(this.getClass()).info("{}", file); + File file = AppConfigController.getInstance().getConfigPath().toFile(); + LogUtil.getLogger(this.getClass()).info("已调用打开配置文件功能,{}", file); // 创建打开文件的任务并启动线程执行任务 - ThreadPoolManager.getThreadPool().submit(controller.createOpenFileTask(file)); + openFile(file); } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenFile.java index 25128629f51ddfe7642392788cf420412a9e1619..ad2c8c70ef100fe13aaa96d2bd59b64a3b34870b 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/OpenFile.java @@ -1,12 +1,24 @@ package org.jcnc.jnotepad.controller.event.handler; +import javafx.application.Platform; +import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.stage.FileChooser; -import org.jcnc.jnotepad.controller.manager.Controller; import org.jcnc.jnotepad.manager.ThreadPoolManager; +import org.jcnc.jnotepad.tool.EncodingDetector; +import org.jcnc.jnotepad.tool.LogUtil; +import org.jcnc.jnotepad.ui.LineNumberTextArea; +import org.jcnc.jnotepad.ui.tab.JNotepadTab; +import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.Charset; + +import static org.jcnc.jnotepad.manager.ThreadPoolManager.threadContSelfSubtracting; /** @@ -24,15 +36,96 @@ public class OpenFile implements EventHandler { */ @Override public void handle(ActionEvent event) { - // 获取控制器 - Controller controller = Controller.getInstance(); + // 创建文件选择器 FileChooser fileChooser = new FileChooser(); // 显示文件选择对话框,并获取选中的文件 File file = fileChooser.showOpenDialog(null); if (file != null) { - // 创建打开文件的任务并启动线程执行任务 - ThreadPoolManager.getThreadPool().submit(controller.createOpenFileTask(file)); + openFile(file); } } + + /** + * 创建打开文件的任务。 + * + * @param file 文件对象 + * @return 打开文件的任务 + */ + public Task createOpenFileTask(File file) { + Task openFileTask = new Task<>() { + @Override + protected Void call() { + getText(file); + return null; + } + + }; + // 设置任务成功完成时的处理逻辑 + openFileTask.setOnSucceeded(e -> threadContSelfSubtracting()); + + // 设置任务失败时的处理逻辑 + openFileTask.setOnFailed(e -> threadContSelfSubtracting()); + return openFileTask; + } + + /** + * 打开文件。 + * + * @param file 文件对象 + */ + protected void openFile(File file) { + ThreadPoolManager.getThreadPool().submit(createOpenFileTask(file)); + } + + /** + * 读取文本文件的内容。 + * + * @param file 文件对象 + */ + public void getText(File file) { + LineNumberTextArea textArea = createNewTextArea(); + // 设置当前标签页关联本地文件 + textArea.setRelevance(true); + // 检测文件编码 + Charset encoding = EncodingDetector.detectEncodingCharset(file); + try (BufferedReader reader = new BufferedReader(new FileReader(file, encoding))) { + StringBuilder textBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + 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); + tab.setUserData(file); + JNotepadTabPane.getInstance().addNewTab(tab); + }); + + } catch (IOException ignored) { + LogUtil.getLogger(this.getClass()).info("已忽视IO异常!"); + } + } + + /** + * 创建新的文本区域。 + * + * @return 新的文本区域 + */ + private LineNumberTextArea createNewTextArea() { + return new LineNumberTextArea(); + } + + /** + * 创建新的标签页。 + * + * @param tabName 标签名 + * @param textArea 文本区域 + * @return 新的标签页 + */ + private JNotepadTab createNewTab(String tabName, LineNumberTextArea textArea, Charset charset) { + return new JNotepadTab(tabName, textArea, charset); + } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveAsFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveAsFile.java index d300a6787251be9af43dd05a173bab54bc4d44b2..1d0af6f89c478e6efd2d1e5b9823d665b705f4b4 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveAsFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveAsFile.java @@ -1,11 +1,8 @@ package org.jcnc.jnotepad.controller.event.handler; import javafx.event.ActionEvent; -import javafx.event.EventHandler; import org.jcnc.jnotepad.tool.LogUtil; -import static org.jcnc.jnotepad.tool.FileUtil.saveTab; - /** * 保存文件事件处理器。 @@ -17,7 +14,7 @@ import static org.jcnc.jnotepad.tool.FileUtil.saveTab; * * @author 许轲 */ -public class SaveAsFile implements EventHandler { +public class SaveAsFile extends SaveFile { /** * 处理保存文件事件。 * diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveFile.java index ac9af9dfd3a5399e3852d9222101ab62ceba048f..4f2db0fd1871e1da7a84e6114e3484f9e80ee986 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/SaveFile.java @@ -2,16 +2,19 @@ package org.jcnc.jnotepad.controller.event.handler; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import org.jcnc.jnotepad.LunchApp; +import javafx.stage.FileChooser; +import org.jcnc.jnotepad.controller.config.AppConfigController; +import org.jcnc.jnotepad.controller.i18n.LocalizationController; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.ui.LineNumberTextArea; +import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar; import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; -import org.jcnc.jnotepad.view.init.View; import org.slf4j.Logger; -import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME; -import static org.jcnc.jnotepad.tool.FileUtil.saveTab; +import java.io.File; + +import static org.jcnc.jnotepad.controller.config.AppConfigController.CONFIG_NAME; /** * 保存文件 @@ -47,10 +50,42 @@ public class SaveFile implements EventHandler { // 如果该文件是配置文件则刷新快捷键 if (CONFIG_NAME.equals(selectedTab.getText())) { // 重新加载语言包和快捷键 - View.getInstance().initJnotepadConfigs(LunchApp.getLocalizationConfigs()); + AppConfigController.getInstance().loadConfig(); + JNotepadMenuBar.getMenuBar().initShortcutKeys(); + LocalizationController.initLocal(); logger.info("已刷新语言包!"); logger.info("已刷新快捷键!"); } } } + + /** + * 保存页面方法 + * + * @param currentClass 调用该方法的类 + * @apiNote 将当前选中的标签页进行弹出窗口式的保存 + * @see LogUtil + */ + protected void saveTab(Class currentClass) { + JNotepadTab selectedTab = JNotepadTabPane.getInstance().getSelected(); + if (selectedTab != null) { + // 创建一个文件窗口 + FileChooser fileChooser = new FileChooser(); + // 设置保存文件名称 + fileChooser.setInitialFileName(selectedTab.getText()); + // 设置保存文件类型 + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("文本文档", "*.txt")); + File file = fileChooser.showSaveDialog(null); + if (file != null) { + LogUtil.getLogger(currentClass).info("正在保存文件:{}", file.getName()); + selectedTab.save(); + // 将保存后的文件设置为已关联 + selectedTab.getLineNumberTextArea().setRelevance(true); + // 更新Tab页标签上的文件名 + selectedTab.setText(file.getName()); + // 将文件对象保存到Tab页的UserData中 + selectedTab.setUserData(file); + } + } + } } diff --git a/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java b/src/main/java/org/jcnc/jnotepad/controller/i18n/LocalizationController.java similarity index 51% rename from src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java rename to src/main/java/org/jcnc/jnotepad/controller/i18n/LocalizationController.java index 35aa48c2ddaf89cd0c5c30d9b8da212b53a8670a..da1daa11972dd61f311dc6b83bdf9e2e35407f5a 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/LocalizationConfig.java +++ b/src/main/java/org/jcnc/jnotepad/controller/i18n/LocalizationController.java @@ -1,7 +1,8 @@ -package org.jcnc.jnotepad.app.config; +package org.jcnc.jnotepad.controller.i18n; import org.jcnc.jnotepad.LunchApp; import org.jcnc.jnotepad.app.i18n.UIResourceBundle; +import org.jcnc.jnotepad.controller.config.AppConfigController; import java.util.HashMap; import java.util.LinkedHashMap; @@ -18,9 +19,9 @@ import static org.jcnc.jnotepad.constants.TextConstants.ENGLISH; * @author gewuyou * @see LunchApp */ -public class LocalizationConfig { - private static final LocalizationConfig LOCALIZATION_CONFIG = new LocalizationConfig(); - private String language; +public class LocalizationController { + private static final LocalizationController LOCALIZATION_CONFIG = new LocalizationController(); + private static final Map SUPPORT_LOCALES; private static final Map SUPPORT_LANGUAGES; @@ -39,44 +40,52 @@ public class LocalizationConfig { return Locale.getDefault(); } - public static void setCurrentLocal(Locale locale) { - Locale.setDefault(locale); - UIResourceBundle.getInstance().resetLocal(); - LOCALIZATION_CONFIG.setLanguage(SUPPORT_LANGUAGES.get(locale)); + /** + * 初始化语言配置 + */ + public static void initLocal() { + setCurrentLocal(null); } - public static void setCurrentLocal(String language) { - Locale locale = SUPPORT_LOCALES.get(language); - if (locale != null) { - setCurrentLocal(locale); + /** + * 设置当前语言配置 + * + * @param locale 当前语言Local对象 + */ + public static void setCurrentLocal(Locale locale) { + if (locale != null && locale.equals(getCurrentLocal())) { + // 要更新的语言与当前语言一致,则不执行 + return; } - } - - private LocalizationConfig() { + if (locale == null) { + locale = SUPPORT_LOCALES.get(LOCALIZATION_CONFIG.getLanguage()); + } + if (locale == null) { + locale = getCurrentLocal(); + } + Locale.setDefault(locale); + UIResourceBundle.getInstance().resetLocal(getCurrentLocal()); + LOCALIZATION_CONFIG.setLanguage(SUPPORT_LANGUAGES.get(locale)); } - private String textWrap; - - - public static LocalizationConfig getLocalizationConfig() { - return LOCALIZATION_CONFIG; + private LocalizationController() { + this.appConfigController = AppConfigController.getInstance(); } + private final AppConfigController appConfigController; - public String getTextWrap() { - return textWrap; - } - - public void setTextWrap(String textWrap) { - this.textWrap = textWrap; - } private void setLanguage(String language) { - this.language = language; + appConfigController.updateLanguage(language); } + /** + * 查询当前语言配置 + * + * @return appConfig中的当前语言配置 + */ public String getLanguage() { - return this.language; + return appConfigController.getLanguage(); } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java index d1a8212f1678d63909ed7269a5c77a0f20dfa7a1..df2909a3357b1ef898a6e11279b30e9d12946164 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java +++ b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java @@ -1,27 +1,12 @@ 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.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; -import org.jcnc.jnotepad.ui.LineNumberTextArea; -import org.jcnc.jnotepad.ui.tab.JNotepadTab; -import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; -import org.jcnc.jnotepad.view.manager.ViewManager; +import org.jcnc.jnotepad.controller.event.handler.NewFile; +import org.jcnc.jnotepad.controller.event.handler.OpenFile; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.nio.charset.Charset; import java.util.List; -import static org.jcnc.jnotepad.manager.ThreadPoolManager.threadContSelfSubtracting; - /** * 控制器类,实现ControllerInterface接口,用于管理文本编辑器的各种操作和事件处理。 * 包括打开关联文件、创建文本区域、处理行分隔、新建文件、打开文件、自动保存等功能。 @@ -46,17 +31,12 @@ public class Controller implements ControllerInterface { * @return 创建的文本区域 */ @Override - public LineNumberTextArea openAssociatedFileAndCreateTextArea(List rawParameters) { + public void openAssociatedFileAndCreateTextArea(List rawParameters) { if (!rawParameters.isEmpty()) { String filePath = rawParameters.get(0); openAssociatedFile(filePath); - return null; } else { - LineNumberTextArea textArea = createNewTextArea(); - // 设置当前标签页与本地文件无关联 - textArea.setRelevance(false); - configureTextArea(textArea); - return textArea; + new NewFile().addNewFileTab(); } } @@ -69,116 +49,7 @@ public class Controller implements ControllerInterface { public void openAssociatedFile(String filePath) { File file = new File(filePath); if (file.exists() && file.isFile()) { - openFile(file); + new OpenFile().createOpenFileTask(file); } } - - /** - * 读取文本文件的内容。 - * - * @param file 文件对象 - */ - @Override - public void getText(File file) { - LineNumberTextArea textArea = createNewTextArea(); - // 设置当前标签页关联本地文件 - textArea.setRelevance(true); - // 检测文件编码 - Charset encoding = EncodingDetector.detectEncodingCharset(file); - try (BufferedReader reader = new BufferedReader(new FileReader(file, encoding))) { - StringBuilder textBuilder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - 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); - tab.setUserData(file); - JNotepadTabPane.getInstance().addNewTab(tab); - }); - - } catch (IOException ignored) { - LogUtil.getLogger(this.getClass()).info("已忽视IO异常!"); - } - } - - /** - * 更新UI和标签页 - * - * @param textArea 文本域 - * @apiNote - * @since 2023/8/20 12:40 - */ - @Override - public void updateUiWithNewTextArea(LineNumberTextArea textArea) { - ViewManager viewManager = ViewManager.getInstance(); - String tabTitle = UIResourceBundle.getContent(TextConstants.NEW_FILE) + viewManager.selfIncreaseAndGetTabIndex(); - JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(tabTitle, textArea)); - } - - - /** - * 配置文本区域。 - * - * @param textArea 文本区域 - */ - private void configureTextArea(LineNumberTextArea textArea) { - textArea.getMainTextArea().setWrapText(true); - } - - /** - * 创建新的文本区域。 - * - * @return 新的文本区域 - */ - private LineNumberTextArea createNewTextArea() { - return new LineNumberTextArea(); - } - - /** - * 创建新的标签页。 - * - * @param tabName 标签名 - * @param textArea 文本区域 - * @return 新的标签页 - */ - private JNotepadTab createNewTab(String tabName, LineNumberTextArea textArea, Charset charset) { - return new JNotepadTab(tabName, textArea, charset); - } - - /** - * 创建打开文件的任务。 - * - * @param file 文件对象 - * @return 打开文件的任务 - */ - public Task createOpenFileTask(File file) { - Task openFileTask = new Task<>() { - @Override - protected Void call() { - getText(file); - return null; - } - - }; - // 设置任务成功完成时的处理逻辑 - openFileTask.setOnSucceeded(e -> threadContSelfSubtracting()); - - // 设置任务失败时的处理逻辑 - openFileTask.setOnFailed(e -> threadContSelfSubtracting()); - return openFileTask; - } - - /** - * 打开文件。 - * - * @param file 文件对象 - */ - private void openFile(File file) { - ThreadPoolManager.getThreadPool().submit(createOpenFileTask(file)); - } - } diff --git a/src/main/java/org/jcnc/jnotepad/json/MyData.java b/src/main/java/org/jcnc/jnotepad/json/MyData.java deleted file mode 100644 index 16c767e4fd863c0fd103f0da91a191039acd6c6b..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/json/MyData.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.jcnc.jnotepad.json; - -import java.util.List; - -/** - * 数据模型类,用于表示 MyData 对象的数据结构。 - * - * @author 许轲 - */ -public class MyData { - private String language; - private List shortcutKey; - - /** - * ShortcutKey 类,用于表示快捷键信息。 - */ - public static class ShortcutKey { - private String buttonName; - private String shortcutKeyValue; - - public String getButtonName() { - return buttonName; - } - - public void setButtonName(String buttonName) { - this.buttonName = buttonName; - } - - public String getShortcutKeyValue() { - return shortcutKeyValue; - } - - public void setShortcutKeyValue(String shortcutKeyValue) { - this.shortcutKeyValue = shortcutKeyValue; - } - } - - public String getLanguage() { - return language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public List getShortcutKey() { - return shortcutKey; - } - - public void setShortcutKey(List shortcutKey) { - this.shortcutKey = shortcutKey; - } -} diff --git a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java b/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java deleted file mode 100644 index 630b091d65c2aa262496dbf282576d1a0e07a9b8..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.jcnc.jnotepad.tool; - -import javafx.stage.FileChooser; -import org.jcnc.jnotepad.ui.tab.JNotepadTab; -import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -/** - * @author 一个大转盘 - */ -public class FileUtil { - - private FileUtil() { - } - - /** - * 把一个文件中的内容读取成一个String字符串
- * - * @param jsonFile json文件 - * @return String - */ - public static String getJsonStr(File jsonFile) { - String jsonStr; - try ( - Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8) - ) { - - int ch; - StringBuffer sb = new StringBuffer(); - while ((ch = reader.read()) != -1) { - sb.append((char) ch); - } - jsonStr = sb.toString(); - return jsonStr; - } catch (IOException e) { - LogUtil.getLogger(FileUtil.class).error("读取配置失败!", e); - return null; - } - } - - - /** - * 保存页面方法 - * - * @param currentClass 调用该方法的类 - * @apiNote 将当前选中的标签页进行弹出窗口式的保存 - * @see LogUtil - */ - public static void saveTab(Class currentClass) { - JNotepadTab selectedTab = JNotepadTabPane.getInstance().getSelected(); - if (selectedTab != null) { - // 创建一个文件窗口 - FileChooser fileChooser = new FileChooser(); - // 设置保存文件名称 - fileChooser.setInitialFileName(selectedTab.getText()); - // 设置保存文件类型 - fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("文本文档", "*.txt")); - File file = fileChooser.showSaveDialog(null); - if (file != null) { - LogUtil.getLogger(currentClass).info("正在保存文件:{}", file.getName()); - selectedTab.save(); - // 将保存后的文件设置为已关联 - selectedTab.getLineNumberTextArea().setRelevance(true); - // 更新Tab页标签上的文件名 - selectedTab.setText(file.getName()); - // 将文件对象保存到Tab页的UserData中 - selectedTab.setUserData(file); - } - } - } - -} diff --git a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java index 5823960abb23b1909911654c386a08a3e4ae14f3..cee60a6ad79236e2595fc0d56e10511e0a37ef0a 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java +++ b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java @@ -3,7 +3,10 @@ package org.jcnc.jnotepad.ui; import javafx.beans.property.StringProperty; import javafx.scene.control.TextArea; import javafx.scene.layout.BorderPane; +import org.jcnc.jnotepad.app.config.AppConfig; +import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.tool.LogUtil; +import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar; import org.jcnc.jnotepad.ui.status.JNotepadStatusBox; import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; @@ -30,6 +33,8 @@ public class LineNumberTextArea extends BorderPane { public LineNumberTextArea() { mainTextArea = new TextArea(); + mainTextArea.setWrapText(AppConfigController.getInstance().getAutoLineConfig()); + lineNumberArea = new TextArea(); lineNumberArea.setEditable(false); lineNumberArea.setPrefWidth(MIN_LINE_NUMBER_WIDTH); diff --git a/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java b/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java index f5936edd4dc325cffc3d2752500d3bacd9f95fa1..ae07a03b1a0bf2308f54378d60426900b6ff9118 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java @@ -1,31 +1,21 @@ package org.jcnc.jnotepad.ui.menu; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.node.ObjectNode; import javafx.event.ActionEvent; import javafx.scene.control.*; +import javafx.scene.input.KeyCombination; 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.config.AppConfig; import org.jcnc.jnotepad.app.i18n.UIResourceBundle; +import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.controller.event.handler.*; -import org.jcnc.jnotepad.exception.AppException; -import org.jcnc.jnotepad.tool.JsonUtil; +import org.jcnc.jnotepad.controller.i18n.LocalizationController; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; -import org.jcnc.jnotepad.view.init.View; 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 java.util.*; -import static com.fasterxml.jackson.core.JsonEncoding.UTF8; -import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME; import static org.jcnc.jnotepad.constants.TextConstants.*; /** @@ -42,7 +32,7 @@ public class JNotepadMenuBar extends MenuBar { private static final JNotepadMenuBar MENU_BAR = new JNotepadMenuBar(); - LocalizationConfig localizationConfig = LocalizationConfig.getLocalizationConfig(); + AppConfigController appConfigController = AppConfigController.getInstance(); Logger logger = LogUtil.getLogger(this.getClass()); private JNotepadMenuBar() { @@ -142,6 +132,30 @@ public class JNotepadMenuBar extends MenuBar { // 菜单栏 this.getMenus().addAll(fileMenu, setMenu, pluginMenu); initEventHandlers(); + initShortcutKeys(); + toggleLanguageCheck(appConfigController.getLanguage()); + } + + /** + * 初始化快捷键。 + */ + public void initShortcutKeys() { + List shortcutKeyConfigs = appConfigController.getShortcutKey(); + //FIXME: 如果shortcutKey不存在,需要解绑已绑定的快捷键 + for (AppConfig.ShortcutKey shortcutKey : shortcutKeyConfigs) { + // 保证json的key必须和变量名一致 + MenuItem menuItem = this.itemMap.get(shortcutKey.getButtonName()); + if (Objects.isNull(menuItem)) { + continue; + } + String shortKeyValue = shortcutKey.getShortcutKeyValue(); + if ("".equals(shortKeyValue)) { + continue; + } + logger.info("功能名称:{}->快捷键:{}", menuItem.getText(), shortKeyValue); + // 动态添加快捷键 + menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue)); + } } /** @@ -260,7 +274,7 @@ public class JNotepadMenuBar extends MenuBar { openConfigItem.setOnAction(new OpenConfig()); lineFeedItem.selectedProperty().addListener((observableValue, before, after) -> { // 1. 更新全局配置 - GlobalConfig.getConfig().setAutoLineConfig(after); + AppConfigController.getInstance().setAutoLineConfig(after); // 2. 对当前tab生效配置 jNotepadTabPane.fireTabSelected(); }); @@ -270,31 +284,14 @@ public class JNotepadMenuBar extends MenuBar { // 设置窗口为置顶 primaryStage.setAlwaysOnTop(after); }); - englishItem.setOnAction(new LocalizationHandler() { - @Override - public void handle(ActionEvent actionEvent) { - try { - setCurrentLanguage(ENGLISH); - toggleLanguage(actionEvent); - - } catch (JsonProcessingException e) { - throw new AppException(e.getMessage()); - } - } - }); - chineseItem.setOnAction(new LocalizationHandler() { - @Override - public void handle(ActionEvent actionEvent) { - try { - setCurrentLanguage(CHINESE); - toggleLanguage(actionEvent); - } catch (JsonProcessingException e) { - throw new AppException(e.getMessage()); - } - } - }); + englishItem.setOnAction(this::toggleLanguage); + chineseItem.setOnAction(this::toggleLanguage); } + /** + * 切换语言 + * @param actionEvent 点击事件 + */ private void toggleLanguage(ActionEvent actionEvent) { if (actionEvent == null) { return; @@ -303,61 +300,9 @@ public class JNotepadMenuBar extends MenuBar { if (languageItem == null) { return; } - LocalizationConfig.setCurrentLocal((Locale) languageItem.getUserData()); + LocalizationController.setCurrentLocal((Locale) languageItem.getUserData()); } - /** - * 设置当前语言
- * - * @param language 要设置的语言 - * @since 2023/8/26 16:16 - */ - private void setCurrentLanguage(String language) throws JsonProcessingException { - // 如果当前已是该语言则不执行该方法 - if (localizationConfig.getLanguage().equals(language)) { - return; - } - boolean flag = false; - // 获取本地配置文件 - logger.info("尝试读取本地配置文件!"); - StringBuilder jsonData = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(CONFIG_NAME)))) { - String line; - while ((line = reader.readLine()) != null) { - jsonData.append(line); - } - } catch (IOException e) { - logger.error("读取失败,配置文件错误或不存在配置文件!"); - flag = true; - } - ObjectNode json; - - if (!flag) { - json = JsonUtil.OBJECT_MAPPER.readValue(jsonData.toString(), ObjectNode.class); - logger.info("读取本地配置文件成功!"); - } else { - logger.info("获取默认内置配置文件!"); - // 如果读取本地失败则获取默认配置文件 - json = createShortcutKeyJson(); - } - try (BufferedWriter writer = new BufferedWriter(new FileWriter(CONFIG_NAME, Charset.forName(UTF8.name())))) { - // 更新语言值为 language 并写回本地 - json.put(LOWER_LANGUAGE, language); - writer.write(JsonUtil.toJsonString(json)); - // 刷新文件 - writer.flush(); - // 重新加载快捷键与语言包 - View.getInstance().initJnotepadConfigs(LunchApp.getLocalizationConfigs()); - logger.info("已刷新语言包!"); - logger.info("已刷新快捷键!"); - } catch (IOException e) { - logger.error("配置文件写入失败,请检查配置文件"); - } - } - - public Map getItemMap() { - return itemMap; - } /** * 根据当前选中tab,更新菜单选项 diff --git a/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTab.java b/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTab.java index 5c41adfc9097ff03a88553674f8df323d173e877..ad13d416d6c01779fd1e5c39ad6c597e4999ab00 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTab.java +++ b/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTab.java @@ -1,7 +1,7 @@ package org.jcnc.jnotepad.ui.tab; import javafx.scene.control.Tab; -import org.jcnc.jnotepad.app.config.GlobalConfig; +import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.ui.LineNumberTextArea; import java.nio.charset.Charset; @@ -33,7 +33,7 @@ public class JNotepadTab extends Tab { super(tabTitle); lineNumberTextArea = textArea; this.setContent(lineNumberTextArea); - setAutoLine(GlobalConfig.getConfig().getAutoLineConfig()); + setAutoLine(AppConfigController.getInstance().getAutoLineConfig()); this.charset = charset; } diff --git a/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTabPane.java b/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTabPane.java index c87cedb786930fcf003c0a86a5d1e4be35be7791..ea509a8b2dd39fcdf00ee2b7d1c09d6a5afc9b5b 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTabPane.java +++ b/src/main/java/org/jcnc/jnotepad/ui/tab/JNotepadTabPane.java @@ -1,7 +1,7 @@ package org.jcnc.jnotepad.ui.tab; import javafx.scene.control.TabPane; -import org.jcnc.jnotepad.app.config.GlobalConfig; +import org.jcnc.jnotepad.controller.config.AppConfigController; import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar; import org.jcnc.jnotepad.ui.status.JNotepadStatusBox; @@ -68,7 +68,7 @@ public class JNotepadTabPane extends TabPane { */ public void fireTabSelected() { JNotepadTab selectedTab = getSelected(); - selectedTab.setAutoLine(GlobalConfig.getConfig().getAutoLineConfig()); + selectedTab.setAutoLine(AppConfigController.getInstance().getAutoLineConfig()); JNotepadStatusBox.getInstance().updateWhenTabSelected(); } } diff --git a/src/main/java/org/jcnc/jnotepad/view/init/View.java b/src/main/java/org/jcnc/jnotepad/view/init/View.java deleted file mode 100644 index bde1f0d48c6600f2c723f309c1d051be247e5a66..0000000000000000000000000000000000000000 --- a/src/main/java/org/jcnc/jnotepad/view/init/View.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.jcnc.jnotepad.view.init; - -import org.jcnc.jnotepad.app.init.LoadJnotepadConfig; - -import java.util.List; - - -/** - * @author 许轲 - */ -public class View { - - private View() { - } - - private static final View INSTANCE = new View(); - - /** - * 初始化配置文件 - * - * @param loadJnotepadConfigs 需要加载的配置文件数组 - * @since 2023/8/24 15:29 - */ - public void initJnotepadConfigs(List> 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; - } -}