diff --git a/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java b/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java index feed804..66c4175 100644 --- a/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java +++ b/src/main/java/org/jcnc/jnotepad/Interface/ControllerInterface.java @@ -31,7 +31,7 @@ public interface ControllerInterface { * * @param file 文件 */ - LineNumberTextArea getText(File file); + void getText(File file); /** * 更新UI和标签页 diff --git a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java index 6b7535a..4f458ec 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/GlobalConfig.java @@ -4,6 +4,8 @@ import org.jcnc.jnotepad.init.Config; import java.util.Properties; +import static org.jcnc.jnotepad.constants.TextConstants.TEXT_WRAP; + /** * 内存中,运行过程中的全局配置项 * @@ -11,10 +13,6 @@ import java.util.Properties; */ public class GlobalConfig { - /** - * 自动换行配置key - */ - public static final String TEXT_WRAP = "text.wrap"; private static final GlobalConfig APP_GLOBAL_CONFIG = new GlobalConfig(); private final Properties properties; diff --git a/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java new file mode 100644 index 0000000..084421b --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/constants/TextConstants.java @@ -0,0 +1,67 @@ +package org.jcnc.jnotepad.constants; + +import org.jcnc.jnotepad.init.Config; + +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"); + + /// GlobalConfig文本常量 + /** + * 自动换行配置key + */ + public static final String TEXT_WRAP = "text.wrap"; + + /// NewFile 文本常量 + + public static final String NEW_FILE = PROPERTIES.getProperty("NEW_FILE"); + + /// 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"); + + /// EncodingDetector 文本常量 + public static final String UNKNOWN = "UNKNOWN"; + + /// 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"); +} 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 0565aae..2ffbe7b 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 @@ -2,14 +2,14 @@ package org.jcnc.jnotepad.controller.event.handler; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import org.jcnc.jnotepad.init.Config; +import org.jcnc.jnotepad.tool.LogUtil; 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 java.util.Properties; +import static org.jcnc.jnotepad.constants.TextConstants.NEW_FILE; /** @@ -21,9 +21,6 @@ import java.util.Properties; */ public class NewFile implements EventHandler { - Config config = new Config(); - Properties properties = config.readPropertiesFromFile(); - String NEW_FILE = properties.getProperty("NEW_FILE"); /** * * 处理新建文件事件。 @@ -38,6 +35,7 @@ public class NewFile implements EventHandler { // TODO: refactor:统一TextArea新建、绑定监听器入口 ViewManager viewManager = ViewManager.getInstance(); + LogUtil.getLogger(NewFile.class).info("{}", NEW_FILE); // 将Tab页添加到TabPane中 JNotepadTabPane.getInstance().addNewTab(new JNotepadTab(NEW_FILE + viewManager.selfIncreaseAndGetTabIndex(), 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 97fe5bb..96fd01f 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 @@ -32,28 +32,40 @@ public class OpenFile implements EventHandler { File file = fileChooser.showOpenDialog(null); if (file != null) { // 创建打开文件的任务 - Task openFileTask = new Task<>() { - @Override - protected Void call() { - // 调用控制器的getText方法,读取文件内容 - controller.getText(file); - return null; - } - }; - - // 设置任务成功完成时的处理逻辑 - openFileTask.setOnSucceeded(e -> { - // 处理成功的逻辑 - }); - - // 设置任务失败时的处理逻辑 - openFileTask.setOnFailed(e -> { - // 处理失败的逻辑 - }); - + Task openFileTask = getVoidTask(controller, file); // 创建并启动线程执行任务 Thread thread = new Thread(openFileTask); thread.start(); } } + + /** + * 获取空返回值任务 + * + * @param controller 控制器 + * @param file 文件 + * @return javafx.concurrent.Task + * @apiNote + */ + private static Task getVoidTask(Controller controller, File file) { + Task openFileTask = new Task<>() { + @Override + protected Void call() { + // 调用控制器的getText方法,读取文件内容 + controller.getText(file); + return null; + } + }; + + // 设置任务成功完成时的处理逻辑 + openFileTask.setOnSucceeded(e -> { + // 处理成功的逻辑 + }); + + // 设置任务失败时的处理逻辑 + openFileTask.setOnFailed(e -> { + // 处理失败的逻辑 + }); + return openFileTask; + } } 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 273c1a5..f531032 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java +++ b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java @@ -3,7 +3,6 @@ package org.jcnc.jnotepad.controller.manager; import javafx.application.Platform; import javafx.concurrent.Task; import org.jcnc.jnotepad.Interface.ControllerInterface; -import org.jcnc.jnotepad.init.Config; import org.jcnc.jnotepad.tool.EncodingDetector; import org.jcnc.jnotepad.tool.LogUtil; import org.jcnc.jnotepad.ui.LineNumberTextArea; @@ -17,7 +16,8 @@ import java.io.FileReader; import java.io.IOException; import java.nio.charset.Charset; import java.util.List; -import java.util.Properties; + +import static org.jcnc.jnotepad.constants.TextConstants.NEW_FILE; /** * 控制器类,实现ControllerInterface接口,用于管理文本编辑器的各种操作和事件处理。 @@ -27,10 +27,6 @@ import java.util.Properties; */ public class Controller implements ControllerInterface { - Config config = new Config(); - Properties properties = config.readPropertiesFromFile(); - - String NEW_FILE = properties.getProperty("NEW_FILE"); private static final Controller INSTANCE = new Controller(); private Controller() { @@ -80,7 +76,7 @@ public class Controller implements ControllerInterface { * @param file 文件对象 */ @Override - public LineNumberTextArea getText(File file) { + public void getText(File file) { LineNumberTextArea textArea = createNewTextArea(); // 设置当前标签页关联本地文件 textArea.setRelevance(true); @@ -104,7 +100,6 @@ public class Controller implements ControllerInterface { } catch (IOException ignored) { LogUtil.getLogger(this.getClass()).info("已忽视IO异常!"); } - return textArea; } /** diff --git a/src/main/java/org/jcnc/jnotepad/init/Config.java b/src/main/java/org/jcnc/jnotepad/init/Config.java index 67374c0..e8da016 100644 --- a/src/main/java/org/jcnc/jnotepad/init/Config.java +++ b/src/main/java/org/jcnc/jnotepad/init/Config.java @@ -1,11 +1,16 @@ 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.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 许轲 @@ -13,7 +18,9 @@ import static org.jcnc.jnotepad.constants.AppConstants.EN_LANGUAGE_PACK_NAME; */ public class Config { - String LANGUAGE_PACK_NAME; + private String languagePackName; + + Logger logger = LogUtil.getLogger(this.getClass()); /** * 从文件中读取属性配置。 @@ -24,8 +31,8 @@ public class Config { Properties properties = new Properties(); //设置语言包 - LANGUAGE_PACK_NAME = EN_LANGUAGE_PACK_NAME; - try (InputStream inputStream = new FileInputStream(LANGUAGE_PACK_NAME)) { + languagePackName = EN_LANGUAGE_PACK_NAME; + try (InputStream inputStream = new FileInputStream(languagePackName)) { InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码 properties.load(reader); } catch (IOException e) { @@ -40,26 +47,28 @@ public class Config { * 如果属性文件不存在,将创建一个新的属性文件并设置默认属性。 */ public void initializePropertiesFile() { - Properties chLanguagePack = getCHLanguagePack(); + Properties chLanguagePack = getChineseLanguagePack(); - Properties enLanguagePack = getENLanguagePack(); + Properties enLanguagePack = getEnglishLanguagePack(); try (OutputStream outputStream = new FileOutputStream(CH_LANGUAGE_PACK_NAME)) { OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码 - chLanguagePack.store(writer, "JNotepad ch_language_pack"); + chLanguagePack.store(writer, JNOTEPAD_CH_LANGUAGE_PACK_NAME); } catch (IOException ignored) { + logger.info("未检测到中文语言包!"); } try (OutputStream outputStream = new FileOutputStream(EN_LANGUAGE_PACK_NAME)) { OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码 - enLanguagePack.store(writer, "JNotepad en_language_pack"); + enLanguagePack.store(writer, JNOTEPAD_EN_LANGUAGE_PACK_NAME); } catch (IOException ignored) { + logger.info("未检测到英文语言包!"); } } - private static Properties getCHLanguagePack() { + private static Properties getChineseLanguagePack() { Properties properties = new Properties(); properties.setProperty("TITLE", "JNotepad"); // 设置默认属性 @@ -81,7 +90,7 @@ public class Config { return properties; } - private static Properties getENLanguagePack() { + private static Properties getEnglishLanguagePack() { Properties properties = new Properties(); properties.setProperty("TITLE", "JNotepad"); diff --git a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java index 9e77439..84d1d86 100644 --- a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java +++ b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java @@ -3,19 +3,15 @@ package org.jcnc.jnotepad.tool; import com.ibm.icu.text.CharsetDetector; import com.ibm.icu.text.CharsetMatch; -import javafx.application.Platform; -import org.jcnc.jnotepad.ui.LineNumberTextArea; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; + +import static org.jcnc.jnotepad.constants.TextConstants.UNKNOWN; /** * 编码检测工具类 @@ -24,8 +20,8 @@ import java.nio.file.Paths; */ public class EncodingDetector { - private static final Logger LOG = LoggerFactory.getLogger(EncodingDetector.class); - public static final String UNKNOWN = "UNKNOWN"; + private static final Logger LOG = LogUtil.getLogger(EncodingDetector.class); + private EncodingDetector() { } @@ -41,14 +37,13 @@ public class EncodingDetector { try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file.getPath()))) { charsetDetector.setText(inputStream); CharsetMatch match = charsetDetector.detect(); - LOG.debug(match.getName() + " " + match.getConfidence()); + LOG.debug("{} : {}", match.getName(), match.getConfidence()); if (match.getConfidence() > 50) { return match.getName(); } } catch (Exception e) { LOG.error("", e); } - return UNKNOWN; } diff --git a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java b/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java index 6895f9f..a1b0351 100644 --- a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java +++ b/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java @@ -1,8 +1,6 @@ package org.jcnc.jnotepad.tool; -import javafx.scene.control.Tab; import javafx.stage.FileChooser; -import org.jcnc.jnotepad.ui.LineNumberTextArea; import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; @@ -13,12 +11,12 @@ import java.nio.charset.StandardCharsets; * @author 一个大转盘 */ public class FileUtil { + private FileUtil() { } /** * 把一个文件中的内容读取成一个String字符串
- * 注意:该方法不支持多线程操作 * * @param jsonFile json文件 * @return String @@ -30,7 +28,7 @@ public class FileUtil { ) { int ch; - StringBuilder sb = new StringBuilder(); + StringBuffer sb = new StringBuffer(); while ((ch = reader.read()) != -1) { sb.append((char) ch); } @@ -60,6 +58,7 @@ public class FileUtil { 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); diff --git a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java index 9008a0f..510bd4a 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java +++ b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java @@ -1,7 +1,6 @@ package org.jcnc.jnotepad.ui; import javafx.beans.property.StringProperty; -import javafx.scene.control.Tab; import javafx.scene.control.TextArea; import javafx.scene.layout.BorderPane; import org.jcnc.jnotepad.tool.LogUtil; 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 07a6917..7a94098 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/ui/menu/JNotepadMenuBar.java @@ -5,14 +5,17 @@ import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import org.jcnc.jnotepad.app.config.GlobalConfig; -import org.jcnc.jnotepad.controller.event.handler.*; -import org.jcnc.jnotepad.init.Config; +import org.jcnc.jnotepad.controller.event.handler.NewFile; +import org.jcnc.jnotepad.controller.event.handler.OpenFile; +import org.jcnc.jnotepad.controller.event.handler.SaveAsFile; +import org.jcnc.jnotepad.controller.event.handler.SaveFile; import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; import java.util.HashMap; import java.util.Map; -import java.util.Properties; + +import static org.jcnc.jnotepad.constants.TextConstants.*; /** * 封装菜单栏组件。 @@ -21,23 +24,11 @@ import java.util.Properties; */ public class JNotepadMenuBar extends MenuBar { - Config config = new Config(); - Properties properties = config.readPropertiesFromFile(); - String SAVA = properties.getProperty("SAVA"); - String FILE = properties.getProperty("FILE"); - String NEW = properties.getProperty("NEW"); - String OPEN = properties.getProperty("OPEN"); - String SAVA_AS = properties.getProperty("SAVA_AS"); - String SET = properties.getProperty("SET"); - - String WORD_WRAP = properties.getProperty("WORD_WRAP"); - - String PLUGIN = properties.getProperty("PLUGIN"); - - String ADD_PLUGIN = properties.getProperty("ADD_PLUGIN"); - - String STATISTICS = properties.getProperty("STATISTICS"); + /** + * 标签页布局组件封装。 + */ + JNotepadTabPane jNotepadTabPane = JNotepadTabPane.getInstance(); private static final JNotepadMenuBar MENU_BAR = new JNotepadMenuBar(); @@ -172,7 +163,7 @@ public class JNotepadMenuBar extends MenuBar { // 1. 更新全局配置 GlobalConfig.getConfig().setAutoLineConfig(after); // 2. 对当前tab生效配置 - JNotepadTabPane.getInstance().fireTabSelected(); + jNotepadTabPane.fireTabSelected(); }); } @@ -184,7 +175,7 @@ public class JNotepadMenuBar extends MenuBar { * 根据当前选中tab,更新菜单选项 */ public void updateMenuStatusBySelectedTab() { - JNotepadTab selectedTab = JNotepadTabPane.getInstance().getSelected(); + JNotepadTab selectedTab = jNotepadTabPane.getSelected(); lineFeedItem.selectedProperty().setValue(selectedTab.isAutoLine()); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java b/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java index 1de1f9a..0990e7c 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java +++ b/src/main/java/org/jcnc/jnotepad/ui/status/JNotepadStatusBox.java @@ -4,11 +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.init.Config; +import org.jcnc.jnotepad.ui.tab.JNotepadTab; import org.jcnc.jnotepad.ui.tab.JNotepadTabPane; import java.nio.charset.Charset; -import java.util.Properties; + +import static org.jcnc.jnotepad.constants.TextConstants.*; /** * 状态栏组件封装。 @@ -19,16 +20,6 @@ import java.util.Properties; */ public class JNotepadStatusBox extends HBox { - Config config = new Config(); - Properties properties = config.readPropertiesFromFile(); - String ROW = properties.getProperty("ROW"); - - String COLUMN = properties.getProperty("COLUMN"); - - String WORD_COUNT = properties.getProperty("WORD_COUNT"); - - String ENCODE = properties.getProperty("ENCODE"); - private static final JNotepadStatusBox STATUS_BOX = new JNotepadStatusBox(); /** @@ -77,7 +68,11 @@ public class JNotepadStatusBox extends HBox { * 更新字数统计 */ public void updateWordCountStatusLabel() { - TextArea textArea = JNotepadTabPane.getInstance().getSelected().getLineNumberTextArea().getMainTextArea(); + JNotepadTabPane instance = JNotepadTabPane.getInstance(); + if (instance.getSelected() == null) { + return; + } + TextArea textArea = instance.getSelected().getLineNumberTextArea().getMainTextArea(); int caretPosition = textArea.getCaretPosition(); int row = getRow(caretPosition, textArea.getText()); int column = getColumn(caretPosition, textArea.getText()); @@ -87,12 +82,18 @@ public class JNotepadStatusBox extends HBox { /** * Tab选中时,更新状态栏 - * 1. 状态栏更新当前选中tab的数字统计 - * 2. 状态栏更新当前选中tab的字符编码 + *
1. 状态栏更新当前选中tab的数字统计 + *
2. 状态栏更新当前选中tab的字符编码 */ public void updateWhenTabSelected() { - updateWordCountStatusLabel(); - updateEncodingLabel(JNotepadTabPane.getInstance().getSelected().getCharset().name()); + JNotepadTabPane instance = JNotepadTabPane.getInstance(); + if (instance.getSelected() != null) { + updateWordCountStatusLabel(); + JNotepadTab jNotepadTab = instance.getSelected(); + if (jNotepadTab != null) { + updateEncodingLabel(jNotepadTab.getCharset().name()); + } + } } /** diff --git a/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java b/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java index 846d1d4..804d1b2 100644 --- a/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java +++ b/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java @@ -1,10 +1,7 @@ package org.jcnc.jnotepad.view.manager; -import javafx.geometry.Insets; import javafx.scene.Scene; -import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; -import javafx.scene.layout.HBox; import org.jcnc.jnotepad.exception.AppException; import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar; import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;