commit
c4b998100e
7
pom.xml
7
pom.xml
@ -32,10 +32,11 @@
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--Json依赖-->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.7.1</version>
|
||||
</dependency>
|
||||
<!--log-->
|
||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
|
||||
|
||||
@ -5,12 +5,15 @@ module org.jcnc.jnotepad {
|
||||
// 但我打开源代码,他们的模块的确有包含这个,java.naming,这个没懂,我干脆自己导入
|
||||
requires java.naming;
|
||||
requires atlantafx.base;
|
||||
requires com.google.gson;
|
||||
requires com.fasterxml.jackson.core;
|
||||
requires com.fasterxml.jackson.databind;
|
||||
requires com.fasterxml.jackson.annotation;
|
||||
requires org.slf4j;
|
||||
requires ch.qos.logback.core;
|
||||
requires ch.qos.logback.classic;
|
||||
requires com.ibm.icu;
|
||||
|
||||
exports org.jcnc.jnotepad.app.config;
|
||||
exports org.jcnc.jnotepad;
|
||||
exports org.jcnc.jnotepad.tool;
|
||||
exports org.jcnc.jnotepad.Interface;
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
package org.jcnc.jnotepad.Interface;
|
||||
|
||||
/**
|
||||
* @author 一个大转盘
|
||||
*/
|
||||
public interface ShortcutKeyInterface {
|
||||
void createShortcutKeyByConfig();
|
||||
|
||||
}
|
||||
@ -7,6 +7,7 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import org.jcnc.jnotepad.app.config.LoadShortcutKeyConfig;
|
||||
import org.jcnc.jnotepad.constants.AppConstants;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
import org.jcnc.jnotepad.init.Config;
|
||||
@ -33,28 +34,22 @@ public class LunchApp extends Application {
|
||||
|
||||
Controller controller = Controller.getInstance();
|
||||
Scene scene;
|
||||
View view;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
|
||||
Config config = new Config();
|
||||
|
||||
Properties properties = config.readPropertiesFromFile();
|
||||
String title = properties.getProperty("title", "JNotepad");
|
||||
|
||||
|
||||
view = new View();
|
||||
|
||||
Pane root = new Pane();
|
||||
|
||||
|
||||
double width = AppConstants.SCREEN_WIDTH;
|
||||
double length = AppConstants.SCREEN_LENGTH;
|
||||
String icon = AppConstants.APP_ICON;
|
||||
|
||||
|
||||
|
||||
scene = new Scene(root, width, length);
|
||||
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
||||
scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/styles.css")).toExternalForm());
|
||||
@ -76,9 +71,7 @@ public class LunchApp extends Application {
|
||||
ViewManager viewManager = ViewManager.getInstance(scene);
|
||||
viewManager.initScreen(scene);
|
||||
// 初始化快捷键
|
||||
view.initShortcutKey();
|
||||
|
||||
|
||||
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
|
||||
import org.jcnc.jnotepad.app.entity.ShortcutKey;
|
||||
import org.jcnc.jnotepad.app.entity.Style;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 应用程序配置类
|
||||
*
|
||||
* @author gewuyou 一个大转盘
|
||||
* @see [相关类/方法]
|
||||
*/
|
||||
public class JnotepadConfig {
|
||||
/**
|
||||
* 快捷键列表
|
||||
*/
|
||||
private List<ShortcutKey> shortcutKeyList;
|
||||
|
||||
/**
|
||||
* 样式列表 TODO
|
||||
*/
|
||||
private List<Style> styleList;
|
||||
|
||||
/**
|
||||
* 单例模式
|
||||
*/
|
||||
private JnotepadConfig() {
|
||||
}
|
||||
|
||||
private static final JnotepadConfig INSTANCE = new JnotepadConfig();
|
||||
|
||||
public static JnotepadConfig getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<ShortcutKey> getShortcutKeyList() {
|
||||
return shortcutKeyList;
|
||||
}
|
||||
|
||||
public void setShortcutKeyList(List<ShortcutKey> shortcutKeyList) {
|
||||
this.shortcutKeyList = shortcutKeyList;
|
||||
}
|
||||
|
||||
public List<Style> getStyleList() {
|
||||
return styleList;
|
||||
}
|
||||
|
||||
public void setStyleList(List<Style> styleList) {
|
||||
this.styleList = styleList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import org.jcnc.jnotepad.app.entity.ShortcutKey;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.tool.PopUpUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME;
|
||||
import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG;
|
||||
|
||||
/**
|
||||
* 加载应用配置类
|
||||
* <br/>空出了加载文件的具体实现
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public abstract class LoadJnotepadConfig {
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
public final void load() {
|
||||
// 判断是否存在这个配置文件
|
||||
try (InputStream inputStream = new FileInputStream(CONFIG_NAME)) {
|
||||
logger.info("正在加载配置文件...");
|
||||
// 存在则加载
|
||||
loadConfig(inputStream);
|
||||
} catch (IOException e) {
|
||||
logger.info("未检测到配置文件!");
|
||||
// 不存在则创建
|
||||
createConfig();
|
||||
}
|
||||
}
|
||||
|
||||
void createConfig() {
|
||||
List<ShortcutKey> shortcutKeyList = getShortcutKeys();
|
||||
JnotepadConfig.getInstance().setShortcutKeyList(shortcutKeyList);
|
||||
for (ShortcutKey shortcutKey : shortcutKeyList) {
|
||||
// 保证json的key必须和变量名一致
|
||||
MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.getButtonName());
|
||||
String shortKeyValue = shortcutKey.getShortcutKeyValue();
|
||||
if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) {
|
||||
continue;
|
||||
}
|
||||
// 动态添加快捷键
|
||||
menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue));
|
||||
}
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(CONFIG_NAME))) {
|
||||
writer.write(JNOTEPAD_CONFIG);
|
||||
} catch (IOException e) {
|
||||
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快捷键集合
|
||||
*
|
||||
* @return java.util.List<org.jcnc.jnotepad.app.entity.ShortcutKey> 快捷键集合
|
||||
* @since 2023/8/24 14:19
|
||||
*/
|
||||
private static List<ShortcutKey> getShortcutKeys() {
|
||||
List<ShortcutKey> shortcutKeyList = new ArrayList<>();
|
||||
// 打开文件
|
||||
ShortcutKey shortcutKeyOfOpen = new ShortcutKey("openItem", "ctrl+o");
|
||||
|
||||
// 新建
|
||||
ShortcutKey shortcutKeyOfNew = new ShortcutKey("newItem", "ctrl+n");
|
||||
|
||||
// 保存
|
||||
ShortcutKey shortcutKeyOfSave = new ShortcutKey("saveItem", "ctrl+s");
|
||||
|
||||
// 保存作为
|
||||
ShortcutKey shortcutKeyOfSaveAs = new ShortcutKey("saveAsItem", "ctrl+shift+s");
|
||||
|
||||
// 打开配置文件
|
||||
ShortcutKey shortcutKeyOfOpenConfig = new ShortcutKey("openConfigItem", "alt+s");
|
||||
|
||||
shortcutKeyList.add(shortcutKeyOfOpen);
|
||||
shortcutKeyList.add(shortcutKeyOfNew);
|
||||
shortcutKeyList.add(shortcutKeyOfSave);
|
||||
shortcutKeyList.add(shortcutKeyOfSaveAs);
|
||||
shortcutKeyList.add(shortcutKeyOfOpenConfig);
|
||||
return shortcutKeyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载配置文件
|
||||
*
|
||||
* @param inputStream 配置文件的输入流
|
||||
*/
|
||||
protected abstract void loadConfig(InputStream inputStream);
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package org.jcnc.jnotepad.app.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
import org.jcnc.jnotepad.tool.PopUpUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_SHORTCUT_KEY_NAME;
|
||||
|
||||
/**
|
||||
* 加载快捷键实现
|
||||
*
|
||||
* @author gewuyou 一个大转盘
|
||||
*/
|
||||
public class LoadShortcutKeyConfig extends LoadJnotepadConfig {
|
||||
Logger log = LogUtil.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void loadConfig(InputStream inputStream) {
|
||||
StringBuffer jsonData = new StringBuffer();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
PopUpUtil.errorAlert("错误", "读写错误", "配置文件读写错误!");
|
||||
}
|
||||
// 转json对象
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, List<Object>> mainConfig = null;
|
||||
try {
|
||||
mainConfig = mapper.readValue(jsonData.toString(), new TypeReference<HashMap<String, List<Object>>>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
PopUpUtil.errorAlert("错误", "解析错误", "配置文件解析错误!");
|
||||
log.error("配置文件解析错误!", e);
|
||||
}
|
||||
if (mainConfig == null) {
|
||||
log.error("未获取到主要配置文件!");
|
||||
return;
|
||||
}
|
||||
List<LinkedHashMap<String, String>> objectList = mainConfig.get(CONFIG_SHORTCUT_KEY_NAME)
|
||||
.stream()
|
||||
.map(e -> {
|
||||
if (e instanceof LinkedHashMap) {
|
||||
return (LinkedHashMap<String, String>) e;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid element type");
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
|
||||
for (LinkedHashMap<String, String> shortcutKey : objectList) {
|
||||
// 保证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));
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/main/java/org/jcnc/jnotepad/app/entity/ShortcutKey.java
Normal file
35
src/main/java/org/jcnc/jnotepad/app/entity/ShortcutKey.java
Normal file
@ -0,0 +1,35 @@
|
||||
package org.jcnc.jnotepad.app.entity;
|
||||
|
||||
/**
|
||||
* 快捷键
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class ShortcutKey {
|
||||
private String buttonName;
|
||||
private String shortcutKeyValue;
|
||||
|
||||
public ShortcutKey() {
|
||||
}
|
||||
|
||||
public ShortcutKey(String buttonName, String shortcutKeyValue) {
|
||||
this.buttonName = buttonName;
|
||||
this.shortcutKeyValue = 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;
|
||||
}
|
||||
}
|
||||
35
src/main/java/org/jcnc/jnotepad/app/entity/Style.java
Normal file
35
src/main/java/org/jcnc/jnotepad/app/entity/Style.java
Normal file
@ -0,0 +1,35 @@
|
||||
package org.jcnc.jnotepad.app.entity;
|
||||
|
||||
/**
|
||||
* 样式
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class Style {
|
||||
private String styleName;
|
||||
private String styleValue;
|
||||
|
||||
public Style() {
|
||||
}
|
||||
|
||||
public Style(String styleName, String styleValue) {
|
||||
this.styleName = styleName;
|
||||
this.styleValue = styleValue;
|
||||
}
|
||||
|
||||
public String getStyleName() {
|
||||
return styleName;
|
||||
}
|
||||
|
||||
public void setStyleName(String styleName) {
|
||||
this.styleName = styleName;
|
||||
}
|
||||
|
||||
public String getStyleValue() {
|
||||
return styleValue;
|
||||
}
|
||||
|
||||
public void setStyleValue(String styleValue) {
|
||||
this.styleValue = styleValue;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package org.jcnc.jnotepad.constants;
|
||||
|
||||
/**
|
||||
* 应用常量
|
||||
*
|
||||
* @author 许轲
|
||||
*/
|
||||
|
||||
@ -27,9 +28,21 @@ public class AppConstants {
|
||||
public static final String APP_ICON = "/img/icon.png";
|
||||
|
||||
/**
|
||||
* 配置文件名
|
||||
* 中文语言包
|
||||
*/
|
||||
public static final String CH_LANGUAGE_PACK_NAME = "ch_language_pack.txt";
|
||||
|
||||
/**
|
||||
* 英文语言包
|
||||
*/
|
||||
public static final String EN_LANGUAGE_PACK_NAME = "en_language_pack.txt";
|
||||
|
||||
/**
|
||||
* 配置文件名
|
||||
*/
|
||||
public static final String CONFIG_NAME = "jnotepadConfig.json";
|
||||
/**
|
||||
* 快捷键
|
||||
*/
|
||||
public static final String CONFIG_SHORTCUT_KEY_NAME = "shortcutKey";
|
||||
|
||||
}
|
||||
|
||||
@ -10,8 +10,7 @@ public class PathConstants {
|
||||
}
|
||||
|
||||
/**
|
||||
* 快捷键配置文件路径
|
||||
* todo:这里这个配置应当可以通过配置文件读取
|
||||
* 配置文件路径
|
||||
*/
|
||||
public static final String SHORTCUT_KEY_CONFIGURATION_FILE_PATH = "/config/shortcutKey.json";
|
||||
public static final String CONFIGURATION_FILE_PATH = "../config/";
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ public class TextConstants {
|
||||
|
||||
public static final String STATISTICS = PROPERTIES.getProperty("STATISTICS");
|
||||
|
||||
public static final String OPEN_CONFIGURATION_FILE = PROPERTIES.getProperty("OPEN_CONFIGURATION_FILE");
|
||||
|
||||
/// GlobalConfig文本常量
|
||||
/**
|
||||
* 自动换行配置key
|
||||
@ -64,4 +66,48 @@ public class TextConstants {
|
||||
public static final String WORD_COUNT = PROPERTIES.getProperty("WORD_COUNT");
|
||||
|
||||
public static final String ENCODE = PROPERTIES.getProperty("ENCODE");
|
||||
|
||||
/// 配置文件文本常量
|
||||
/**
|
||||
* 内置配置文件
|
||||
*/
|
||||
public static final String JNOTEPAD_CONFIG =
|
||||
"""
|
||||
{
|
||||
"shortcutKey":[
|
||||
{
|
||||
"buttonName": "newItem",
|
||||
"shortcutKeyValue": "ctrl+n"
|
||||
},
|
||||
{
|
||||
"buttonName": "openItem",
|
||||
"shortcutKeyValue": "ctrl+o"
|
||||
},
|
||||
{
|
||||
"buttonName": "saveItem",
|
||||
"shortcutKeyValue": "ctrl+s"
|
||||
},
|
||||
{
|
||||
"buttonName": "saveAsItem",
|
||||
"shortcutKeyValue": "ctrl+alt+s"
|
||||
},
|
||||
{
|
||||
"buttonName": "lineFeedItem",
|
||||
"shortcutKeyValue": ""
|
||||
},
|
||||
{
|
||||
"buttonName": "openConfigItem",
|
||||
"shortcutKeyValue": "alt+s"
|
||||
},
|
||||
{
|
||||
"buttonName": "addItem",
|
||||
"shortcutKeyValue": ""
|
||||
},
|
||||
{
|
||||
"buttonName": "countItem",
|
||||
"shortcutKeyValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package org.jcnc.jnotepad.controller.event.handler;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
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;
|
||||
@ -35,7 +34,6 @@ public class NewFile implements EventHandler<ActionEvent> {
|
||||
|
||||
// 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(),
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package org.jcnc.jnotepad.controller.event.handler;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
import org.jcnc.jnotepad.tool.LogUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME;
|
||||
|
||||
/**
|
||||
* 打开配置文件事件
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class OpenConfig extends OpenHandler {
|
||||
@Override
|
||||
public void handle(ActionEvent actionEvent) {
|
||||
// 获取控制器
|
||||
Controller controller = Controller.getInstance();
|
||||
// 显示文件选择对话框,并获取选中的文件
|
||||
File file = new File(CONFIG_NAME);
|
||||
LogUtil.getLogger(this.getClass()).info("已调用打开配置文件功能");
|
||||
// 创建打开文件的任务
|
||||
Task<Void> openFileTask = getVoidTask(controller, file);
|
||||
// 创建并启动线程执行任务
|
||||
Thread thread = new Thread(openFileTask);
|
||||
thread.start();
|
||||
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,6 @@ 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.controller.manager.Controller;
|
||||
|
||||
@ -16,7 +15,7 @@ import java.io.File;
|
||||
*
|
||||
* @author 许轲
|
||||
*/
|
||||
public class OpenFile implements EventHandler<ActionEvent> {
|
||||
public class OpenFile extends OpenHandler {
|
||||
/**
|
||||
* 处理打开文件事件。
|
||||
*
|
||||
@ -38,34 +37,4 @@ public class OpenFile implements EventHandler<ActionEvent> {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取空返回值任务
|
||||
*
|
||||
* @param controller 控制器
|
||||
* @param file 文件
|
||||
* @return javafx.concurrent.Task<java.lang.Void>
|
||||
* @apiNote
|
||||
*/
|
||||
private static Task<Void> getVoidTask(Controller controller, File file) {
|
||||
Task<Void> openFileTask = new Task<>() {
|
||||
@Override
|
||||
protected Void call() {
|
||||
// 调用控制器的getText方法,读取文件内容
|
||||
controller.getText(file);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 设置任务成功完成时的处理逻辑
|
||||
openFileTask.setOnSucceeded(e -> {
|
||||
// 处理成功的逻辑
|
||||
});
|
||||
|
||||
// 设置任务失败时的处理逻辑
|
||||
openFileTask.setOnFailed(e -> {
|
||||
// 处理失败的逻辑
|
||||
});
|
||||
return openFileTask;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package org.jcnc.jnotepad.controller.event.handler;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 打开抽象类
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public abstract class OpenHandler implements EventHandler<ActionEvent> {
|
||||
/**
|
||||
* 获取空返回值任务
|
||||
*
|
||||
* @param controller 控制器
|
||||
* @param file 文件
|
||||
* @return javafx.concurrent.Task<java.lang.Void>
|
||||
* @apiNote
|
||||
*/
|
||||
protected Task<Void> getVoidTask(Controller controller, File file) {
|
||||
Task<Void> openFileTask = new Task<>() {
|
||||
@Override
|
||||
protected Void call() {
|
||||
// 调用控制器的getText方法,读取文件内容
|
||||
controller.getText(file);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 设置任务成功完成时的处理逻辑
|
||||
openFileTask.setOnSucceeded(e -> {
|
||||
// 处理成功的逻辑
|
||||
});
|
||||
|
||||
// 设置任务失败时的处理逻辑
|
||||
openFileTask.setOnFailed(e -> {
|
||||
// 处理失败的逻辑
|
||||
});
|
||||
return openFileTask;
|
||||
}
|
||||
}
|
||||
@ -2,12 +2,15 @@ package org.jcnc.jnotepad.controller.event.handler;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import org.jcnc.jnotepad.app.config.LoadShortcutKeyConfig;
|
||||
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.init.View;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME;
|
||||
import static org.jcnc.jnotepad.tool.FileUtil.saveTab;
|
||||
|
||||
/**
|
||||
@ -41,6 +44,12 @@ public class SaveFile implements EventHandler<ActionEvent> {
|
||||
logger.info("当前保存文件为关联打开文件,调用自动保存方法");
|
||||
// 调用tab保存
|
||||
selectedTab.save();
|
||||
// 如果该文件是配置文件则刷新快捷键
|
||||
if (CONFIG_NAME.equals(selectedTab.getText())) {
|
||||
// 初始化快捷键
|
||||
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
|
||||
logger.info("已刷新快捷键!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
package org.jcnc.jnotepad.controller.manager;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
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.LogUtil;
|
||||
import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.jcnc.jnotepad.constants.PathConstants.SHORTCUT_KEY_CONFIGURATION_FILE_PATH;
|
||||
|
||||
/**
|
||||
* @author 一个大转盘<br>
|
||||
*/
|
||||
public class ShortcutKey implements ShortcutKeyInterface {
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 按配置创建快捷键
|
||||
*
|
||||
* @apiNote 此方法通过配置json文件初始化快捷键
|
||||
* @since 2023/8/23 21:56
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void createShortcutKeyByConfig() {
|
||||
String jsonData = getJsonPathDataBasedOnJson();
|
||||
// 转json对象
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
Gson gson = gsonBuilder.create();
|
||||
Map<String, String> shortcutKeyConfig = gson.fromJson(jsonData, new TypeToken<Map<String, String>>() {
|
||||
}.getType());
|
||||
for (Map.Entry<String, String> stringObjectEntry : shortcutKeyConfig.entrySet()) {
|
||||
// 保证json的key必须和变量名一致
|
||||
MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(stringObjectEntry.getKey());
|
||||
String shortKeyValue = stringObjectEntry.getValue();
|
||||
if ("".equals(shortKeyValue) || Objects.isNull(menuItem)) {
|
||||
continue;
|
||||
}
|
||||
logger.info("快捷键对象:{}->已分配快捷键:{}", menuItem.getText(), shortKeyValue);
|
||||
// 动态添加快捷键
|
||||
menuItem.setAccelerator(KeyCombination.keyCombination(shortKeyValue));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据json路径返回解析的Json数据
|
||||
*
|
||||
* @return java.lang.String Json数据
|
||||
*/
|
||||
private String getJsonPathDataBasedOnJson() {
|
||||
String rootPath = System.getProperty("user.dir");
|
||||
// 构建JSON文件路径
|
||||
String jsonFilePath = rootPath + SHORTCUT_KEY_CONFIGURATION_FILE_PATH;
|
||||
StringBuilder jsonData = new StringBuilder();
|
||||
InputStream inputStream = getClass().getResourceAsStream(SHORTCUT_KEY_CONFIGURATION_FILE_PATH);
|
||||
File file = new File(jsonFilePath);
|
||||
if (file.exists()) {
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("读取配置失败!", e);
|
||||
}
|
||||
} else {
|
||||
if (inputStream != null) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonData.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("读取配置失败!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsonData.toString();
|
||||
}
|
||||
}
|
||||
@ -80,6 +80,7 @@ public class Config {
|
||||
properties.setProperty("SAVA_AS", "另存为");
|
||||
properties.setProperty("SET", "设置");
|
||||
properties.setProperty("WORD_WRAP", "自动换行");
|
||||
properties.setProperty("OPEN_CONFIGURATION_FILE", "打开配置文件");
|
||||
properties.setProperty("PLUGIN", "插件");
|
||||
properties.setProperty("ADD_PLUGIN", "增加插件");
|
||||
properties.setProperty("STATISTICS", "统计字数");
|
||||
@ -102,6 +103,7 @@ public class Config {
|
||||
properties.setProperty("SAVA_AS", "Save As");
|
||||
properties.setProperty("SET", "Settings");
|
||||
properties.setProperty("WORD_WRAP", "Word Wrap");
|
||||
properties.setProperty("OPEN_CONFIGURATION_FILE", "Open Configuration File");
|
||||
properties.setProperty("PLUGIN", "Plugins");
|
||||
properties.setProperty("ADD_PLUGIN", "Add Plugin");
|
||||
properties.setProperty("STATISTICS", "Word Count");
|
||||
|
||||
32
src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java
Normal file
32
src/main/java/org/jcnc/jnotepad/tool/PopUpUtil.java
Normal file
@ -0,0 +1,32 @@
|
||||
package org.jcnc.jnotepad.tool;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
|
||||
/**
|
||||
* 弹窗工具类
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class PopUpUtil {
|
||||
|
||||
private static final ThreadLocal<Alert> ERROR_ALERTS = ThreadLocal.withInitial(() -> new Alert(Alert.AlertType.ERROR));
|
||||
|
||||
private PopUpUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误弹窗
|
||||
*
|
||||
* @param title 弹窗标题
|
||||
* @param headerText 头文本
|
||||
* @param message 信息
|
||||
*/
|
||||
public static void errorAlert(String title, String headerText, String message) {
|
||||
Alert alert = ERROR_ALERTS.get();
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(headerText);
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
ERROR_ALERTS.remove();
|
||||
}
|
||||
}
|
||||
@ -5,10 +5,7 @@ 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.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.controller.event.handler.*;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
|
||||
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
|
||||
|
||||
@ -75,13 +72,16 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
* 查看
|
||||
*/
|
||||
private MenuItem countItem;
|
||||
|
||||
|
||||
/**
|
||||
* 打开配置文件
|
||||
*/
|
||||
private MenuItem openConfigItem;
|
||||
/**
|
||||
* 自动换行点击菜单按钮
|
||||
*/
|
||||
private CheckMenuItem lineFeedItem;
|
||||
|
||||
|
||||
private final Map<String, MenuItem> itemMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
@ -128,8 +128,9 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
lineFeedItem = new CheckMenuItem(WORD_WRAP);
|
||||
itemMap.put("lineFeedItem", lineFeedItem);
|
||||
lineFeedItem.selectedProperty().set(true);
|
||||
|
||||
setMenu.getItems().addAll(lineFeedItem);
|
||||
openConfigItem = new MenuItem(OPEN_CONFIGURATION_FILE);
|
||||
itemMap.put("openConfigItem", openConfigItem);
|
||||
setMenu.getItems().addAll(lineFeedItem, openConfigItem);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,6 +160,7 @@ public class JNotepadMenuBar extends MenuBar {
|
||||
openItem.setOnAction(new OpenFile());
|
||||
saveItem.setOnAction(new SaveFile());
|
||||
saveAsItem.setOnAction(new SaveAsFile());
|
||||
openConfigItem.setOnAction(new OpenConfig());
|
||||
lineFeedItem.selectedProperty().addListener((observableValue, before, after) -> {
|
||||
// 1. 更新全局配置
|
||||
GlobalConfig.getConfig().setAutoLineConfig(after);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package org.jcnc.jnotepad.view.init;
|
||||
|
||||
import org.jcnc.jnotepad.controller.manager.ShortcutKey;
|
||||
import org.jcnc.jnotepad.app.config.LoadJnotepadConfig;
|
||||
|
||||
|
||||
/**
|
||||
@ -8,9 +8,21 @@ import org.jcnc.jnotepad.controller.manager.ShortcutKey;
|
||||
*/
|
||||
public class View {
|
||||
|
||||
// 初始化快捷键
|
||||
public void initShortcutKey() {
|
||||
new ShortcutKey().createShortcutKeyByConfig();
|
||||
private View() {
|
||||
}
|
||||
|
||||
private static final View INSTANCE = new View();
|
||||
|
||||
/**
|
||||
* 初始化快捷键
|
||||
*
|
||||
* @param loadJnotepadConfig 加载配置文件
|
||||
* @since 2023/8/24 15:29
|
||||
*/
|
||||
public void initShortcutKey(LoadJnotepadConfig loadJnotepadConfig) {
|
||||
loadJnotepadConfig.load();
|
||||
}
|
||||
public static View getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
{
|
||||
"newItem": "ctrl+n",
|
||||
"openItem": "ctrl+o",
|
||||
"saveItem": "ctrl+s",
|
||||
"saveAsItem": "ctrl+alt+s",
|
||||
"lineFeedItem": "",
|
||||
|
||||
"addItem": "",
|
||||
"countItem": ""
|
||||
}
|
||||
@ -9,9 +9,9 @@
|
||||
<!-- 文件保留时间 -->
|
||||
<property name="log.maxHistory" value="30"/>
|
||||
<!-- 日志存储路径 -->
|
||||
<!--<property name="log.filePath" value="logs"/>-->
|
||||
<property name="log.filePath" value="logs"/>
|
||||
<!--打包时,请使用下方的路径-->
|
||||
<property name="log.filePath" value="../logs"/>
|
||||
<!--<property name="log.filePath" value="../logs"/>-->
|
||||
<!-- 日志的显式格式 -->
|
||||
<property name="log.pattern"
|
||||
value="时间:[%d{yyyy-MM-dd HH:mm:ss.SSS}] 线程:[%thread] 日志级别:[%-5level] 调用位置:[%logger{50} 参见:[\(%F:%L\)]] - 日志信息:[%msg]%n">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user