rawParameters = getParameters().getRaw();
- threadPool.execute(() -> {
+ THREAD_POOL.execute(() -> {
LineNumberTextArea textArea = controller.openAssociatedFileAndCreateTextArea(rawParameters);
if (!Objects.isNull(textArea)) {
Platform.runLater(() -> controller.updateUiWithNewTextArea(textArea));
@@ -82,7 +88,7 @@ public class LunchApp extends Application {
@Override
public void stop() {
// 关闭线程池
- threadPool.shutdownNow();
+ THREAD_POOL.shutdownNow();
}
public static void main(String[] args) {
diff --git a/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java b/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..3650c4b267cf607df5e2469ed0f07f5b1132e304
--- /dev/null
+++ b/src/main/java/org/jcnc/jnotepad/constants/AppConstants.java
@@ -0,0 +1,34 @@
+package org.jcnc.jnotepad.constants;
+
+/**
+ * 应用常量
+ * @author 许轲
+ */
+
+public class AppConstants {
+ private AppConstants() {
+ }
+
+ /**
+ * 初始宽度
+ */
+ public static final double SCREEN_WIDTH = 800;
+ /**
+ * 初始高度
+ */
+ 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 PROPERTY_FILE_NAME = "project.txt";
+
+}
diff --git a/src/main/java/org/jcnc/jnotepad/constants/Constants.java b/src/main/java/org/jcnc/jnotepad/constants/Constants.java
deleted file mode 100644
index a2185ce64074a54353b36287dacc2ef57cb6e1c6..0000000000000000000000000000000000000000
--- a/src/main/java/org/jcnc/jnotepad/constants/Constants.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.jcnc.jnotepad.constants;
-
-/**
- * Constants持有所有共享信息的全局变量
- */
-
-public class Constants {
- public static final double SCREEN_WIDTH = 800; //宽度
- public static final double SCREEN_LENGTH = 600; //高度
- public static final String APP_NAME = "JNotepad"; //名字
- public static final String APP_ICON = "/img/icon.png"; //logo地址
-
- //配置文件
- public static final String PROPERTY_FILE_NAME = "project.txt"; //配置文件名字
-
-}
diff --git a/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java b/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..e666e75cdeed67e6a986d668541515f87496fefd
--- /dev/null
+++ b/src/main/java/org/jcnc/jnotepad/constants/PathConstants.java
@@ -0,0 +1,17 @@
+package org.jcnc.jnotepad.constants;
+
+/**
+ * 路径常量
+ *
+ * @author gewuyou
+ */
+public class PathConstants {
+ private PathConstants() {
+ }
+
+ /**
+ * 快捷键配置文件路径
+ * todo:这里这个配置可以通过配置文件读取
+ */
+ public static final String SHORTCUT_KEY_CONFIGURATION_FILE_PATH = "/config/shortcutKey.json";
+}
diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/LineFeed.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/LineFeed.java
index bf8e9ab3ba21d67da34b918939b1cd64b3df6e00..8c5af377b4c2abbdb96658db6e84b817d75fd9c3 100644
--- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/LineFeed.java
+++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/LineFeed.java
@@ -8,6 +8,7 @@ import org.jcnc.jnotepad.ui.LineNumberTextArea;
* 换行程序。
*
* 用于在文本区域中插入一个换行符。
+ * @author 许轲
*/
public class LineFeed implements EventHandler {
private final LineNumberTextArea textArea;
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 7482cd3a78fde78758c5662229b79087cc81d77f..8e79a0179134214d81556d4e02e9a441801330ef 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
@@ -3,16 +3,17 @@ package org.jcnc.jnotepad.controller.event.handler;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Tab;
-import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.controller.manager.Controller;
+import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.view.manager.ViewManager;
-import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
/**
* 新建文件事件的事件处理程序。
*
* 当用户选择新建文件时候,将创建一个新的文本编辑区,并在Tab页中显示。
+ *
+ * @author 许轲
*/
public class NewFile implements EventHandler {
/**
@@ -28,24 +29,22 @@ public class NewFile implements EventHandler {
// 创建一个新的文本编辑区
LineNumberTextArea textArea = new LineNumberTextArea();
-
textArea.setStyle(
"-fx-border-color:white ;-fx-background-color:white;"
);
- //TODO: refactor:统一TextArea新建、绑定监听器入口
+ // TODO: refactor:统一TextArea新建、绑定监听器入口
// 增加autoSave监听器绑定
controller.autoSave(textArea);
-
+ ViewManager viewManager = ViewManager.getInstance();
// 创建一个新的Tab页
- Tab tab = new Tab("新建文本 " + ++ViewManager.tabIndex);
+ Tab tab = new Tab("新建文本 " + viewManager.selfIncreaseAndGetTabIndex());
tab.setContent(textArea);
-
// 将Tab页添加到TabPane中
- tabPane.getTabs().add(tab);
+ viewManager.getTabPane().getTabs().add(tab);
// 将新建的Tab页设置为选中状态
- tabPane.getSelectionModel().select(tab);
+ viewManager.getTabPane().getSelectionModel().select(tab);
// 更新状态标签
controller.updateStatusLabel(textArea);
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 635a34a02f300d1a5c4d0da2650d0f497a686de6..ddb64b86ad9285dbc8422fea567c888078f1b064 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
@@ -3,19 +3,19 @@ package org.jcnc.jnotepad.controller.event.handler;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
-
import javafx.stage.FileChooser;
-import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.controller.manager.Controller;
+import org.jcnc.jnotepad.ui.LineNumberTextArea;
+import org.jcnc.jnotepad.view.manager.ViewManager;
import java.io.File;
-import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
/**
* 打开文件的事件处理程序。
*
* 当用户选择打开文件时,将创建一个新的文本编辑区,并在Tab页中显示。
+ * @author 许轲
*/
public class OpenFile implements EventHandler {
/**
@@ -25,6 +25,8 @@ public class OpenFile implements EventHandler {
*/
@Override
public void handle(ActionEvent event) {
+ // 获取ViewManager的实例
+ ViewManager viewManager = ViewManager.getInstance();
// 获取控制器
Controller controller = Controller.getInstance();
// 创建文件选择器
@@ -39,7 +41,7 @@ public class OpenFile implements EventHandler {
// 调用控制器的getText方法,读取文件内容
controller.getText(file);
// 更新编码标签
- controller.upDateEncodingLabel(((LineNumberTextArea) tabPane.getSelectionModel().getSelectedItem().getContent()).getMainTextArea().getText());
+ controller.upDateEncodingLabel(((LineNumberTextArea) viewManager.getTabPane().getSelectionModel().getSelectedItem().getContent()).getMainTextArea().getText());
return null;
}
};
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 3299bf6812557f519ba2cd9aab2545a03847ace7..b2c1536f9d68d925ae9359b28718283fcb107d8d 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
@@ -4,14 +4,15 @@ import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Tab;
import javafx.stage.FileChooser;
+import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.ui.LineNumberTextArea;
+import org.jcnc.jnotepad.view.manager.ViewManager;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
/**
* 保存文件事件处理器。
@@ -20,6 +21,8 @@ import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
* 会弹出一个保存文件对话框,用户选择保存位置和文件名后,
* 将当前文本编辑区的内容保存到指定文件中,
* 并更新Tab页上的文件名和UserData。
+ *
+ * @author 许轲
*/
public class SaveAsFile implements EventHandler {
/**
@@ -29,23 +32,25 @@ public class SaveAsFile implements EventHandler {
*/
@Override
public void handle(ActionEvent event) {
- Tab selectedTab = tabPane.getSelectionModel().getSelectedItem();
+ ViewManager viewManager = ViewManager.getInstance();
+ Tab selectedTab = viewManager.getTabPane().getSelectionModel().getSelectedItem();
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) {
- try {
- BufferedWriter writer = new BufferedWriter(new FileWriter(file));
+ try (
+ BufferedWriter writer = new BufferedWriter(new FileWriter(file))
+ ) {
LineNumberTextArea textArea = (LineNumberTextArea) selectedTab.getContent(); // 获取当前Tab页的文本编辑区
String text = textArea.getMainTextArea().getText();
writer.write(text); // 写入文件内容
writer.flush();
- writer.close();
selectedTab.setText(file.getName()); // 更新Tab页标签上的文件名
selectedTab.setUserData(file); // 将文件对象保存到Tab页的UserData中
} catch (IOException ignored) {
+ LogUtil.info("已忽略IO异常!",this.getClass());
}
}
}
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 099e8be09db2ce0fd73ac85b11e0289685224e99..a7b14174a9f780fdcd854777d49d2e92bae77b39 100644
--- a/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java
+++ b/src/main/java/org/jcnc/jnotepad/controller/manager/Controller.java
@@ -6,12 +6,12 @@ import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Tab;
import org.jcnc.jnotepad.Interface.ControllerInterface;
-import org.jcnc.jnotepad.LunchApp;
import org.jcnc.jnotepad.controller.event.handler.LineFeed;
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.tool.EncodingDetector;
+import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.view.manager.ViewManager;
@@ -26,8 +26,15 @@ import java.util.List;
* @author 许轲
*/
public class Controller implements ControllerInterface {
-
private static final Controller INSTANCE = new Controller();
+ /**
+ * 是否关联
+ */
+ private boolean isRelevance = true;
+
+ public boolean isRelevance() {
+ return isRelevance;
+ }
private Controller() {
}
@@ -95,15 +102,15 @@ public class Controller implements ControllerInterface {
@Override
public void autoSave(LineNumberTextArea textArea) {
textArea.getMainTextArea().textProperty().addListener((observable, oldValue, newValue) -> {
- Tab tab = ViewManager.tabPane.getSelectionModel().getSelectedItem();
+ Tab tab = ViewManager.getInstance().getTabPane().getSelectionModel().getSelectedItem();
if (tab != null) {
File file = (File) tab.getUserData();
if (file != null) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(newValue);
- System.out.println("正在自动保存---");
+ LogUtil.info("正在自动保存---",this.getClass());
} catch (IOException ignored) {
-
+ LogUtil.info("已忽略IO异常!",this.getClass());
}
}
}
@@ -131,7 +138,7 @@ public class Controller implements ControllerInterface {
int row = getRow(caretPosition, textArea.getMainTextArea().getText());
int column = getColumn(caretPosition, textArea.getMainTextArea().getText());
int length = textArea.getMainTextArea().getLength();
- ViewManager.statusLabel.setText("行: " + row + " \t列: " + column + " \t字数: " + length);
+ ViewManager.getInstance().getStatusLabel().setText("行: " + row + " \t列: " + column + " \t字数: " + length);
}
/**
@@ -143,7 +150,7 @@ public class Controller implements ControllerInterface {
public void openAssociatedFile(String filePath) {
File file = new File(filePath);
if (file.exists() && file.isFile()) {
- LunchApp.isRelevance = false;
+ isRelevance = false;
openFile(file);
}
}
@@ -155,6 +162,7 @@ public class Controller implements ControllerInterface {
*/
@Override
public void getText(File file) {
+ ViewManager viewManager = ViewManager.getInstance();
LineNumberTextArea textArea = createNewTextArea();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
StringBuilder textBuilder = new StringBuilder();
@@ -169,15 +177,15 @@ public class Controller implements ControllerInterface {
Tab tab = createNewTab(file.getName(), textArea);
tab.setUserData(file);
- ViewManager.tabPane.getTabs().add(tab);
+ viewManager.getTabPane().getTabs().add(tab);
// ViewManager.tabPane.sets
- ViewManager.tabPane.getSelectionModel().select(tab);
+ viewManager.getTabPane().getSelectionModel().select(tab);
updateStatusLabel(textArea);
autoSave(textArea);
});
} catch (IOException ignored) {
-
+ LogUtil.info("已忽略IO异常!",this.getClass());
}
}
@@ -189,7 +197,7 @@ public class Controller implements ControllerInterface {
@Override
public void upDateEncodingLabel(String text) {
String encoding = EncodingDetector.detectEncoding(text);
- ViewManager.enCodingLabel.setText("\t编码: " + encoding);
+ ViewManager.getInstance().getEnCodingLabel().setText("\t编码: " + encoding);
}
/**
@@ -230,7 +238,7 @@ public class Controller implements ControllerInterface {
@Override
public void initTabPane() {
Controller controller = new Controller();
- ViewManager.tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> {
+ ViewManager.getInstance().getTabPane().getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> {
LineNumberTextArea textArea;
if (newTab != null) {
// 获取新选定的标签页并关联的文本区域
@@ -253,16 +261,17 @@ public class Controller implements ControllerInterface {
/**
* 更新UI和标签页
*
- * @param textArea 文本域
+ * @param textArea 文本域
* @apiNote
* @since 2023/8/20 12:40
*/
@Override
public void updateUiWithNewTextArea(LineNumberTextArea textArea) {
- Tab tab = new Tab("新建文件 " + (++ViewManager.tabIndex));
+ ViewManager viewManager = ViewManager.getInstance();
+ Tab tab = new Tab("新建文件 " + viewManager.selfIncreaseAndGetTabIndex());
tab.setContent(textArea);
- ViewManager.tabPane.getTabs().add(tab);
- ViewManager.tabPane.getSelectionModel().select(tab);
+ viewManager.getTabPane().getTabs().add(tab);
+ viewManager.getTabPane().getSelectionModel().select(tab);
updateStatusLabel(textArea);
}
diff --git a/src/main/java/org/jcnc/jnotepad/controller/manager/ShortcutKey.java b/src/main/java/org/jcnc/jnotepad/controller/manager/ShortcutKey.java
index d6a7874c20b55ddb5f5d75c09f350e152b4e3281..3228404932f9b367a9a0c793a40c5c5a0f6cefe2 100644
--- a/src/main/java/org/jcnc/jnotepad/controller/manager/ShortcutKey.java
+++ b/src/main/java/org/jcnc/jnotepad/controller/manager/ShortcutKey.java
@@ -6,44 +6,45 @@ import com.google.gson.reflect.TypeToken;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCombination;
import org.jcnc.jnotepad.Interface.ShortcutKeyInterface;
-import org.jcnc.jnotepad.tool.FileUtil;
+import org.jcnc.jnotepad.tool.LogUtil;
import org.jcnc.jnotepad.view.manager.ViewManager;
import java.io.*;
-import java.net.URL;
import java.util.Map;
import java.util.Objects;
+import static org.jcnc.jnotepad.constants.PathConstants.SHORTCUT_KEY_CONFIGURATION_FILE_PATH;
+
/**
- * @author 一个大转盘
- * @date 2023/8/18
+ * @author 一个大转盘
*/
public class ShortcutKey implements ShortcutKeyInterface {
@Override
public void createShortcutKeyByConfig() {
- String rootPath =System.getProperty("user.dir");
+ String rootPath = System.getProperty("user.dir");
// 构建JSON文件路径
- String jsonFilePath = rootPath +"/config/shortcutKey.json";
- InputStream inputStream = getClass().getResourceAsStream("/config/shortcutKey.json");
+ String jsonFilePath = rootPath + SHORTCUT_KEY_CONFIGURATION_FILE_PATH;
+ InputStream inputStream = getClass().getResourceAsStream(SHORTCUT_KEY_CONFIGURATION_FILE_PATH);
StringBuffer jsonData = new StringBuffer();
File file = new File(jsonFilePath);
- if(file.exists()){
+ if (file.exists()) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
jsonData.append(line);
}
} catch (IOException e) {
- e.printStackTrace();
+ LogUtil.error(e.getMessage(),e,this.getClass());
}
- }else {
+ } else {
+ // todo new InputStreamReader(inputStream) 实参 'inputStream' 可能为null
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
jsonData.append(line);
}
} catch (IOException e) {
- e.printStackTrace();
+ LogUtil.error(e.getMessage(),e,this.getClass());
}
}
@@ -54,16 +55,13 @@ public class ShortcutKey implements ShortcutKeyInterface {
}.getType());
for (Map.Entry stringObjectEntry : shortcutKeyConfig.entrySet()) {
// 保证json的key必须和变量名一致
- MenuItem menuItem = ViewManager.itemMap.get(stringObjectEntry.getKey());
+ MenuItem menuItem = ViewManager.getInstance().getItemMap().get(stringObjectEntry.getKey());
String shortKeyValue = stringObjectEntry.getValue();
-
if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) {
continue;
}
// 动态添加快捷键
menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue));
}
-
-
}
}
diff --git a/src/main/java/org/jcnc/jnotepad/exception/AppException.java b/src/main/java/org/jcnc/jnotepad/exception/AppException.java
new file mode 100644
index 0000000000000000000000000000000000000000..af597831786e511d6f6e0d9b48314208a612235c
--- /dev/null
+++ b/src/main/java/org/jcnc/jnotepad/exception/AppException.java
@@ -0,0 +1,14 @@
+package org.jcnc.jnotepad.exception;
+import org.jcnc.jnotepad.tool.LogUtil;
+
+/**
+ * 应用异常类
+ *
+ * @author gewuyou
+ */
+public class AppException extends RuntimeException{
+ public AppException(String message) {
+ super(message);
+ LogUtil.error(message,this.getClass());
+ }
+}
diff --git a/src/main/java/org/jcnc/jnotepad/init/Config.java b/src/main/java/org/jcnc/jnotepad/init/Config.java
index 8eb85bb38fe0c7ae9ad1fc679febf24bd6140d9d..fa5f3168499513d02c9cdd859c3f7642e81c9a9a 100644
--- a/src/main/java/org/jcnc/jnotepad/init/Config.java
+++ b/src/main/java/org/jcnc/jnotepad/init/Config.java
@@ -6,8 +6,11 @@ import org.jcnc.jnotepad.Interface.ConfigInterface;
import java.io.*;
import java.util.Properties;
-import static org.jcnc.jnotepad.constants.Constants.PROPERTY_FILE_NAME;
+import static org.jcnc.jnotepad.constants.AppConstants.PROPERTY_FILE_NAME;
+/**
+ * @author 许轲
+ */
public class Config implements ConfigInterface {
public Properties readPropertiesFromFile() {
Properties properties = new Properties();
diff --git a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
index 0bdd00cc8adc1197ac8d364ba22b39db1e702114..938af8ae4d7616380f6a83df3348185c5292c8e8 100644
--- a/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
+++ b/src/main/java/org/jcnc/jnotepad/tool/EncodingDetector.java
@@ -8,8 +8,12 @@ import java.nio.charset.StandardCharsets;
/**
* 编码检测工具类
+ *
+ * @author 许轲
*/
public class EncodingDetector {
+ private EncodingDetector() {
+ }
/**
* 检测 TextArea 中的文本编码
@@ -19,7 +23,6 @@ public class EncodingDetector {
*/
public static String detectEncoding(LineNumberTextArea textArea) {
String text = textArea.getMainTextArea().getText();
-
return detectEncoding(text);
}
@@ -33,7 +36,7 @@ public class EncodingDetector {
// 尝试常见的编码
for (Charset charset : commonCharsets()) {
if (isValidEncoding(text, charset)) {
- System.out.println("编码监测结果:" + isValidEncoding(text, charset));
+ LogUtil.info("编码监测结果:" + isValidEncoding(text, charset), EncodingDetector.class);
return charset.name();
}
}
diff --git a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java b/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java
index 752350f0f8eb2af5e9ae0de65a6fe7d2e6bbc097..9156a90c2eaacbb4fe1c91a768fc4a5faf46a049 100644
--- a/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java
+++ b/src/main/java/org/jcnc/jnotepad/tool/FileUtil.java
@@ -5,32 +5,32 @@ import java.nio.charset.StandardCharsets;
/**
* @author 一个大转盘
- * @date 2023/8/18
*/
public class FileUtil {
+ private FileUtil() {
+ }
/**
* 把一个文件中的内容读取成一个String字符串
- * @date 2023/8/18 0:54
- * @param jsonFile
+ *
+ * @param jsonFile json文件
* @return String
*/
- public static String getJsonStr(File jsonFile){
- String jsonStr = "";
- try {
- FileReader fileReader = new FileReader(jsonFile);
- Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8);
- int ch = 0;
+ 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);
}
- fileReader.close();
- reader.close();
jsonStr = sb.toString();
return jsonStr;
} catch (IOException e) {
- e.printStackTrace();
+ LogUtil.error(e.getMessage(),e,FileUtil.class);
return null;
}
}
diff --git a/src/main/java/org/jcnc/jnotepad/tool/LogUtil.java b/src/main/java/org/jcnc/jnotepad/tool/LogUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..163985524fed071de6d5066640892a01e0b57d36
--- /dev/null
+++ b/src/main/java/org/jcnc/jnotepad/tool/LogUtil.java
@@ -0,0 +1,79 @@
+package org.jcnc.jnotepad.tool;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 日志工具类
+ *
+ * @author gewuyou
+ */
+public class LogUtil {
+ private LogUtil() {
+ }
+
+ /**
+ * 日志信息打印
+ *
+ * @param message 日志信息
+ * @param currentClass 所要记录的类
+ *
+ * @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
+ */
+ public static void info(String message, Class> currentClass) {
+ Logger logger = LoggerFactory.getLogger(currentClass);
+ logger.info(message);
+ }
+ /**
+ * 日志排错信息打印
+ *
+ * @param message 日志信息
+ * @param currentClass 所要记录的类
+ *
+ * @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
+ */
+
+ public static void debug(String message, Class> currentClass) {
+ Logger logger = LoggerFactory.getLogger(currentClass);
+ logger.debug(message);
+ }
+ /**
+ * 日志警告信息打印
+ *
+ * @param message 日志信息
+ * @param currentClass 所要记录的类
+ *
+ * @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
+ */
+ public static void warn(String message, Class> currentClass) {
+ Logger logger = LoggerFactory.getLogger(currentClass);
+ logger.warn(message);
+ }
+ /**
+ * 日志错误信息打印
+ *
+ * @param message 日志信息
+ * @param currentClass 所要记录的类
+ *
+ * @apiNote 传入当前需要记录的类,方便知晓是哪个位置记录的日志
+ */
+ public static void error(String message, Class> currentClass) {
+ Logger logger = LoggerFactory.getLogger(currentClass);
+ logger.error(message);
+ }
+ /**
+ * 日志错误信息打印
+ *
+ * @param message 日志信息
+ * @param throwable 抛出的异常
+ * @param currentClass 所要记录的类
+ *
+ * @apiNote 这个方法用来弥补当抛出异常或手动抛出异常时,无法捕捉到所抛异常
+ */
+
+ public static void error(String message, Throwable throwable, Class> currentClass) {
+ Logger logger = LoggerFactory.getLogger(currentClass);
+ logger.error(message, throwable);
+ }
+}
+
diff --git a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
index b911ba136eea9da1d38ba2b99816557384345f1b..34a1a9754d758d7d99aab0f7fc84573f7e2d26bd 100644
--- a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
+++ b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
@@ -4,13 +4,14 @@ import javafx.beans.property.StringProperty;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
+/**
+ * @author 许轲
+ */
public class LineNumberTextArea extends BorderPane {
-
-
private final TextArea mainTextArea;
private final TextArea lineNumberArea;
- static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
+ static final int[] SIZE_TABLE = {9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE};
private static final int MIN_LINE_NUMBER_WIDTH = 30;
@@ -27,15 +28,10 @@ public class LineNumberTextArea extends BorderPane {
mainTextArea.textProperty().addListener((observable, oldValue, newValue) -> updateLineNumberArea());
// 当主要文本区域的垂直滚动位置发生变化时,使行号文本区域的滚动位置保持一致
- mainTextArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> {
- lineNumberArea.setScrollTop(mainTextArea.getScrollTop());
- });
+ mainTextArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> lineNumberArea.setScrollTop(mainTextArea.getScrollTop()));
// 当行号文本区域的垂直滚动位置发生变化时,使主要文本区域的滚动位置保持一致
- lineNumberArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> {
- mainTextArea.setScrollTop(lineNumberArea.getScrollTop());
- });
-
+ lineNumberArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> mainTextArea.setScrollTop(lineNumberArea.getScrollTop()));
setCenter(mainTextArea);
setLeft(lineNumberArea);
}
@@ -43,13 +39,13 @@ public class LineNumberTextArea extends BorderPane {
private void updateLineNumberWidth() {
int numOfLines = mainTextArea.getParagraphs().size();
int count = 1;
- for (int i = 0; i < sizeTable.length; i++) {
- if (numOfLines <= sizeTable[i]) {
+ for (int i = 0; i < SIZE_TABLE.length; i++) {
+ if (numOfLines <= SIZE_TABLE[i]) {
count = i + 1;
break;
}
}
- //单数字宽度10像素,4为padding=左3+右1
+ // 单数字宽度10像素,4为padding=左3+右1
int actualWidth = Math.max(count * 10 + 11, MIN_LINE_NUMBER_WIDTH);
if (actualWidth != lineNumberArea.getWidth()) {
lineNumberArea.setPrefWidth(actualWidth);
diff --git a/src/main/java/org/jcnc/jnotepad/view/init/View.java b/src/main/java/org/jcnc/jnotepad/view/init/View.java
index 4e99f634dece14296cdd9a49465116c827e53e29..258b0b2ca26cfce6d9adddacc74e40d623ee675e 100644
--- a/src/main/java/org/jcnc/jnotepad/view/init/View.java
+++ b/src/main/java/org/jcnc/jnotepad/view/init/View.java
@@ -2,28 +2,32 @@ package org.jcnc.jnotepad.view.init;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
-import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.controller.manager.Controller;
import org.jcnc.jnotepad.controller.manager.ShortcutKey;
+import org.jcnc.jnotepad.ui.LineNumberTextArea;
+import org.jcnc.jnotepad.view.manager.ViewManager;
import java.util.HashMap;
import java.util.Map;
-import static org.jcnc.jnotepad.view.manager.ViewManager.*;
-
+/**
+ * @author 许轲
+ */
public class View {
- private static Map itmeMap = new HashMap<>();
+ // todo 这个东西干嘛的,都没用过
+ private static Map itmeMap = new HashMap<>();
public void initItem() {
+ ViewManager viewManager = ViewManager.getInstance();
// 初始化菜单项的事件处理器
EventHandler newFileEventHandler = Controller.getInstance().getNewFileEventHandler(new LineNumberTextArea());
- newItem.setOnAction(newFileEventHandler);
+ viewManager.getNewItem().setOnAction(newFileEventHandler);
EventHandler openFileEventHandler = Controller.getInstance().getOpenFileEventHandler();
- openItem.setOnAction(openFileEventHandler);
+ viewManager.getOpenItem().setOnAction(openFileEventHandler);
EventHandler saveAsFileEventHandler = Controller.getInstance().getSaveAsFileEventHandler();
- saveAsItem.setOnAction(saveAsFileEventHandler);
- lineFeedItem.setOnAction(Controller.getInstance().getLineFeedEventHandler(new LineNumberTextArea()));
+ viewManager.getSaveAsItem().setOnAction(saveAsFileEventHandler);
+ viewManager.getLineFeedItem().setOnAction(Controller.getInstance().getLineFeedEventHandler(new LineNumberTextArea()));
}
public void initTabPane() {
@@ -31,7 +35,7 @@ public class View {
}
// 初始化快捷键
- public void initShortcutKey(){
+ public void initShortcutKey() {
new ShortcutKey().createShortcutKeyByConfig();
}
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 d479541c70f6d891fce43d5178cefcdcc8620c9d..0842809d35930dc47901206446b76d99ee166576 100644
--- a/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java
+++ b/src/main/java/org/jcnc/jnotepad/view/manager/ViewManager.java
@@ -5,42 +5,159 @@ import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
+import org.jcnc.jnotepad.exception.AppException;
import java.util.HashMap;
import java.util.Map;
-import java.util.Objects;
+
/**
* 该类管理记事本应用程序的视图组件。
+ *
+ * @author 许轲
*/
public class ViewManager {
- public static Label enCodingLabel; // 显示文本编码
+ /**
+ * 显示文本编码
+ */
+ private Label enCodingLabel; // 显示文本编码
- public static int tabIndex = 0;
+ private int tabIndex = 0;
- public static Boolean Line = true;
+ private Boolean line = true;
+ /// 菜单栏组件
+ /**
+ * 菜单栏
+ */
+ private MenuBar menuBar;
+ /**
+ * 文件菜单
+ */
+ private Menu fileMenu;
+ /**
+ * 插件菜单
+ */
+ private Menu setMenu;
+ /**
+ * 插件菜单
+ */
+ private Menu pluginMenu;
- // 菜单栏组件
- public static MenuBar menuBar; //菜单栏
- public static Menu fileMenu, setMenu, pluginMenu; //文件菜单//设置菜单//插件菜单 菜单
- public static MenuItem newItem, openItem, saveAsItem, addItem, countItem; //新建/打开/保存/保存至//增加//查看 菜单按钮
+ /// 菜单按钮
- public static CheckMenuItem lineFeedItem; //自动换行点击菜单按钮
- // 主界面布局
- public static BorderPane root; //主布局
+ /**
+ * 新建
+ */
+ private MenuItem newItem;
+ /**
+ * 打开
+ */
+ private MenuItem openItem;
+ /**
+ * 保存
+ */
+ private MenuItem saveAsItem;
+ /**
+ * 增加
+ */
+ private MenuItem addItem;
+ /**
+ * 查看
+ */
+ private MenuItem countItem;
+ private CheckMenuItem lineFeedItem; // 自动换行点击菜单按钮
+ // 主界面布局
+ private BorderPane root; // 主布局
// 多个标签页
- public static TabPane tabPane; //标签页栏
+ private TabPane tabPane; // 标签页栏
// 状态栏
- public static Label statusLabel;
+ private Label statusLabel;
private static ViewManager instance = null;
- public static Map itemMap = new HashMap<>();
+ private Map itemMap = new HashMap<>();
+
+
+ public Label getEnCodingLabel() {
+ return enCodingLabel;
+ }
+ /**
+ * 自增并获取标签页索引
+ *
+ *
+ * @return int 标签页索引
+ * @apiNote ++tabIndex
+ */
+
+ public int selfIncreaseAndGetTabIndex() {
+ return ++tabIndex;
+ }
+
+ public Boolean getLine() {
+ return line;
+ }
+
+ public MenuBar getMenuBar() {
+ return menuBar;
+ }
+
+ public Menu getFileMenu() {
+ return fileMenu;
+ }
+
+ public Menu getSetMenu() {
+ return setMenu;
+ }
+
+ public Menu getPluginMenu() {
+ return pluginMenu;
+ }
+
+ public MenuItem getNewItem() {
+ return newItem;
+ }
+
+ public MenuItem getOpenItem() {
+ return openItem;
+ }
+
+ public MenuItem getSaveAsItem() {
+ return saveAsItem;
+ }
+
+ public MenuItem getAddItem() {
+ return addItem;
+ }
+
+ public MenuItem getCountItem() {
+ return countItem;
+ }
+
+ public CheckMenuItem getLineFeedItem() {
+ return lineFeedItem;
+ }
+
+ public BorderPane getRoot() {
+ return root;
+ }
+
+ public TabPane getTabPane() {
+ return tabPane;
+ }
+
+ public Label getStatusLabel() {
+ return statusLabel;
+ }
+
+ public Map getItemMap() {
+ return itemMap;
+ }
+
/**
* 获取ViewManager的实例。如果实例不存在,则创建一个新实例。
@@ -49,13 +166,20 @@ public class ViewManager {
* @return ViewManager的实例。
*/
public static ViewManager getInstance(Scene scene) {
-
if (instance == null) {
instance = new ViewManager(scene);
}
return instance;
}
+ public static ViewManager getInstance() {
+ if (instance != null) {
+ return instance;
+ } else {
+ throw new AppException("ViewManager实例未初始化!");
+ }
+ }
+
/**
* 构造函数。设置场景和根布局。
*
@@ -63,10 +187,7 @@ public class ViewManager {
*/
private ViewManager(Scene scene) {
root = new BorderPane();
-
-
scene.setRoot(root);
-
}
/**
@@ -78,7 +199,7 @@ public class ViewManager {
// 创建菜单栏并添加菜单项
menuBar = new MenuBar();
- //文件菜单
+ // 文件菜单
fileMenu = new Menu("文件");
newItem = new MenuItem("新建");
@@ -92,7 +213,7 @@ public class ViewManager {
fileMenu.getItems().addAll(newItem, openItem, saveAsItem);
- //设置菜单
+ // 设置菜单
setMenu = new Menu("设置");
lineFeedItem = new CheckMenuItem("自动换行");
@@ -101,7 +222,7 @@ public class ViewManager {
setMenu.getItems().addAll(lineFeedItem);
- //插件菜单
+ // 插件菜单
pluginMenu = new Menu("插件");
addItem = new MenuItem("增加插件");
itemMap.put("addItem", addItem);
@@ -111,7 +232,7 @@ public class ViewManager {
pluginMenu.getItems().addAll(addItem, countItem);
- //菜单栏
+ // 菜单栏
menuBar.getMenus().addAll(fileMenu, setMenu, pluginMenu);
// 创建主界面布局
@@ -131,8 +252,5 @@ public class ViewManager {
BorderPane.setMargin(statusBox, new Insets(5, 10, 5, 10));
scene.setRoot(root);
-
-
-
}
}
diff --git a/src/main/resources/img/icon.svg b/src/main/resources/img/icon.svg
index 6d9d5340a238f7548898a8a249ae454542e057b4..794655025eece2abeb583e0a285c3bc38bade7ca 100644
--- a/src/main/resources/img/icon.svg
+++ b/src/main/resources/img/icon.svg
@@ -1,7 +1,8 @@
-