添加置顶功能

This commit is contained in:
gewuyou 2023-08-25 16:18:26 +08:00
parent 3daba03cbb
commit fbc1d020d9
13 changed files with 226 additions and 89 deletions

2
.gitignore vendored
View File

@ -2,7 +2,7 @@ target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
test/
### IntelliJ IDEA ###
.idea/
*.iws

View File

@ -12,7 +12,7 @@ module org.jcnc.jnotepad {
requires ch.qos.logback.core;
requires ch.qos.logback.classic;
requires com.ibm.icu;
exports org.jcnc.jnotepad.init;
exports org.jcnc.jnotepad.app.config;
exports org.jcnc.jnotepad;
exports org.jcnc.jnotepad.tool;

View File

@ -7,20 +7,23 @@ import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import org.jcnc.jnotepad.app.config.LoadJnotepadConfig;
import org.jcnc.jnotepad.app.config.LoadLanguageConfig;
import org.jcnc.jnotepad.app.config.LoadShortcutKeyConfig;
import org.jcnc.jnotepad.constants.AppConstants;
import org.jcnc.jnotepad.controller.manager.Controller;
import org.jcnc.jnotepad.init.Config;
import org.jcnc.jnotepad.ui.LineNumberTextArea;
import org.jcnc.jnotepad.view.init.View;
import org.jcnc.jnotepad.view.manager.ViewManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.jcnc.jnotepad.constants.TextConstants.TITLE;
/**
* 启动程序
*
@ -34,22 +37,26 @@ public class LunchApp extends Application {
Controller controller = Controller.getInstance();
Scene scene;
/**
* 配置文件数组
*/
static List<LoadJnotepadConfig> loadJnotepadConfigs = new ArrayList<>();
static {
// 快捷键配置文件
loadJnotepadConfigs.add(new LoadShortcutKeyConfig());
// 语言配置文件
loadJnotepadConfigs.add(new LoadLanguageConfig());
}
@Override
public void start(Stage primaryStage) {
Config config = new Config();
Properties properties = config.readPropertiesFromFile();
String title = properties.getProperty("title", "JNotepad");
Pane root = new Pane();
double width = AppConstants.SCREEN_WIDTH;
double length = AppConstants.SCREEN_LENGTH;
String icon = AppConstants.APP_ICON;
scene = new Scene(root, width, length);
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/styles.css")).toExternalForm());
@ -62,7 +69,7 @@ public class LunchApp extends Application {
Platform.runLater(() -> controller.updateUiWithNewTextArea(textArea));
}
});
primaryStage.setTitle(title);
primaryStage.setTitle(TITLE);
primaryStage.setWidth(width);
primaryStage.setHeight(length);
primaryStage.setScene(scene);
@ -71,7 +78,7 @@ public class LunchApp extends Application {
ViewManager viewManager = ViewManager.getInstance(scene);
viewManager.initScreen(scene);
// 初始化快捷键
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
View.getInstance().initJnotepadConfigs(loadJnotepadConfigs);
}
@Override

View File

@ -1,9 +1,6 @@
package org.jcnc.jnotepad.app.config;
import org.jcnc.jnotepad.init.Config;
import java.util.Properties;
import static org.jcnc.jnotepad.constants.TextConstants.PROPERTIES;
import static org.jcnc.jnotepad.constants.TextConstants.TEXT_WRAP;
/**
@ -14,10 +11,8 @@ import static org.jcnc.jnotepad.constants.TextConstants.TEXT_WRAP;
public class GlobalConfig {
private static final GlobalConfig APP_GLOBAL_CONFIG = new GlobalConfig();
private final Properties properties;
private GlobalConfig() {
properties = new Config().readPropertiesFromFile();
}
/**
@ -26,12 +21,12 @@ public class GlobalConfig {
* @return true, 自动换行false不自动换行
*/
public boolean getAutoLineConfig() {
return Boolean.parseBoolean(properties.getProperty(TEXT_WRAP, "true"));
return Boolean.parseBoolean(PROPERTIES.getProperty(TEXT_WRAP, "true"));
}
public void setAutoLineConfig(boolean isAutoLine) {
String autoLineConfig = String.valueOf(isAutoLine);
properties.setProperty(TEXT_WRAP, autoLineConfig);
PROPERTIES.setProperty(TEXT_WRAP, autoLineConfig);
}
public static GlobalConfig getConfig() {

View File

@ -1,5 +1,8 @@
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.app.entity.ShortcutKey;
@ -9,11 +12,10 @@ 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 java.util.*;
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_NAME;
import static org.jcnc.jnotepad.constants.AppConstants.CONFIG_SHORTCUT_KEY_NAME;
import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG;
/**
@ -25,6 +27,7 @@ import static org.jcnc.jnotepad.constants.TextConstants.JNOTEPAD_CONFIG;
public abstract class LoadJnotepadConfig {
Logger logger = LogUtil.getLogger(this.getClass());
public final void load() {
// 判断是否存在这个配置文件
try (InputStream inputStream = new FileInputStream(CONFIG_NAME)) {
@ -35,10 +38,54 @@ public abstract class LoadJnotepadConfig {
logger.info("未检测到配置文件!");
// 不存在则创建
createConfig();
logger.info("已创建默认配置文件!");
}
}
void createConfig() {
/**
* 解析配置文件
*
* @param inputStream 输入流
* @return java.util.List<java.util.LinkedHashMap < java.lang.String, java.lang.String>>
* @since 2023/8/25 15:18
*/
protected List<LinkedHashMap<String, String>> parseConfig(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("错误", "解析错误", "配置文件解析错误!");
logger.error("配置文件解析错误!", e);
}
if (mainConfig == null) {
logger.error("未获取到主要配置文件!");
return Collections.emptyList();
}
return 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();
}
private void createConfig() {
List<ShortcutKey> shortcutKeyList = getShortcutKeys();
JnotepadConfig.getInstance().setShortcutKeyList(shortcutKeyList);
for (ShortcutKey shortcutKey : shortcutKeyList) {

View File

@ -0,0 +1,31 @@
package org.jcnc.jnotepad.app.config;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.List;
import static org.jcnc.jnotepad.constants.TextConstants.CONFIG;
import static org.jcnc.jnotepad.constants.TextConstants.LANGUAGE_MAP;
/**
* 加载语言配置文件
*
* @author gewuyou
* @see [相关类/方法]
*/
public class LoadLanguageConfig extends LoadJnotepadConfig {
@Override
protected void loadConfig(InputStream inputStream) {
List<LinkedHashMap<String, String>> configData = parseConfig(inputStream);
String language = "";
for (LinkedHashMap<String, String> config : configData) {
language = config.get("language");
if (language != null) {
break;
}
}
if (!"".equals(language) && language != null) {
CONFIG.setLanguagePackName(LANGUAGE_MAP.get(language));
}
}
}

View File

@ -1,22 +1,15 @@
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;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
/**
* 加载快捷键实现
@ -28,41 +21,8 @@ public class LoadShortcutKeyConfig extends LoadJnotepadConfig {
@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) {
List<LinkedHashMap<String, String>> configData = parseConfig(inputStream);
for (LinkedHashMap<String, String> shortcutKey : configData) {
// 保证json的key必须和变量名一致
MenuItem menuItem = JNotepadMenuBar.getMenuBar().getItemMap().get(shortcutKey.get("buttonName"));
String shortKeyValue = shortcutKey.get("shortcutKeyValue");

View File

@ -2,6 +2,7 @@ package org.jcnc.jnotepad.constants;
import org.jcnc.jnotepad.init.Config;
import java.util.Map;
import java.util.Properties;
/**
@ -17,8 +18,11 @@ public class TextConstants {
private TextConstants() {
}
private static final Config CONFIG = new Config();
private static final Properties PROPERTIES = CONFIG.readPropertiesFromFile();
public static final Config CONFIG = new Config();
public static final Properties PROPERTIES = CONFIG.readPropertiesFromFile();
/// 应用程序文本常量
public static final String TITLE = PROPERTIES.getProperty("title", "JNotepad");
///菜单栏文本常量
@ -44,6 +48,15 @@ public class TextConstants {
public static final String OPEN_CONFIGURATION_FILE = PROPERTIES.getProperty("OPEN_CONFIGURATION_FILE");
public static final String TOP = PROPERTIES.getProperty("TOP");
public static final String LANGUAGE = PROPERTIES.getProperty("LANGUAGE");
public static final String CHINESE = PROPERTIES.getProperty("CHINESE");
public static final String ENGLISH = PROPERTIES.getProperty("ENGLISH");
/// GlobalConfig文本常量
/**
* 自动换行配置key
@ -70,7 +83,11 @@ public class TextConstants {
public static final String WORD_COUNT = PROPERTIES.getProperty("WORD_COUNT");
public static final String ENCODE = PROPERTIES.getProperty("ENCODE");
/// 语言映射
public static final Map<String, String> LANGUAGE_MAP = Map.of(
"chinese", "JNotepad ch_language_pack",
"english", "JNotepad en_language_pack"
);
/// 配置文件文本常量
/**
* 内置配置文件
@ -78,6 +95,7 @@ public class TextConstants {
public static final String JNOTEPAD_CONFIG =
"""
{
"language":"chinese",
"shortcutKey":[
{
"buttonName": "newItem",

View File

@ -47,7 +47,7 @@ public class SaveFile implements EventHandler<ActionEvent> {
// 如果该文件是配置文件则刷新快捷键
if (CONFIG_NAME.equals(selectedTab.getText())) {
// 初始化快捷键
View.getInstance().initShortcutKey(new LoadShortcutKeyConfig());
View.getInstance().initJnotepadConfig(new LoadShortcutKeyConfig());
logger.info("已刷新快捷键!");
}
}

View File

@ -22,6 +22,14 @@ public class Config {
Logger logger = LogUtil.getLogger(this.getClass());
public void setLanguagePackName(String languagePackName) {
this.languagePackName = languagePackName;
}
public String getLanguagePackName() {
return languagePackName;
}
/**
* 从文件中读取属性配置
*
@ -29,11 +37,11 @@ public class Config {
*/
public Properties readPropertiesFromFile() {
Properties properties = new Properties();
//设置语言包
// 设置语言包
languagePackName = EN_LANGUAGE_PACK_NAME;
try (InputStream inputStream = new FileInputStream(languagePackName)) {
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
// 使用 UTF-8 编码
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
properties.load(reader);
} catch (IOException e) {
// 如果读取出错则调用初始化方法
@ -52,7 +60,8 @@ public class Config {
Properties enLanguagePack = getEnglishLanguagePack();
try (OutputStream outputStream = new FileOutputStream(CH_LANGUAGE_PACK_NAME)) {
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
// 使用 UTF-8 编码
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
chLanguagePack.store(writer, JNOTEPAD_CH_LANGUAGE_PACK_NAME);
} catch (IOException ignored) {
@ -60,7 +69,8 @@ public class Config {
}
try (OutputStream outputStream = new FileOutputStream(EN_LANGUAGE_PACK_NAME)) {
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); // 使用 UTF-8 编码
// 使用 UTF-8 编码
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
enLanguagePack.store(writer, JNOTEPAD_EN_LANGUAGE_PACK_NAME);
} catch (IOException ignored) {
@ -70,8 +80,8 @@ public class Config {
private static Properties getChineseLanguagePack() {
Properties properties = new Properties();
properties.setProperty("TITLE", "JNotepad"); // 设置默认属性
// 设置默认属性
properties.setProperty("TITLE", "JNotepad");
properties.setProperty("NEW_FILE", "新建文件");
properties.setProperty("SAVA", "保存");
properties.setProperty("FILE", "文件");
@ -88,6 +98,10 @@ public class Config {
properties.setProperty("COLUMN", "列数");
properties.setProperty("WORD_COUNT", "字数");
properties.setProperty("ENCODE", "编码");
properties.setProperty("TOP", "窗口置顶");
properties.setProperty("LANGUAGE", "语言");
properties.setProperty("CHINESE", "中文");
properties.setProperty("ENGLISH", "英文");
return properties;
}
@ -111,6 +125,10 @@ public class Config {
properties.setProperty("COLUMN", "Column");
properties.setProperty("WORD_COUNT", "Word Count");
properties.setProperty("ENCODE", "Encoding");
properties.setProperty("TOP", "Window Top");
properties.setProperty("LANGUAGE", "Language");
properties.setProperty("CHINESE", "Chinese");
properties.setProperty("ENGLISH", "English");
return properties;
}

View File

@ -3,14 +3,12 @@ package org.jcnc.jnotepad.tool;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import org.jcnc.jnotepad.constants.TextConstants;
import org.slf4j.Logger;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import static org.jcnc.jnotepad.constants.TextConstants.UNKNOWN;

View File

@ -4,6 +4,7 @@ import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.stage.Stage;
import org.jcnc.jnotepad.app.config.GlobalConfig;
import org.jcnc.jnotepad.controller.event.handler.*;
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
@ -38,7 +39,7 @@ public class JNotepadMenuBar extends MenuBar {
*/
private Menu fileMenu;
/**
* 插件菜单
* 设置菜单
*/
private Menu setMenu;
/**
@ -46,6 +47,11 @@ public class JNotepadMenuBar extends MenuBar {
*/
private Menu pluginMenu;
/**
* 语言菜单
*/
private Menu languageMenu;
/// 菜单按钮
/**
@ -80,8 +86,19 @@ public class JNotepadMenuBar extends MenuBar {
* 自动换行点击菜单按钮
*/
private CheckMenuItem lineFeedItem;
/**
* 置顶按钮
*/
private CheckMenuItem topItem;
/**
* 中文选项
*/
private MenuItem chineseItem;
/**
* 英文选项
*/
private MenuItem englishItem;
private final Map<String, MenuItem> itemMap = new HashMap<>();
/**
@ -89,13 +106,31 @@ public class JNotepadMenuBar extends MenuBar {
*/
private void init() {
initFileMenu();
initLanguageMenu();
initSettingMenu();
initPluginMenu();
// 菜单栏
this.getMenus().addAll(fileMenu, setMenu, pluginMenu);
initEventHandlers();
}
/**
* 初始化语言菜单
*/
private void initLanguageMenu() {
// 语言菜单
languageMenu = new Menu(LANGUAGE);
chineseItem = new MenuItem(CHINESE);
itemMap.put("chineseItem", chineseItem);
englishItem = new MenuItem(ENGLISH);
itemMap.put("englishItem", englishItem);
languageMenu.getItems().addAll(chineseItem, englishItem);
}
/**
* 初始化文件菜单
*/
@ -128,9 +163,15 @@ public class JNotepadMenuBar extends MenuBar {
lineFeedItem = new CheckMenuItem(WORD_WRAP);
itemMap.put("lineFeedItem", lineFeedItem);
lineFeedItem.selectedProperty().set(true);
topItem = new CheckMenuItem(TOP);
itemMap.put("topItem", topItem);
openConfigItem = new MenuItem(OPEN_CONFIGURATION_FILE);
itemMap.put("openConfigItem", openConfigItem);
setMenu.getItems().addAll(lineFeedItem, openConfigItem);
itemMap.put("languageMenu", languageMenu);
setMenu.getItems().addAll(lineFeedItem, openConfigItem, topItem, languageMenu);
}
/**
@ -167,6 +208,13 @@ public class JNotepadMenuBar extends MenuBar {
// 2. 对当前tab生效配置
jNotepadTabPane.fireTabSelected();
});
topItem.selectedProperty().addListener((observableValue, before, after) -> {
// 获取窗口容器
Stage primaryStage = (Stage) this.getScene().getWindow();
// 设置窗口为置顶
primaryStage.setAlwaysOnTop(after);
});
}
public Map<String, MenuItem> getItemMap() {

View File

@ -2,6 +2,8 @@ package org.jcnc.jnotepad.view.init;
import org.jcnc.jnotepad.app.config.LoadJnotepadConfig;
import java.util.List;
/**
* @author 许轲
@ -14,14 +16,27 @@ public class View {
private static final View INSTANCE = new View();
/**
* 初始化快捷键
* 初始化配置文件
*
* @param loadJnotepadConfig 加载配置文件
* @param loadJnotepadConfigs 需要加载配置文件数组
* @since 2023/8/24 15:29
*/
public void initShortcutKey(LoadJnotepadConfig loadJnotepadConfig) {
public void initJnotepadConfigs(List<LoadJnotepadConfig> loadJnotepadConfigs) {
for (LoadJnotepadConfig loadJnotepadConfig : loadJnotepadConfigs) {
initJnotepadConfig(loadJnotepadConfig);
}
}
/**
* 初始化配置文件
*
* @param loadJnotepadConfig 配置文件
* @since 2023/8/24 15:29
*/
public void initJnotepadConfig(LoadJnotepadConfig loadJnotepadConfig) {
loadJnotepadConfig.load();
}
public static View getInstance() {
return INSTANCE;
}