From 981fa41f2559d5c9d894e547c45280c0cfee346c Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Thu, 5 Oct 2023 11:03:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B0=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/module-info.java | 4 +- .../stage/AbstractPaneStage.java | 2 +- .../core/manager/AbstractCacheManager.java | 2 +- .../manager/builder/SideBarButtonBuilder.java | 8 +- .../jnotepad/app/config/PluginConfig.java | 2 +- .../jcnc/jnotepad/app/config/UserConfig.java | 2 +- .../jnotepad/component/module/CodeArea.java | 226 ------------------ .../component/module/TextCodeArea.java | 146 +++++++++++ .../stage/dialog/AppDialogBuilder.java | 2 +- .../stage/setting/HelpPaneStage.java | 2 +- .../setting/plugin/PluginManagementPane.java | 4 +- .../controller/cache/CacheController.java | 2 +- .../config/UserConfigController.java | 2 +- .../event/handler/menuitem/NewFile.java | 4 +- .../event/handler/menuitem/OpenDirectory.java | 6 +- .../event/handler/menuitem/OpenFile.java | 28 +-- .../event/handler/menuitem/SaveFile.java | 4 +- .../{cache => model}/entity/Cache.java | 2 +- .../model/entity/DefaultContextMenu.java | 56 +++++ .../{cache => model}/entity/DirFileModel.java | 2 +- .../entity/PluginDescriptor.java | 2 +- .../{cache => model}/entity/ShortcutKey.java | 2 +- .../model/entity/VisibleParagraphStyler.java | 47 ++++ .../enums/CacheExpirationTime.java | 2 +- .../{cache => model}/enums/DialogType.java | 2 +- .../jcnc/jnotepad/plugin/PluginLoader.java | 2 +- .../plugin/manager/PluginManager.java | 2 +- .../java/org/jcnc/jnotepad/util/FileUtil.java | 2 +- .../org/jcnc/jnotepad/util/PopUpUtil.java | 2 +- .../views/manager/BottomStatusBoxManager.java | 6 +- .../views/manager/CenterTabPaneManager.java | 10 +- .../manager/DirectorySidebarManager.java | 2 +- .../views/manager/TopMenuBarManager.java | 2 +- .../directory/DirectorySidebarPane.java | 2 +- .../center/main/center/tab/CenterTab.java | 22 +- tool/jpackage.sh | 11 + 36 files changed, 329 insertions(+), 295 deletions(-) rename src/main/java/org/jcnc/jnotepad/api/core/{ui => component}/stage/AbstractPaneStage.java (95%) delete mode 100644 src/main/java/org/jcnc/jnotepad/component/module/CodeArea.java create mode 100644 src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java rename src/main/java/org/jcnc/jnotepad/{cache => model}/entity/Cache.java (98%) create mode 100644 src/main/java/org/jcnc/jnotepad/model/entity/DefaultContextMenu.java rename src/main/java/org/jcnc/jnotepad/{cache => model}/entity/DirFileModel.java (97%) rename src/main/java/org/jcnc/jnotepad/{cache => model}/entity/PluginDescriptor.java (99%) rename src/main/java/org/jcnc/jnotepad/{cache => model}/entity/ShortcutKey.java (93%) create mode 100644 src/main/java/org/jcnc/jnotepad/model/entity/VisibleParagraphStyler.java rename src/main/java/org/jcnc/jnotepad/{cache => model}/enums/CacheExpirationTime.java (94%) rename src/main/java/org/jcnc/jnotepad/{cache => model}/enums/DialogType.java (88%) create mode 100644 tool/jpackage.sh diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 39a90de..6c3451e 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -21,7 +21,7 @@ module org.jcnc.jnotepad { requires javafx.web; exports org.jcnc.jnotepad; - exports org.jcnc.jnotepad.cache.enums; + exports org.jcnc.jnotepad.model.enums; exports org.jcnc.jnotepad.app.config; exports org.jcnc.jnotepad.app.i18n; exports org.jcnc.jnotepad.common.constants; @@ -36,7 +36,7 @@ module org.jcnc.jnotepad { exports org.jcnc.jnotepad.views.root.bottom.function; exports org.jcnc.jnotepad.component.module; - exports org.jcnc.jnotepad.cache.entity; + exports org.jcnc.jnotepad.model.entity; exports org.jcnc.jnotepad.views.root.bottom; exports org.jcnc.jnotepad.views.root.bottom.status; exports org.jcnc.jnotepad.api.core.views.sidebar.bottom; diff --git a/src/main/java/org/jcnc/jnotepad/api/core/ui/stage/AbstractPaneStage.java b/src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractPaneStage.java similarity index 95% rename from src/main/java/org/jcnc/jnotepad/api/core/ui/stage/AbstractPaneStage.java rename to src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractPaneStage.java index e2b7471..b3e405e 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/ui/stage/AbstractPaneStage.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractPaneStage.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.api.core.ui.stage; +package org.jcnc.jnotepad.api.core.component.stage; import javafx.scene.Scene; import javafx.scene.image.Image; diff --git a/src/main/java/org/jcnc/jnotepad/api/core/manager/AbstractCacheManager.java b/src/main/java/org/jcnc/jnotepad/api/core/manager/AbstractCacheManager.java index 5bdad91..0bdfc32 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/manager/AbstractCacheManager.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/manager/AbstractCacheManager.java @@ -1,6 +1,6 @@ package org.jcnc.jnotepad.api.core.manager; -import org.jcnc.jnotepad.cache.entity.Cache; +import org.jcnc.jnotepad.model.entity.Cache; import java.util.Map; diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/manager/builder/SideBarButtonBuilder.java b/src/main/java/org/jcnc/jnotepad/api/core/views/manager/builder/SideBarButtonBuilder.java index 9be20d3..c77cad6 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/manager/builder/SideBarButtonBuilder.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/manager/builder/SideBarButtonBuilder.java @@ -49,14 +49,14 @@ public class SideBarButtonBuilder { * @return 建造者对象 */ public SideBarButtonBuilder setImageViewEssentialAttribute(Double fitWidth, Double fitHeight, boolean preserveRatio, Double scaleX, Double scaleY) { - Optional container = Optional.of(fitWidth); + Optional container = Optional.ofNullable(fitWidth); imageView.setFitWidth(container.orElse(10D)); - container = Optional.of(fitHeight); + container = Optional.ofNullable(fitHeight); imageView.setFitHeight(container.orElse(10D)); imageView.setPreserveRatio(preserveRatio); - container = Optional.of(scaleX); + container = Optional.ofNullable(scaleX); imageView.setScaleX(container.orElse(2.5)); - container = Optional.of(scaleY); + container = Optional.ofNullable(scaleY); imageView.setScaleY(container.orElse(2.5)); return this; } diff --git a/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java index 92e3bcf..2b05c81 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java @@ -1,6 +1,6 @@ package org.jcnc.jnotepad.app.config; -import org.jcnc.jnotepad.cache.entity.PluginDescriptor; +import org.jcnc.jnotepad.model.entity.PluginDescriptor; import java.util.List; diff --git a/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java index d144f98..c828a33 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java @@ -1,7 +1,7 @@ package org.jcnc.jnotepad.app.config; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.jcnc.jnotepad.cache.entity.ShortcutKey; +import org.jcnc.jnotepad.model.entity.ShortcutKey; import java.util.List; diff --git a/src/main/java/org/jcnc/jnotepad/component/module/CodeArea.java b/src/main/java/org/jcnc/jnotepad/component/module/CodeArea.java deleted file mode 100644 index 248a1c4..0000000 --- a/src/main/java/org/jcnc/jnotepad/component/module/CodeArea.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.jcnc.jnotepad.component.module; - -import javafx.application.Platform; -import javafx.geometry.Insets; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.MenuItem; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; -import org.fxmisc.richtext.GenericStyledArea; -import org.fxmisc.richtext.LineNumberFactory; -import org.fxmisc.richtext.model.Paragraph; -import org.fxmisc.richtext.model.StyleSpans; -import org.fxmisc.richtext.model.StyleSpansBuilder; -import org.reactfx.Subscription; -import org.reactfx.collection.ListModification; - -import java.time.Duration; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * 行号文本区域 - * - *

这个类继承自JavaFX的BorderPane类,用于显示带有行号的文本区域。它包括主要文本区域和行号文本区域。

- * - * @author luke - */ -public class CodeArea extends org.fxmisc.richtext.CodeArea { - - private static final String[] KEYWORDS = new String[]{ - "abstract", "assert", "boolean", "break", "byte", - "case", "catch", "char", "class", "const", - "continue", "default", "do", "double", "else", - "enum", "extends", "final", "finally", "float", - "for", "goto", "if", "implements", "import", - "instanceof", "int", "interface", "long", "native", - "new", "package", "private", "protected", "public", - "return", "short", "static", "strictfp", "super", - "switch", "synchronized", "this", "throw", "throws", - "transient", "try", "void", "volatile", "while" - }; - - /** - * 定义用于匹配关键字、括号、分号、字符串和注释的正则表达式模式 - */ - private static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; - private static final String PAREN_PATTERN = "\\(|\\)"; - private static final String BRACE_PATTERN = "\\{|\\}"; - private static final String BRACKET_PATTERN = "\\[|\\]"; - private static final String SEMICOLON_PATTERN = "\\;"; - private static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\""; - private static final String COMMENT_PATTERN = - // 用于整体文本处理(文本块) - "//[^\n]*" + "|" + "/\\*(.|\\R)*?\\*/" - // 用于可见段落处理(逐行) - + "|" + "/\\*[^\\v]*" + "|" + "^\\h*\\*([^\\v]*|/)"; - - - /** - * 使用正则表达式将关键字、括号、分号、字符串和注释的模式组合成一个复合模式 - */ - private static final Pattern PATTERN = Pattern.compile( - "(?" + KEYWORD_PATTERN + ")" - + "|(?" + PAREN_PATTERN + ")" - + "|(?" + BRACE_PATTERN + ")" - + "|(?" + BRACKET_PATTERN + ")" - + "|(?" + SEMICOLON_PATTERN + ")" - + "|(?" + STRING_PATTERN + ")" - + "|(?" + COMMENT_PATTERN + ")" - ); - - /** - * 构造函数 - *

- * 用于创建 LineNumberTextArea 对象 - */ - public CodeArea() { - // 上、右、下、左 - this.setPadding(new Insets(8, 0, 0, 0)); - - // 在区域左侧添加行号 - this.setParagraphGraphicFactory(LineNumberFactory.get(this)); - this.setContextMenu(new DefaultContextMenu()); - - /* - 重新计算所有文本的语法高亮,用户停止编辑区域后的500毫秒内 - */ - Subscription cleanupWhenNoLongerNeedIt = this - .multiPlainChanges() - .successionEnds(Duration.ofMillis(500)) - .subscribe(ignore -> this.setStyleSpans(0, computeHighlighting(this.getText()))); - - this.getVisibleParagraphs().addModificationObserver - ( - new CodeArea.VisibleParagraphStyler<>(this, this::computeHighlighting) - ); - - // 自动缩进:在按下回车键时插入上一行的缩进 - final Pattern whiteSpace = Pattern.compile("^\\s+"); - this.addEventHandler(KeyEvent.KEY_PRESSED, kE -> - { - if (kE.getCode() == KeyCode.ENTER) { - int caretPosition = this.getCaretPosition(); - int currentParagraph = this.getCurrentParagraph(); - Matcher m0 = whiteSpace.matcher(this.getParagraph(currentParagraph - 1).getSegments().get(0)); - if (m0.find()) { - Platform.runLater(() -> this.insertText(caretPosition, m0.group())); - } - } - }); - this.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/java_code_styles.css")).toString()); - } - - - private StyleSpans> computeHighlighting(String text) { - Matcher matcher = PATTERN.matcher(text); - int lastKwEnd = 0; - StyleSpansBuilder> spansBuilder - = new StyleSpansBuilder<>(); - while (matcher.find()) { - String styleClass = getStyleClass(matcher); - spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd); - spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start()); - lastKwEnd = matcher.end(); - } - spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd); - return spansBuilder.create(); - } - - private static String getStyleClass(Matcher matcher) { - String styleClass = - matcher.group("KEYWORD") != null ? "keyword" : - matcher.group("PAREN") != null ? "paren" : - matcher.group("BRACE") != null ? "brace" : - matcher.group("BRACKET") != null ? "bracket" : - matcher.group("SEMICOLON") != null ? "semicolon" : - matcher.group("STRING") != null ? "string" : - matcher.group("COMMENT") != null ? "comment" : - null; /* 永远不会发生 */ - assert styleClass != null; - return styleClass; - } - - static class VisibleParagraphStyler implements Consumer>> { - private final GenericStyledArea area; - private final Function> computeStyles; - private int prevParagraph, prevTextLength; - - public VisibleParagraphStyler(GenericStyledArea area, Function> computeStyles) { - this.computeStyles = computeStyles; - this.area = area; - } - - @Override - public void accept(ListModification> lm) { - if (lm.getAddedSize() > 0) { - Platform.runLater(() -> { - int paragraph = Math.min(area.firstVisibleParToAllParIndex() + lm.getFrom(), area.getParagraphs().size() - 1); - String text = area.getText(paragraph, 0, paragraph, area.getParagraphLength(paragraph)); - - if (paragraph != prevParagraph || text.length() != prevTextLength) { - if (paragraph < area.getParagraphs().size() - 1) { - int startPos = area.getAbsolutePosition(paragraph, 0); - area.setStyleSpans(startPos, computeStyles.apply(text)); - } - prevTextLength = text.length(); - prevParagraph = paragraph; - } - }); - } - - } - } - - private static class DefaultContextMenu extends ContextMenu { - private final MenuItem fold; - private final MenuItem unfold; - private final MenuItem print; - - public DefaultContextMenu() { - fold = new MenuItem("折叠所选文本"); - fold.setOnAction(aE -> { - hide(); - fold(); - }); - - unfold = new MenuItem("从光标处展开"); - unfold.setOnAction(aE -> { - hide(); - unfold(); - }); - - print = new MenuItem("打印"); - print.setOnAction(aE -> { - hide(); - print(); - }); - - getItems().addAll(fold, unfold, print); - } - - /** - * 折叠多行所选文本,仅显示第一行并隐藏其余部分。 - */ - private void fold() { - ((org.fxmisc.richtext.CodeArea) getOwnerNode()).foldSelectedParagraphs(); - } - - /** - * 展开当前行/段落(如果有折叠)。 - */ - private void unfold() { - org.fxmisc.richtext.CodeArea area = (org.fxmisc.richtext.CodeArea) getOwnerNode(); - area.unfoldParagraphs(area.getCurrentParagraph()); - } - - private void print() { - System.out.println(((org.fxmisc.richtext.CodeArea) getOwnerNode()).getText()); - } - } -} diff --git a/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java b/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java new file mode 100644 index 0000000..451958f --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/component/module/TextCodeArea.java @@ -0,0 +1,146 @@ +package org.jcnc.jnotepad.component.module; + +import javafx.application.Platform; +import javafx.geometry.Insets; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import org.fxmisc.richtext.CodeArea; +import org.fxmisc.richtext.LineNumberFactory; +import org.fxmisc.richtext.model.StyleSpans; +import org.fxmisc.richtext.model.StyleSpansBuilder; +import org.jcnc.jnotepad.model.entity.DefaultContextMenu; +import org.jcnc.jnotepad.model.entity.VisibleParagraphStyler; +import org.reactfx.Subscription; + +import java.time.Duration; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 文本代码域 + *

+ * + * @author luke + */ +public class TextCodeArea extends CodeArea { + + private static final String[] KEYWORDS = new String[]{ + "abstract", "assert", "boolean", "break", "byte", + "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", + "enum", "extends", "final", "finally", "float", + "for", "goto", "if", "implements", "import", + "instanceof", "int", "interface", "long", "native", + "new", "package", "private", "protected", "public", + "return", "short", "static", "strictfp", "super", + "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while" + }; + + /** + * 定义用于匹配关键字、括号、分号、字符串和注释的正则表达式模式 + */ + private static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; + private static final String PAREN_PATTERN = "[()]"; + private static final String BRACE_PATTERN = "[{}]"; + private static final String BRACKET_PATTERN = "[\\[\\]]"; + private static final String SEMICOLON_PATTERN = ";"; + private static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\""; + private static final String COMMENT_PATTERN = + // 用于整体文本处理(文本块) + "//[^\n]*" + "|" + "/\\*(.|\\R)*?\\*/" + // 用于可见段落处理(逐行) + + "|" + "/\\*\\V*" + "|" + "^\\h*\\*(\\V*|/)"; + + + /** + * 使用正则表达式将关键字、括号、分号、字符串和注释的模式组合成一个复合模式 + */ + private static final Pattern PATTERN = Pattern.compile( + "(?" + KEYWORD_PATTERN + ")" + + "|(?" + PAREN_PATTERN + ")" + + "|(?" + BRACE_PATTERN + ")" + + "|(?" + BRACKET_PATTERN + ")" + + "|(?" + SEMICOLON_PATTERN + ")" + + "|(?" + STRING_PATTERN + ")" + + "|(?" + COMMENT_PATTERN + ")" + ); + + /** + * 构造函数 + *

+ * 用于创建 TextCodeArea 对象 + */ + public TextCodeArea() { + // 上、右、下、左 + this.setPadding(new Insets(8, 0, 0, 0)); + + // 在区域左侧添加行号 + this.setParagraphGraphicFactory(LineNumberFactory.get(this)); + this.setContextMenu(new DefaultContextMenu()); + + /* + 重新计算所有文本的语法高亮,用户停止编辑区域后的500毫秒内 + fixme 这个代码没有作用 + */ + Subscription cleanupWhenNoLongerNeedIt = this + .multiPlainChanges() + .successionEnds(Duration.ofMillis(500)) + .subscribe(ignore -> this.setStyleSpans(0, computeHighlighting(this.getText()))); + + this.getVisibleParagraphs().addModificationObserver + ( + new VisibleParagraphStyler<>(this, this::computeHighlighting) + ); + + // 自动缩进:在按下回车键时插入上一行的缩进 + final Pattern whiteSpace = Pattern.compile("^\\s+"); + this.addEventHandler(KeyEvent.KEY_PRESSED, kE -> + { + if (kE.getCode() == KeyCode.ENTER) { + int caretPosition = this.getCaretPosition(); + int currentParagraph = this.getCurrentParagraph(); + Matcher m0 = whiteSpace.matcher(this.getParagraph(currentParagraph - 1).getSegments().get(0)); + if (m0.find()) { + Platform.runLater(() -> this.insertText(caretPosition, m0.group())); + } + } + }); + this.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/css/java_code_styles.css")).toString()); + } + + + private StyleSpans> computeHighlighting(String text) { + Matcher matcher = PATTERN.matcher(text); + int lastKwEnd = 0; + StyleSpansBuilder> spansBuilder + = new StyleSpansBuilder<>(); + while (matcher.find()) { + String styleClass = getStyleClass(matcher); + spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd); + spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start()); + lastKwEnd = matcher.end(); + } + spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd); + return spansBuilder.create(); + } + + private static String getStyleClass(Matcher matcher) { + Map patternToStyleClass = new HashMap<>(16); + patternToStyleClass.put("keyword", matcher.group("KEYWORD")); + patternToStyleClass.put("paren", matcher.group("PAREN")); + patternToStyleClass.put("brace", matcher.group("BRACE")); + patternToStyleClass.put("bracket", matcher.group("BRACKET")); + patternToStyleClass.put("semicolon", matcher.group("SEMICOLON")); + patternToStyleClass.put("string", matcher.group("STRING")); + patternToStyleClass.put("comment", matcher.group("COMMENT")); + for (Map.Entry entry : patternToStyleClass.entrySet()) { + if (entry.getValue() != null) { + return entry.getKey(); + } + } + // 永不发生 + return null; + } +} diff --git a/src/main/java/org/jcnc/jnotepad/component/stage/dialog/AppDialogBuilder.java b/src/main/java/org/jcnc/jnotepad/component/stage/dialog/AppDialogBuilder.java index 9e6a0e5..ec46440 100644 --- a/src/main/java/org/jcnc/jnotepad/component/stage/dialog/AppDialogBuilder.java +++ b/src/main/java/org/jcnc/jnotepad/component/stage/dialog/AppDialogBuilder.java @@ -5,8 +5,8 @@ import javafx.geometry.Pos; import javafx.scene.image.Image; import javafx.stage.Modality; import javafx.stage.Stage; -import org.jcnc.jnotepad.cache.enums.DialogType; import org.jcnc.jnotepad.component.stage.dialog.interfaces.DialogButtonAction; +import org.jcnc.jnotepad.model.enums.DialogType; import org.jcnc.jnotepad.util.UiUtil; import org.kordamp.ikonli.javafx.FontIcon; diff --git a/src/main/java/org/jcnc/jnotepad/component/stage/setting/HelpPaneStage.java b/src/main/java/org/jcnc/jnotepad/component/stage/setting/HelpPaneStage.java index d25adbc..1ada5f0 100644 --- a/src/main/java/org/jcnc/jnotepad/component/stage/setting/HelpPaneStage.java +++ b/src/main/java/org/jcnc/jnotepad/component/stage/setting/HelpPaneStage.java @@ -17,7 +17,7 @@ import javafx.scene.input.ClipboardContent; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; -import org.jcnc.jnotepad.api.core.ui.stage.AbstractPaneStage; +import org.jcnc.jnotepad.api.core.component.stage.AbstractPaneStage; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; import org.jcnc.jnotepad.views.manager.RootManager; diff --git a/src/main/java/org/jcnc/jnotepad/component/stage/setting/plugin/PluginManagementPane.java b/src/main/java/org/jcnc/jnotepad/component/stage/setting/plugin/PluginManagementPane.java index 589e31b..49c4aea 100644 --- a/src/main/java/org/jcnc/jnotepad/component/stage/setting/plugin/PluginManagementPane.java +++ b/src/main/java/org/jcnc/jnotepad/component/stage/setting/plugin/PluginManagementPane.java @@ -25,9 +25,9 @@ import javafx.scene.web.WebView; import javafx.stage.Stage; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; -import org.jcnc.jnotepad.api.core.ui.stage.AbstractPaneStage; -import org.jcnc.jnotepad.cache.entity.PluginDescriptor; +import org.jcnc.jnotepad.api.core.component.stage.AbstractPaneStage; import org.jcnc.jnotepad.component.stage.setting.CustomSetButton; +import org.jcnc.jnotepad.model.entity.PluginDescriptor; import org.jcnc.jnotepad.plugin.manager.PluginManager; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.PopUpUtil; diff --git a/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java b/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java index fdb5569..28cd7d0 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java @@ -1,9 +1,9 @@ package org.jcnc.jnotepad.controller.cache; import com.fasterxml.jackson.core.type.TypeReference; -import org.jcnc.jnotepad.cache.entity.Cache; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; import org.jcnc.jnotepad.controller.config.AppConfigController; +import org.jcnc.jnotepad.model.entity.Cache; import org.jcnc.jnotepad.util.JsonUtil; import org.jcnc.jnotepad.util.LogUtil; import org.slf4j.Logger; diff --git a/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java b/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java index 231b083..c0c88ce 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java @@ -2,7 +2,7 @@ package org.jcnc.jnotepad.controller.config; import org.jcnc.jnotepad.api.core.controller.config.BaseConfigController; import org.jcnc.jnotepad.app.config.UserConfig; -import org.jcnc.jnotepad.cache.entity.ShortcutKey; +import org.jcnc.jnotepad.model.entity.ShortcutKey; import java.nio.file.Paths; import java.util.ArrayList; diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/NewFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/NewFile.java index ade9ce5..81c107c 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/NewFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/NewFile.java @@ -6,7 +6,7 @@ import javafx.scene.control.Tab; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; import org.jcnc.jnotepad.common.constants.AppConstants; import org.jcnc.jnotepad.common.constants.TextConstants; -import org.jcnc.jnotepad.component.module.CodeArea; +import org.jcnc.jnotepad.component.module.TextCodeArea; import org.jcnc.jnotepad.views.manager.BottomStatusBoxManager; import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; @@ -38,7 +38,7 @@ public class NewFile implements EventHandler { */ public void addNewFileTab() { // 创建一个新的文本编辑区 - CodeArea textArea = new CodeArea(); + TextCodeArea textArea = new TextCodeArea(); // TODO: refactor:统一TextArea新建、绑定监听器入口 // 设定初始索引 int index = 1; diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenDirectory.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenDirectory.java index ba84dd6..726e7c8 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenDirectory.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenDirectory.java @@ -4,12 +4,12 @@ package org.jcnc.jnotepad.controller.event.handler.menuitem; import javafx.event.ActionEvent; import javafx.event.EventHandler; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; -import org.jcnc.jnotepad.cache.entity.Cache; -import org.jcnc.jnotepad.cache.entity.DirFileModel; -import org.jcnc.jnotepad.cache.enums.CacheExpirationTime; import org.jcnc.jnotepad.common.constants.TextConstants; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; import org.jcnc.jnotepad.component.stage.dialog.factory.impl.BasicDirectoryChooserFactory; +import org.jcnc.jnotepad.model.entity.Cache; +import org.jcnc.jnotepad.model.entity.DirFileModel; +import org.jcnc.jnotepad.model.enums.CacheExpirationTime; import org.jcnc.jnotepad.util.FileUtil; import org.jcnc.jnotepad.util.UiUtil; import org.jcnc.jnotepad.views.manager.DirectorySidebarManager; diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenFile.java index db19160..ededf51 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/OpenFile.java @@ -5,12 +5,12 @@ import javafx.event.EventHandler; import javafx.scene.control.Tab; import javafx.stage.FileChooser; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; -import org.jcnc.jnotepad.cache.entity.Cache; -import org.jcnc.jnotepad.cache.enums.CacheExpirationTime; import org.jcnc.jnotepad.common.constants.TextConstants; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; -import org.jcnc.jnotepad.component.module.CodeArea; +import org.jcnc.jnotepad.component.module.TextCodeArea; import org.jcnc.jnotepad.component.stage.dialog.factory.impl.BasicFileChooserFactory; +import org.jcnc.jnotepad.model.entity.Cache; +import org.jcnc.jnotepad.model.enums.CacheExpirationTime; import org.jcnc.jnotepad.util.EncodingDetector; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; @@ -70,9 +70,9 @@ public class OpenFile implements EventHandler { */ public static void openFile(File file) { // 获取标签页集合 - CenterTabPane jnotepadTabPane = CenterTabPane.getInstance(); + CenterTabPane centerTabPane = CenterTabPane.getInstance(); // 遍历标签页,查找匹配的标签页 - for (Tab tab : jnotepadTabPane.getTabs()) { + for (Tab tab : centerTabPane.getTabs()) { // 获取绑定的文件 File tabFile = (File) tab.getUserData(); if (tabFile == null) { @@ -80,7 +80,7 @@ public class OpenFile implements EventHandler { } if (file.getPath().equals((tabFile).getPath())) { // 找到匹配的标签页,设置为选中状态并跳转 - jnotepadTabPane.getSelectionModel().select(tab); + centerTabPane.getSelectionModel().select(tab); return; } } @@ -93,13 +93,13 @@ public class OpenFile implements EventHandler { * @param file 文件对象 */ public static void getText(File file) { - CodeArea textArea = createNewTextArea(); + TextCodeArea textCodeArea = createNewTextArea(); // 检测文件编码 Charset encoding = EncodingDetector.detectEncodingCharset(file); String fileText = getFileText(file, encoding); LogUtil.getLogger(OpenFile.class).info("已调用读取文件功能"); - textArea.appendText(fileText); - CenterTab tab = createNewTab(file.getName(), textArea, encoding); + textCodeArea.appendText(fileText); + CenterTab tab = createNewTab(file.getName(), textCodeArea, encoding); // 设置当前标签页关联本地文件 tab.setRelevance(true); // 设置标签页关联文件 @@ -115,18 +115,18 @@ public class OpenFile implements EventHandler { * * @return 新的文本区域 */ - private static CodeArea createNewTextArea() { - return new CodeArea(); + private static TextCodeArea createNewTextArea() { + return new TextCodeArea(); } /** * 创建新的标签页。 * * @param tabName 标签名 - * @param textArea 文本区域 + * @param textCodeArea 文本区域 * @return 新的标签页 */ - private static CenterTab createNewTab(String tabName, CodeArea textArea, Charset charset) { - return new CenterTab(tabName, textArea, charset); + private static CenterTab createNewTab(String tabName, TextCodeArea textCodeArea, Charset charset) { + return new CenterTab(tabName, textCodeArea, charset); } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/SaveFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/SaveFile.java index acf24ee..31f818d 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/SaveFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menuitem/SaveFile.java @@ -4,13 +4,13 @@ import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.stage.FileChooser; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; -import org.jcnc.jnotepad.cache.entity.Cache; -import org.jcnc.jnotepad.cache.enums.CacheExpirationTime; import org.jcnc.jnotepad.common.constants.TextConstants; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; import org.jcnc.jnotepad.component.stage.dialog.factory.impl.BasicFileChooserFactory; import org.jcnc.jnotepad.controller.config.UserConfigController; import org.jcnc.jnotepad.controller.i18n.LocalizationController; +import org.jcnc.jnotepad.model.entity.Cache; +import org.jcnc.jnotepad.model.enums.CacheExpirationTime; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; diff --git a/src/main/java/org/jcnc/jnotepad/cache/entity/Cache.java b/src/main/java/org/jcnc/jnotepad/model/entity/Cache.java similarity index 98% rename from src/main/java/org/jcnc/jnotepad/cache/entity/Cache.java rename to src/main/java/org/jcnc/jnotepad/model/entity/Cache.java index beffe44..8826144 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/entity/Cache.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/Cache.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.entity; +package org.jcnc.jnotepad.model.entity; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/src/main/java/org/jcnc/jnotepad/model/entity/DefaultContextMenu.java b/src/main/java/org/jcnc/jnotepad/model/entity/DefaultContextMenu.java new file mode 100644 index 0000000..e6770b4 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/model/entity/DefaultContextMenu.java @@ -0,0 +1,56 @@ +package org.jcnc.jnotepad.model.entity; + +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; + +/** + * 默认上下文菜单 + * + * @author gewuyou + */ +public class DefaultContextMenu extends ContextMenu { + private final MenuItem fold; + private final MenuItem unfold; + private final MenuItem print; + + public DefaultContextMenu() { + fold = new MenuItem("折叠所选文本"); + fold.setOnAction(aE -> { + hide(); + fold(); + }); + + unfold = new MenuItem("从光标处展开"); + unfold.setOnAction(aE -> { + hide(); + unfold(); + }); + + print = new MenuItem("打印"); + print.setOnAction(aE -> { + hide(); + print(); + }); + + getItems().addAll(fold, unfold, print); + } + + /** + * 折叠多行所选文本,仅显示第一行并隐藏其余部分。 + */ + private void fold() { + ((org.fxmisc.richtext.CodeArea) getOwnerNode()).foldSelectedParagraphs(); + } + + /** + * 展开当前行/段落(如果有折叠)。 + */ + private void unfold() { + org.fxmisc.richtext.CodeArea area = (org.fxmisc.richtext.CodeArea) getOwnerNode(); + area.unfoldParagraphs(area.getCurrentParagraph()); + } + + private void print() { + System.out.println(((org.fxmisc.richtext.CodeArea) getOwnerNode()).getText()); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/cache/entity/DirFileModel.java b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java similarity index 97% rename from src/main/java/org/jcnc/jnotepad/cache/entity/DirFileModel.java rename to src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java index 1a345a8..0d65f28 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/entity/DirFileModel.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.entity; +package org.jcnc.jnotepad.model.entity; import org.kordamp.ikonli.javafx.FontIcon; diff --git a/src/main/java/org/jcnc/jnotepad/cache/entity/PluginDescriptor.java b/src/main/java/org/jcnc/jnotepad/model/entity/PluginDescriptor.java similarity index 99% rename from src/main/java/org/jcnc/jnotepad/cache/entity/PluginDescriptor.java rename to src/main/java/org/jcnc/jnotepad/model/entity/PluginDescriptor.java index def520b..b7e4f71 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/entity/PluginDescriptor.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/PluginDescriptor.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.entity; +package org.jcnc.jnotepad.model.entity; import com.fasterxml.jackson.annotation.JsonIgnore; import org.jcnc.jnotepad.plugin.interfaces.Plugin; diff --git a/src/main/java/org/jcnc/jnotepad/cache/entity/ShortcutKey.java b/src/main/java/org/jcnc/jnotepad/model/entity/ShortcutKey.java similarity index 93% rename from src/main/java/org/jcnc/jnotepad/cache/entity/ShortcutKey.java rename to src/main/java/org/jcnc/jnotepad/model/entity/ShortcutKey.java index 70a5966..da2650b 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/entity/ShortcutKey.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/ShortcutKey.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.entity; +package org.jcnc.jnotepad.model.entity; /** diff --git a/src/main/java/org/jcnc/jnotepad/model/entity/VisibleParagraphStyler.java b/src/main/java/org/jcnc/jnotepad/model/entity/VisibleParagraphStyler.java new file mode 100644 index 0000000..fc05b01 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/model/entity/VisibleParagraphStyler.java @@ -0,0 +1,47 @@ +package org.jcnc.jnotepad.model.entity; + +import javafx.application.Platform; +import org.fxmisc.richtext.GenericStyledArea; +import org.fxmisc.richtext.model.Paragraph; +import org.fxmisc.richtext.model.StyleSpans; +import org.reactfx.collection.ListModification; + +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * 可见段落样式器 + * + * @author gewuyou + */ +public class VisibleParagraphStyler implements Consumer>> { + private final GenericStyledArea area; + private final Function> computeStyles; + private int prevParagraph; + private int prevTextLength; + + public VisibleParagraphStyler(GenericStyledArea area, Function> computeStyles) { + this.computeStyles = computeStyles; + this.area = area; + } + + @Override + public void accept(ListModification> lm) { + if (lm.getAddedSize() > 0) { + Platform.runLater(() -> { + int paragraph = Math.min(area.firstVisibleParToAllParIndex() + lm.getFrom(), area.getParagraphs().size() - 1); + String text = area.getText(paragraph, 0, paragraph, area.getParagraphLength(paragraph)); + + if (paragraph != prevParagraph || text.length() != prevTextLength) { + if (paragraph < area.getParagraphs().size() - 1) { + int startPos = area.getAbsolutePosition(paragraph, 0); + area.setStyleSpans(startPos, computeStyles.apply(text)); + } + prevTextLength = text.length(); + prevParagraph = paragraph; + } + }); + } + + } +} diff --git a/src/main/java/org/jcnc/jnotepad/cache/enums/CacheExpirationTime.java b/src/main/java/org/jcnc/jnotepad/model/enums/CacheExpirationTime.java similarity index 94% rename from src/main/java/org/jcnc/jnotepad/cache/enums/CacheExpirationTime.java rename to src/main/java/org/jcnc/jnotepad/model/enums/CacheExpirationTime.java index ec8c998..9686842 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/enums/CacheExpirationTime.java +++ b/src/main/java/org/jcnc/jnotepad/model/enums/CacheExpirationTime.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.enums; +package org.jcnc.jnotepad.model.enums; /** * 缓存过期时间枚举 diff --git a/src/main/java/org/jcnc/jnotepad/cache/enums/DialogType.java b/src/main/java/org/jcnc/jnotepad/model/enums/DialogType.java similarity index 88% rename from src/main/java/org/jcnc/jnotepad/cache/enums/DialogType.java rename to src/main/java/org/jcnc/jnotepad/model/enums/DialogType.java index 5f38f7f..1f4cecc 100644 --- a/src/main/java/org/jcnc/jnotepad/cache/enums/DialogType.java +++ b/src/main/java/org/jcnc/jnotepad/model/enums/DialogType.java @@ -1,4 +1,4 @@ -package org.jcnc.jnotepad.cache.enums; +package org.jcnc.jnotepad.model.enums; /** * 对话框类型 diff --git a/src/main/java/org/jcnc/jnotepad/plugin/PluginLoader.java b/src/main/java/org/jcnc/jnotepad/plugin/PluginLoader.java index 72a1e0e..09aa933 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/PluginLoader.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/PluginLoader.java @@ -1,9 +1,9 @@ package org.jcnc.jnotepad.plugin; -import org.jcnc.jnotepad.cache.entity.PluginDescriptor; import org.jcnc.jnotepad.common.manager.ThreadPoolManager; import org.jcnc.jnotepad.controller.config.PluginConfigController; import org.jcnc.jnotepad.controller.exception.AppException; +import org.jcnc.jnotepad.model.entity.PluginDescriptor; import org.jcnc.jnotepad.plugin.interfaces.Plugin; import org.jcnc.jnotepad.plugin.manager.PluginManager; import org.jcnc.jnotepad.util.JsonUtil; diff --git a/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java b/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java index 40693c8..70e3a51 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java @@ -1,9 +1,9 @@ package org.jcnc.jnotepad.plugin.manager; import org.jcnc.jnotepad.app.manager.ApplicationManager; -import org.jcnc.jnotepad.cache.entity.PluginDescriptor; import org.jcnc.jnotepad.common.manager.ThreadPoolManager; import org.jcnc.jnotepad.controller.config.PluginConfigController; +import org.jcnc.jnotepad.model.entity.PluginDescriptor; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.PopUpUtil; import org.slf4j.Logger; diff --git a/src/main/java/org/jcnc/jnotepad/util/FileUtil.java b/src/main/java/org/jcnc/jnotepad/util/FileUtil.java index 3ff41e5..c68e316 100644 --- a/src/main/java/org/jcnc/jnotepad/util/FileUtil.java +++ b/src/main/java/org/jcnc/jnotepad/util/FileUtil.java @@ -1,8 +1,8 @@ package org.jcnc.jnotepad.util; -import org.jcnc.jnotepad.cache.entity.DirFileModel; import org.jcnc.jnotepad.controller.event.handler.menuitem.OpenFile; import org.jcnc.jnotepad.controller.exception.AppException; +import org.jcnc.jnotepad.model.entity.DirFileModel; import org.kordamp.ikonli.javafx.FontIcon; import java.io.*; diff --git a/src/main/java/org/jcnc/jnotepad/util/PopUpUtil.java b/src/main/java/org/jcnc/jnotepad/util/PopUpUtil.java index 71bc75d..d205ea8 100644 --- a/src/main/java/org/jcnc/jnotepad/util/PopUpUtil.java +++ b/src/main/java/org/jcnc/jnotepad/util/PopUpUtil.java @@ -1,8 +1,8 @@ package org.jcnc.jnotepad.util; -import org.jcnc.jnotepad.cache.enums.DialogType; import org.jcnc.jnotepad.component.stage.dialog.AppDialogBuilder; import org.jcnc.jnotepad.component.stage.dialog.interfaces.DialogButtonAction; +import org.jcnc.jnotepad.model.enums.DialogType; /** * 弹窗工具类 diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java index a94565a..6e0f024 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java @@ -7,7 +7,7 @@ import javafx.scene.control.Label; import javafx.scene.layout.HBox; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; import org.jcnc.jnotepad.common.constants.TextConstants; -import org.jcnc.jnotepad.component.module.CodeArea; +import org.jcnc.jnotepad.component.module.TextCodeArea; import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; @@ -106,7 +106,7 @@ public class BottomStatusBoxManager { if (instance.getSelected() == null) { return; } - CodeArea textArea = instance.getSelected().getLineNumberTextArea(); + TextCodeArea textArea = instance.getSelected().getLineNumberTextArea(); int caretPosition = textArea.getCaretPosition(); int row = getRow(caretPosition, textArea.getText()); int column = getColumn(caretPosition, textArea.getText()); @@ -128,7 +128,7 @@ public class BottomStatusBoxManager { updateEncodingLabel(centerTab.getCharset().name()); // 添加光标位置变化监听器 - CodeArea textArea = centerTab.getLineNumberTextArea(); + TextCodeArea textArea = centerTab.getLineNumberTextArea(); textArea.caretPositionProperty().addListener((ChangeListener) (observable, oldValue, newValue) -> updateRowColumnLabel(textArea.getCaretPosition(), textArea.getText())); } } diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java index a49d541..2ceeb3e 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java @@ -3,10 +3,10 @@ package org.jcnc.jnotepad.views.manager; import javafx.collections.ObservableList; import javafx.scene.control.Tab; import javafx.stage.Stage; -import org.jcnc.jnotepad.cache.enums.CacheExpirationTime; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; -import org.jcnc.jnotepad.component.module.CodeArea; +import org.jcnc.jnotepad.component.module.TextCodeArea; import org.jcnc.jnotepad.controller.config.UserConfigController; +import org.jcnc.jnotepad.model.enums.CacheExpirationTime; import org.jcnc.jnotepad.util.FileUtil; import org.jcnc.jnotepad.util.PopUpUtil; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; @@ -79,7 +79,7 @@ public class CenterTabPaneManager { } if (tab.isRelevance()) { // 获取当前文本域对象 - CodeArea codeArea = tab.getLineNumberTextArea(); + TextCodeArea textCodeArea = tab.getLineNumberTextArea(); // 获取当前标签页对应文件上次修改时间 Long lastModifiedTime = tab.getLastModifiedTimeOfAssociatedFile(); // 获取对应文件上次修改时间 @@ -95,8 +95,8 @@ public class CenterTabPaneManager { PopUpUtil.questionAlert( "重新加载", file.getAbsolutePath(), "此文件已被外部修改,是否重新加载该文件?", appDialog -> { - codeArea.clear(); - codeArea.appendText(fileText); + textCodeArea.clear(); + textCodeArea.appendText(fileText); appDialog.close(); }, Stage::close, "是", "否"); } diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/DirectorySidebarManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/DirectorySidebarManager.java index cd536e7..0ff640c 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/DirectorySidebarManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/DirectorySidebarManager.java @@ -3,9 +3,9 @@ package org.jcnc.jnotepad.views.manager; import javafx.beans.value.ChangeListener; import javafx.scene.control.SplitPane; import javafx.scene.control.TreeItem; -import org.jcnc.jnotepad.cache.entity.DirFileModel; import org.jcnc.jnotepad.common.manager.ApplicationCacheManager; import org.jcnc.jnotepad.controller.event.handler.menuitem.OpenDirectory; +import org.jcnc.jnotepad.model.entity.DirFileModel; import org.jcnc.jnotepad.util.FileUtil; import org.jcnc.jnotepad.views.root.center.main.MainBorderPane; import org.jcnc.jnotepad.views.root.center.main.center.directory.DirectorySidebarPane; diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java index 5af2759..ffe169c 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java @@ -6,8 +6,8 @@ import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.input.KeyCombination; import org.jcnc.jnotepad.api.core.views.manager.AbstractManager; -import org.jcnc.jnotepad.cache.entity.ShortcutKey; import org.jcnc.jnotepad.controller.config.UserConfigController; +import org.jcnc.jnotepad.model.entity.ShortcutKey; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.views.root.top.menubar.TopMenuBar; import org.jcnc.jnotepad.views.root.top.menubar.menu.*; diff --git a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/directory/DirectorySidebarPane.java b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/directory/DirectorySidebarPane.java index 54ddbf8..9df82d8 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/directory/DirectorySidebarPane.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/directory/DirectorySidebarPane.java @@ -2,8 +2,8 @@ package org.jcnc.jnotepad.views.root.center.main.center.directory; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; -import org.jcnc.jnotepad.cache.entity.DirFileModel; import org.jcnc.jnotepad.controller.event.handler.menuitem.OpenFile; +import org.jcnc.jnotepad.model.entity.DirFileModel; import java.io.File; import java.util.Objects; diff --git a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTab.java b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTab.java index 4cbbb55..e937d88 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTab.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTab.java @@ -2,7 +2,7 @@ package org.jcnc.jnotepad.views.root.center.main.center.tab; import javafx.scene.control.Tab; import org.fxmisc.flowless.VirtualizedScrollPane; -import org.jcnc.jnotepad.component.module.CodeArea; +import org.jcnc.jnotepad.component.module.TextCodeArea; import org.jcnc.jnotepad.controller.config.UserConfigController; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.views.manager.BottomStatusBoxManager; @@ -23,7 +23,7 @@ import java.nio.charset.Charset; */ public class CenterTab extends Tab { Logger logger = LogUtil.getLogger(this.getClass()); - private final CodeArea codeArea; + private final TextCodeArea textCodeArea; /** * 默认关闭自动换行 */ @@ -39,18 +39,18 @@ public class CenterTab extends Tab { private Charset charset = Charset.defaultCharset(); public CenterTab(String tabTitle) { - this(tabTitle, new CodeArea()); + this(tabTitle, new TextCodeArea()); } - public CenterTab(String tabTitle, CodeArea textArea) { + public CenterTab(String tabTitle, TextCodeArea textArea) { this(tabTitle, textArea, Charset.defaultCharset()); } - public CenterTab(String tabTitle, CodeArea textArea, Charset charset) { + public CenterTab(String tabTitle, TextCodeArea textArea, Charset charset) { super(tabTitle); - codeArea = textArea; + textCodeArea = textArea; initTextAreaListeners(); - this.setContent(new VirtualizedScrollPane<>(codeArea)); + this.setContent(new VirtualizedScrollPane<>(textCodeArea)); setAutoLine(UserConfigController.getInstance().getAutoLineConfig()); this.charset = charset; } @@ -69,11 +69,11 @@ public class CenterTab extends Tab { public void setAutoLine(boolean autoLine) { this.autoLine = autoLine; - codeArea.setWrapText(autoLine); + textCodeArea.setWrapText(autoLine); } - public CodeArea getLineNumberTextArea() { - return codeArea; + public TextCodeArea getLineNumberTextArea() { + return textCodeArea; } public Charset getCharset() { @@ -126,7 +126,7 @@ public class CenterTab extends Tab { */ private void initTextAreaListeners() { // 监听主要文本区域的文本变化 - codeArea.textProperty().addListener((observable, oldValue, newValue) -> { + textCodeArea.textProperty().addListener((observable, oldValue, newValue) -> { BottomStatusBoxManager.getInstance().updateWordCountStatusLabel(); saveSelectedFileTab(); }); diff --git a/tool/jpackage.sh b/tool/jpackage.sh new file mode 100644 index 0000000..5c480ad --- /dev/null +++ b/tool/jpackage.sh @@ -0,0 +1,11 @@ +#!/bin/bash +#请在jlink之后通过文件管理器打开tool双击这个脚本,而不是直接使用Idea执行 +cd .. +jpackage \ + --name JNotepad \ + --type app-image \ + -m org.jcnc.jnotepad/org.jcnc.jnotepad.LunchApp \ + --runtime-image ./target/JNotepad/ \ + --icon src/main/resources/img/icon.ico \ + --app-version 1.1.13 \ + --vendor "JCNC" \ No newline at end of file