From f61d308a908e08722efefd280583e5dec89fa36a Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Tue, 26 Sep 2023 21:42:45 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20=E5=88=9B=E5=BB=BA=E5=8D=95=E4=BE=8B?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=AE=A1=E7=90=86=E7=B1=BB=EF=BC=8C=E5=B0=86?= =?UTF-8?q?=E5=8D=95=E4=BE=8B=E7=BB=84=E4=BB=B6=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E4=B8=8E=E5=8D=95=E4=BE=8B=E7=BB=84=E4=BB=B6=E5=88=86=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/manager/ApplicationManager.java | 13 +- .../event/handler/menubar/NewFile.java | 7 +- .../event/handler/menubar/OpenFile.java | 3 +- .../event/handler/menubar/RenameFile.java | 3 +- .../event/handler/menubar/SaveFile.java | 6 +- .../plugin/manager/PluginManager.java | 2 +- .../ui/module/LineNumberTextArea.java | 8 +- .../views/manager/BottomStatusBoxManager.java | 198 ++++++++++++++++++ .../views/manager/CenterTabPaneManager.java | 91 ++++++++ .../RootBottomSideBarVerticalBoxManager.java | 41 ++++ .../jnotepad/views/manager/RootManager.java | 4 +- .../views/manager/TopMenuBarManager.java | 3 +- .../bottom/RootBottomSideBarVerticalBox.java | 19 +- .../root/bottom/status/BottomStatusBox.java | 171 +-------------- .../center/main/center/tab/CenterTabPane.java | 64 +----- .../views/root/top/menu/TopMenuBar.java | 4 +- 16 files changed, 374 insertions(+), 263 deletions(-) create mode 100644 src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java create mode 100644 src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java create mode 100644 src/main/java/org/jcnc/jnotepad/views/manager/RootBottomSideBarVerticalBoxManager.java diff --git a/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java b/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java index 0d47795..52a64a4 100644 --- a/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java +++ b/src/main/java/org/jcnc/jnotepad/app/manager/ApplicationManager.java @@ -17,9 +17,7 @@ import org.jcnc.jnotepad.controller.manager.Controller; import org.jcnc.jnotepad.plugin.manager.PluginManager; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; -import org.jcnc.jnotepad.views.manager.RootManager; -import org.jcnc.jnotepad.views.manager.SidebarToolBarManager; -import org.jcnc.jnotepad.views.manager.TopMenuBarManager; +import org.jcnc.jnotepad.views.manager.*; import org.slf4j.Logger; import java.util.List; @@ -65,11 +63,15 @@ public class ApplicationManager { // 初始化scene initScene(); // 初始化插件 - PluginManager.getInstance().initializePlugins(); + PluginManager.getInstance().initPlugins(); // 初始化顶部菜单栏 TopMenuBarManager.getInstance().initTopMenuBar(); // 初始化侧边工具栏 SidebarToolBarManager.getInstance().initSidebarToolBar(); + // 初始化下方状态栏 + BottomStatusBoxManager.getInstance().initStatusBox(); + // 初始标签页布局组件 + CenterTabPaneManager.getInstance().initCenterTabPane(); // 初始化ui组件 initUiComponents(); // 初始化primaryStage @@ -159,6 +161,8 @@ public class ApplicationManager { // 加载组件 RootManager rootManager = RootManager.getInstance(scene); rootManager.initScreen(scene); + // 初始化底部根侧边栏垂直布局 + RootBottomSideBarVerticalBoxManager.getInstance().initSidebarVerticalBox(); } public Pane getRoot() { @@ -187,6 +191,5 @@ public class ApplicationManager { public void stopApplication() { Platform.exit(); -// application.stop(); } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/NewFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/NewFile.java index e6ed2c4..204aeae 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/NewFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/NewFile.java @@ -7,7 +7,8 @@ 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.ui.module.LineNumberTextArea; -import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; +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; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; @@ -69,8 +70,8 @@ public class NewFile implements EventHandler { // 设置当前标签页与本地文件无关联 centerTab.setRelevance(false); // 将Tab页添加到TabPane中 - CenterTabPane.getInstance().addNewTab(centerTab); + CenterTabPaneManager.getInstance().addNewTab(centerTab); // 更新编码信息 - BottomStatusBox.getInstance().updateEncodingLabel(); + BottomStatusBoxManager.getInstance().updateEncodingLabel(); } } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java index a9c1fe1..3f4fbae 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/OpenFile.java @@ -14,6 +14,7 @@ import org.jcnc.jnotepad.ui.module.LineNumberTextArea; import org.jcnc.jnotepad.util.EncodingDetector; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; +import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; @@ -126,7 +127,7 @@ public class OpenFile implements EventHandler { // 设置当前标签页关联本地文件 tab.setRelevance(true); tab.setUserData(file); - CenterTabPane.getInstance().addNewTab(tab); + CenterTabPaneManager.getInstance().addNewTab(tab); }); } catch (IOException ignored) { LogUtil.getLogger(this.getClass()).info("已忽视IO异常!"); diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java index 32cb018..57bf5e5 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/RenameFile.java @@ -11,6 +11,7 @@ import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.PopUpUtil; import org.jcnc.jnotepad.util.UiUtil; +import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.slf4j.Logger; @@ -31,7 +32,7 @@ public class RenameFile implements EventHandler { @Override public void handle(ActionEvent actionEvent) { // 获取当前标签页 - CenterTab centerTab = CenterTabPane.getInstance().getSelected(); + CenterTab centerTab = CenterTabPaneManager.getInstance().getSelected(); if (centerTab == null || centerTab.getText().isEmpty()) { return; } diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java index 9556b67..ef71642 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/menubar/SaveFile.java @@ -10,9 +10,9 @@ import org.jcnc.jnotepad.controller.i18n.LocalizationController; import org.jcnc.jnotepad.ui.dialog.factory.impl.BasicFileChooserFactory; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; +import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; import org.jcnc.jnotepad.views.manager.TopMenuBarManager; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.slf4j.Logger; import java.io.File; @@ -40,7 +40,7 @@ public class SaveFile implements EventHandler { @Override public void handle(ActionEvent actionEvent) { // 获取当前tab页 - CenterTab selectedTab = CenterTabPane.getInstance().getSelected(); + CenterTab selectedTab = CenterTabPaneManager.getInstance().getSelected(); if (selectedTab == null) { return; } @@ -72,7 +72,7 @@ public class SaveFile implements EventHandler { * @see LogUtil */ protected void saveTab(Class currentClass) { - CenterTab selectedTab = CenterTabPane.getInstance().getSelected(); + CenterTab selectedTab = CenterTabPaneManager.getInstance().getSelected(); if (selectedTab == null) { return; } 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 418236a..adc8e8e 100644 --- a/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java +++ b/src/main/java/org/jcnc/jnotepad/plugin/manager/PluginManager.java @@ -113,7 +113,7 @@ public class PluginManager { /** * 初始化所有启用的插件 */ - public void initializePlugins() { + public void initPlugins() { for (PluginDescriptor pluginDescriptor : pluginDescriptors) { if (pluginDescriptor.isEnabled()) { pluginDescriptor.getPlugin().initialize(); diff --git a/src/main/java/org/jcnc/jnotepad/ui/module/LineNumberTextArea.java b/src/main/java/org/jcnc/jnotepad/ui/module/LineNumberTextArea.java index e13cc1d..ff995bd 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/module/LineNumberTextArea.java +++ b/src/main/java/org/jcnc/jnotepad/ui/module/LineNumberTextArea.java @@ -4,9 +4,9 @@ import javafx.geometry.Insets; import org.fxmisc.richtext.LineNumberFactory; import org.fxmisc.richtext.StyleClassedTextArea; import org.jcnc.jnotepad.util.LogUtil; -import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; +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; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.slf4j.Logger; import java.io.BufferedWriter; @@ -51,7 +51,7 @@ public class LineNumberTextArea extends StyleClassedTextArea { private void initListeners() { // 监听主要文本区域的文本变化 this.textProperty().addListener((observable, oldValue, newValue) -> { - BottomStatusBox.getInstance().updateWordCountStatusLabel(); + BottomStatusBoxManager.getInstance().updateWordCountStatusLabel(); save(); }); } @@ -61,7 +61,7 @@ public class LineNumberTextArea extends StyleClassedTextArea { */ public void save() { // 获取当前选定的中央标签页(CenterTab对象) - CenterTab tab = CenterTabPane.getInstance().getSelected(); + CenterTab tab = CenterTabPaneManager.getInstance().getSelected(); // 如果没有选定标签页,返回,不执行保存操作 if (tab == null) { diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java new file mode 100644 index 0000000..ed12a5b --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/views/manager/BottomStatusBoxManager.java @@ -0,0 +1,198 @@ +package org.jcnc.jnotepad.views.manager; + +import javafx.beans.value.ChangeListener; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +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.ui.module.LineNumberTextArea; +import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; +import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; + +import java.nio.charset.Charset; + +/** + * 状态栏组件管理类 + * + * @author gewuyou + */ +public class BottomStatusBoxManager { + private static final BottomStatusBoxManager INSTANCE = new BottomStatusBoxManager(); + + private static final BottomStatusBox BOTTOM_STATUS_BOX = BottomStatusBox.getInstance(); + + private static final String STATUS_LABEL_FORMAT = "%s : %d \t%s: %d \t%s: %d \t"; + + private String style = "-fx-background-color: rgba(43,43,43,0.12);"; + + public static BottomStatusBoxManager getInstance() { + return INSTANCE; + } + + /** + * 初始化状态栏 + */ + public void initStatusBox() { + BOTTOM_STATUS_BOX.setStyle(style); + BOTTOM_STATUS_BOX.getChildren().clear(); + registerBottomStatusBox(); + updateEncodingLabel(); + updateWhenTabSelected(); + BOTTOM_STATUS_BOX.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10)); + BOTTOM_STATUS_BOX.setAlignment(Pos.BASELINE_RIGHT); + UiResourceBundle.getInstance().addListener((observable, oldValue, newValue) -> updateWhenTabSelected()); + + /* + 第一个参数 10 表示上边距。 + 第二个参数 10 表示右边距。 + 第三个参数 10 表示下边距。 + 第四个参数 10 表示左边距。 + */ + HBox.setMargin(BOTTOM_STATUS_BOX.getStatusLabel(), new Insets(5, 10, 5, 10)); + } + + /** + * 注册下方状态栏 + */ + public void registerBottomStatusBox() { + Label statusLabel = BOTTOM_STATUS_BOX.getStatusLabel(); + registerChildrenByLabel(statusLabel); + statusLabel.setText(getStatusBarFormattedText(0, 0, 1)); + + registerChildrenByLabel(BOTTOM_STATUS_BOX.getEncodingLabel()); + } + + /** + * 设置状态栏样式 + * + * @param style 样式字符串 + */ + public void setBottomStatusBoxStyle(String style) { + this.style = style; + } + + /** + * 注册状态栏标签组件 + * + * @param label 标签组件 + */ + public void registerChildrenByLabel(Label label) { + BOTTOM_STATUS_BOX.getChildren().add(label); + } + + public void updateEncodingLabel() { + updateEncodingLabel(null); + } + + /** + * 更新编码展示 + * + * @param encoding 文件编码 + */ + public void updateEncodingLabel(String encoding) { + if (encoding == null) { + encoding = Charset.defaultCharset().name(); + } + BOTTOM_STATUS_BOX.getEncodingLabel().setText(getEncodingFormattedText(encoding) + "\t"); + } + + /** + * 更新字数统计 + */ + public void updateWordCountStatusLabel() { + CenterTabPaneManager instance = CenterTabPaneManager.getInstance(); + if (instance.getSelected() == null) { + return; + } + LineNumberTextArea textArea = instance.getSelected().getLineNumberTextArea(); + int caretPosition = textArea.getCaretPosition(); + int row = getRow(caretPosition, textArea.getText()); + int column = getColumn(caretPosition, textArea.getText()); + int length = textArea.getLength(); + BOTTOM_STATUS_BOX.getStatusLabel().setText(getStatusBarFormattedText(row, column, length)); + } + + /** + * Tab选中时,更新状态栏 + *
1. 状态栏更新当前选中tab的数字统计 + *
2. 状态栏更新当前选中tab的字符编码 + */ + public void updateWhenTabSelected() { + CenterTabPaneManager instance = CenterTabPaneManager.getInstance(); + if (instance.getSelected() != null) { + updateWordCountStatusLabel(); + CenterTab centerTab = instance.getSelected(); + if (centerTab != null) { + updateEncodingLabel(centerTab.getCharset().name()); + + // 添加光标位置变化监听器 + LineNumberTextArea textArea = centerTab.getLineNumberTextArea(); + textArea.caretPositionProperty().addListener((ChangeListener) (observable, oldValue, newValue) -> updateRowColumnLabel(textArea.getCaretPosition(), textArea.getText())); + } + } + } + + /** + * 更新行列信息 + * + * @param caretPosition 光标位置 + * @param text 文本内容 + */ + public void updateRowColumnLabel(int caretPosition, String text) { + int row = getRow(caretPosition, text); + int column = getColumn(caretPosition, text); + BOTTOM_STATUS_BOX.getStatusLabel().setText(getStatusBarFormattedText(row, column, text.length())); + } + + + /** + * 获取光标所在行号。 + * + * @param caretPosition 光标位置 + * @param text 文本内容 + * @return 光标所在行号 + */ + public int getRow(int caretPosition, String text) { + caretPosition = Math.min(caretPosition, text.length()); + String substring = text.substring(0, caretPosition); + int count = 0; + for (char c : substring.toCharArray()) { + if (c == '\n') { + count++; + } + } + return count + 1; + } + + /** + * 获取光标所在列号。 + * + * @param caretPosition 光标位置 + * @param text 文本内容 + * @return 光标所在列号 + */ + public int getColumn(int caretPosition, String text) { + return caretPosition - text.lastIndexOf("\n", caretPosition - 1); + } + + public String getStatusBarFormattedText(int row, int column, int wordCount) { + String rowText = UiResourceBundle.getContent(TextConstants.ROW); + String columnText = UiResourceBundle.getContent(TextConstants.COLUMN); + String wordCountText = UiResourceBundle.getContent(TextConstants.WORD_COUNT); + return String.format(STATUS_LABEL_FORMAT, + rowText, + row, + columnText, + column, + wordCountText, + wordCount + ); + } + + public String getEncodingFormattedText(String encoding) { + String encodingLabelFormat = "%s : %s"; + return String.format(encodingLabelFormat, UiResourceBundle.getContent(TextConstants.ENCODE), encoding); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java new file mode 100644 index 0000000..45ba703 --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/views/manager/CenterTabPaneManager.java @@ -0,0 +1,91 @@ +package org.jcnc.jnotepad.views.manager; + +import org.jcnc.jnotepad.controller.config.AppConfigController; +import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; +import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; +import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar; + +/** + * 中心标签页窗格管理类 + * + * @author gewuyou + */ +public class CenterTabPaneManager { + private static final CenterTabPaneManager INSTANCE = new CenterTabPaneManager(); + + private final CenterTabPane centerTabPane = CenterTabPane.getInstance(); + + private final BottomStatusBoxManager bottomStatusBoxManager = BottomStatusBoxManager.getInstance(); + + private CenterTabPaneManager() { + + } + + public static CenterTabPaneManager getInstance() { + return INSTANCE; + } + + /** + * 初始化标签页布局组件 + */ + public void initCenterTabPane() { + initListeners(); + } + + + /** + * 初始化监听器 + */ + private void initListeners() { + // tab选中行为监听器,用于tab切换后,更新与当前tab相关的组件 + centerTabPane.getSelectionModel().selectedItemProperty().addListener( + (ov, from, to) -> { + if (to != null) { + // 更新菜单栏中与tab相关设置 + TopMenuBar.getInstance().updateMenuStatusBySelectedTab(); + } + // 更新状态标签 + bottomStatusBoxManager.updateWhenTabSelected(); + } + ); + } + + /** + * 添加新tab并设置为选中状态 + * + * @param tab 新标签页 + */ + public void addNewTab(CenterTab tab) { + if (tab == null) { + return; + } + // 将标签页加入标签页列表 + centerTabPane.getTabs().add(tab); + // 设置索引 + centerTabPane.getSelectionModel().select(tab); + // 将标签页设置为选中状态 + fireTabSelected(); + } + + /** + * 获取选中的标签页 + * + * @return 当前选中的标签页 + */ + public CenterTab getSelected() { + return (CenterTab) centerTabPane.getSelectionModel().getSelectedItem(); + } + + /** + * tab选中行为。 + * 应用当前菜单上选中的自动换行设置。 + */ + public void fireTabSelected() { + CenterTab selectedTab = getSelected(); + if (selectedTab == null) { + return; + } + selectedTab.setAutoLine(AppConfigController.getInstance().getAutoLineConfig()); + bottomStatusBoxManager.updateWhenTabSelected(); + } +} diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/RootBottomSideBarVerticalBoxManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/RootBottomSideBarVerticalBoxManager.java new file mode 100644 index 0000000..107b4ab --- /dev/null +++ b/src/main/java/org/jcnc/jnotepad/views/manager/RootBottomSideBarVerticalBoxManager.java @@ -0,0 +1,41 @@ +package org.jcnc.jnotepad.views.manager; + +import javafx.scene.layout.VBox; +import org.jcnc.jnotepad.views.root.bottom.RootBottomSideBarVerticalBox; +import org.jcnc.jnotepad.views.root.bottom.function.FunctionBox; +import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; + +/** + * 底部根侧边栏垂直布局管理类 + * + * @author gewuyou + */ +public class RootBottomSideBarVerticalBoxManager { + private static final RootBottomSideBarVerticalBoxManager INSTANCE = new RootBottomSideBarVerticalBoxManager(); + + private final RootBottomSideBarVerticalBox rootBottomSideBarVerticalBox = RootBottomSideBarVerticalBox.getInstance(); + + private RootBottomSideBarVerticalBoxManager() { + + } + + public static RootBottomSideBarVerticalBoxManager getInstance() { + return INSTANCE; + } + + /** + * 初始化底部根侧边栏垂直布局 + */ + + public void initSidebarVerticalBox() { + FunctionBox functionBox = FunctionBox.getInstance(); + VBox vbox = rootBottomSideBarVerticalBox.getVbox(); + if (!FunctionBox.getMenuBar().getMenus().isEmpty()) { + functionBox.getChildren().add(FunctionBox.getMenuBar()); + vbox.getChildren().addAll(functionBox); + } + vbox.getChildren().addAll(BottomStatusBox.getInstance()); + rootBottomSideBarVerticalBox.getChildren().addAll(vbox); + + } +} diff --git a/src/main/java/org/jcnc/jnotepad/views/manager/RootManager.java b/src/main/java/org/jcnc/jnotepad/views/manager/RootManager.java index 5c2996a..8bdcbdb 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/RootManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/RootManager.java @@ -5,8 +5,6 @@ import javafx.scene.layout.BorderPane; import org.jcnc.jnotepad.exception.AppException; import org.jcnc.jnotepad.views.root.RootBorderPane; -import static org.jcnc.jnotepad.views.root.bottom.RootBottomSideBarVerticalBox.initSidebarVerticalBox; - /** * 根布局管理器类,用于管理记事本应用程序的根布局组件。 * @@ -72,6 +70,6 @@ public class RootManager { root.setCenter(RootBorderPane.getInstance()); scene.setRoot(root); - initSidebarVerticalBox(); + } } 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 224153d..6b8c845 100644 --- a/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java +++ b/src/main/java/org/jcnc/jnotepad/views/manager/TopMenuBarManager.java @@ -17,7 +17,6 @@ import org.jcnc.jnotepad.model.entity.ShortcutKey; import org.jcnc.jnotepad.ui.pluginstage.PluginManagementPane; import org.jcnc.jnotepad.util.LogUtil; import org.jcnc.jnotepad.util.UiUtil; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar; import org.slf4j.Logger; @@ -97,7 +96,7 @@ public class TopMenuBarManager { // 1. 更新全局配置 AppConfigController.getInstance().setAutoLineConfig(after); // 2. 对当前tab生效配置 - CenterTabPane.getInstance().fireTabSelected(); + CenterTabPaneManager.getInstance().fireTabSelected(); }); topMenuBar.getLineFeedItem().selectedProperty().set(true); diff --git a/src/main/java/org/jcnc/jnotepad/views/root/bottom/RootBottomSideBarVerticalBox.java b/src/main/java/org/jcnc/jnotepad/views/root/bottom/RootBottomSideBarVerticalBox.java index 05fffce..336fbd0 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/bottom/RootBottomSideBarVerticalBox.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/bottom/RootBottomSideBarVerticalBox.java @@ -2,8 +2,6 @@ package org.jcnc.jnotepad.views.root.bottom; import javafx.scene.layout.VBox; import org.jcnc.jnotepad.ui.module.AbstractVerticalBox; -import org.jcnc.jnotepad.views.root.bottom.function.FunctionBox; -import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; /** * 底部根侧边栏垂直布局 @@ -17,7 +15,7 @@ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { /** * VBox实例 */ - private static final VBox V_BOX_INSTANCE = new VBox(); + private final VBox vBox = new VBox(); /** * 获取 RootBottomSideBarVerticalBox 的唯一实例。 @@ -37,21 +35,10 @@ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { * * @return VBox */ - public static VBox getVboxInstance() { - return V_BOX_INSTANCE; + public VBox getVbox() { + return vBox; } private static final RootBottomSideBarVerticalBox INSTANCE = new RootBottomSideBarVerticalBox(); - public static void initSidebarVerticalBox() { - FunctionBox functionBox = FunctionBox.getInstance(); - if (!FunctionBox.getMenuBar().getMenus().isEmpty()) { - functionBox.getChildren().add(FunctionBox.getMenuBar()); - V_BOX_INSTANCE.getChildren().addAll(functionBox); - } - V_BOX_INSTANCE.getChildren().addAll(BottomStatusBox.getInstance()); - INSTANCE.getChildren().addAll(V_BOX_INSTANCE); - - } - } diff --git a/src/main/java/org/jcnc/jnotepad/views/root/bottom/status/BottomStatusBox.java b/src/main/java/org/jcnc/jnotepad/views/root/bottom/status/BottomStatusBox.java index 8675bb3..4ebc6c0 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/bottom/status/BottomStatusBox.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/bottom/status/BottomStatusBox.java @@ -1,18 +1,7 @@ package org.jcnc.jnotepad.views.root.bottom.status; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.geometry.Insets; -import javafx.geometry.Pos; import javafx.scene.control.Label; -import org.jcnc.jnotepad.app.i18n.UiResourceBundle; -import org.jcnc.jnotepad.common.constants.TextConstants; import org.jcnc.jnotepad.ui.module.AbstractHorizontalBox; -import org.jcnc.jnotepad.ui.module.LineNumberTextArea; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; - -import java.nio.charset.Charset; /** * 状态栏组件封装。 @@ -23,171 +12,31 @@ import java.nio.charset.Charset; */ public class BottomStatusBox extends AbstractHorizontalBox { - private static final BottomStatusBox STATUS_BOX = new BottomStatusBox(); - private static final String STATUS_LABEL_FORMAT = "%s : %d \t%s: %d \t%s: %d \t"; + private static final BottomStatusBox INSTANCE = new BottomStatusBox(); + /** * 字数统计及光标 */ - private Label statusLabel; + private final Label statusLabel = new Label(); /** * 显示文本编码 */ - private Label encodingLabel; - + private final Label encodingLabel = new Label(); private BottomStatusBox() { - initStatusBox(); - } - public static BottomStatusBox getInstance() { - return STATUS_BOX; } - /** - * 初始化状态栏组件 - */ - public void initStatusBox() { - this.setStyle("-fx-background-color: rgba(43,43,43,0.12);"); - - this.getChildren().clear(); - // 创建状态栏 - statusLabel = new Label(); - statusLabel.setText(getStatusBarFormattedText(0, 0, 1)); - // 创建新的标签以显示编码信息 - encodingLabel = new Label(); - updateEncodingLabel(); - updateWhenTabSelected(); - this.getChildren().add(statusLabel); - this.getChildren().add(encodingLabel); - this.getProperties().put("borderpane-margin", new Insets(5, 10, 5, 10)); - this.setAlignment(Pos.BASELINE_RIGHT); - UiResourceBundle.getInstance().addListener((observable, oldValue, newValue) -> updateWhenTabSelected()); - - /* - 第一个参数 10 表示上边距。 - 第二个参数 10 表示右边距。 - 第三个参数 10 表示下边距。 - 第四个参数 10 表示左边距。 - */ - setMargin(statusLabel, new Insets(5, 10, 5, 10)); - } - - public void updateEncodingLabel() { - updateEncodingLabel(null); - } - - /** - * 更新编码展示 - * - * @param encoding 文件编码 - */ - public void updateEncodingLabel(String encoding) { - if (encoding == null) { - encoding = Charset.defaultCharset().name(); - } - this.encodingLabel.setText(getEncodingFormattedText(encoding) + "\t"); - } - - /** - * 更新字数统计 - */ - public void updateWordCountStatusLabel() { - CenterTabPane instance = CenterTabPane.getInstance(); - if (instance.getSelected() == null) { - return; - } - LineNumberTextArea textArea = instance.getSelected().getLineNumberTextArea(); - int caretPosition = textArea.getCaretPosition(); - int row = getRow(caretPosition, textArea.getText()); - int column = getColumn(caretPosition, textArea.getText()); - int length = textArea.getLength(); - this.statusLabel.setText(getStatusBarFormattedText(row, column, length)); - } - - /** - * Tab选中时,更新状态栏 - *
1. 状态栏更新当前选中tab的数字统计 - *
2. 状态栏更新当前选中tab的字符编码 - */ - public void updateWhenTabSelected() { - CenterTabPane instance = CenterTabPane.getInstance(); - if (instance.getSelected() != null) { - updateWordCountStatusLabel(); - CenterTab centerTab = instance.getSelected(); - if (centerTab != null) { - updateEncodingLabel(centerTab.getCharset().name()); - - // 添加光标位置变化监听器 - LineNumberTextArea textArea = centerTab.getLineNumberTextArea(); - textArea.caretPositionProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Number oldValue, Number newValue) { - updateRowColumnLabel(textArea.getCaretPosition(), textArea.getText()); - } - }); - } - } - } - - /** - * 更新行列信息 - * - * @param caretPosition 光标位置 - * @param text 文本内容 - */ - private void updateRowColumnLabel(int caretPosition, String text) { - int row = getRow(caretPosition, text); - int column = getColumn(caretPosition, text); - statusLabel.setText(getStatusBarFormattedText(row, column, text.length())); - } - - - /** - * 获取光标所在行号。 - * - * @param caretPosition 光标位置 - * @param text 文本内容 - * @return 光标所在行号 - */ - public int getRow(int caretPosition, String text) { - caretPosition = Math.min(caretPosition, text.length()); - String substring = text.substring(0, caretPosition); - int count = 0; - for (char c : substring.toCharArray()) { - if (c == '\n') { - count++; - } - } - return count + 1; + public static BottomStatusBox getInstance() { + return INSTANCE; } - /** - * 获取光标所在列号。 - * - * @param caretPosition 光标位置 - * @param text 文本内容 - * @return 光标所在列号 - */ - public int getColumn(int caretPosition, String text) { - return caretPosition - text.lastIndexOf("\n", caretPosition - 1); - } - protected String getStatusBarFormattedText(int row, int column, int wordCount) { - String rowText = UiResourceBundle.getContent(TextConstants.ROW); - String columnText = UiResourceBundle.getContent(TextConstants.COLUMN); - String wordCountText = UiResourceBundle.getContent(TextConstants.WORD_COUNT); - return String.format(STATUS_LABEL_FORMAT, - rowText, - row, - columnText, - column, - wordCountText, - wordCount - ); + public Label getStatusLabel() { + return statusLabel; } - protected String getEncodingFormattedText(String encoding) { - String encodingLabelFormat = "%s : %s"; - return String.format(encodingLabelFormat, UiResourceBundle.getContent(TextConstants.ENCODE), encoding); + public Label getEncodingLabel() { + return encodingLabel; } } diff --git a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTabPane.java b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTabPane.java index bc10ee1..8a774b3 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTabPane.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/center/main/center/tab/CenterTabPane.java @@ -1,9 +1,6 @@ package org.jcnc.jnotepad.views.root.center.main.center.tab; import javafx.scene.control.TabPane; -import org.jcnc.jnotepad.controller.config.AppConfigController; -import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox; -import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar; /** * 标签页布局组件封装。 @@ -12,69 +9,14 @@ import org.jcnc.jnotepad.views.root.top.menu.TopMenuBar; */ public class CenterTabPane extends TabPane { - private static final CenterTabPane TAB_PANE = new CenterTabPane(); + private static final CenterTabPane INSTANCE = new CenterTabPane(); private CenterTabPane() { - initListeners(); - } - - public static CenterTabPane getInstance() { - return TAB_PANE; - } - /** - * 初始化监听器 - */ - private void initListeners() { - // tab选中行为监听器,用于tab切换后,更新与当前tab相关的组件 - this.getSelectionModel().selectedItemProperty().addListener( - (ov, from, to) -> { - if (to != null) { - // 更新菜单栏中与tab相关设置 - TopMenuBar.getInstance().updateMenuStatusBySelectedTab(); - } - // 更新状态标签 - BottomStatusBox.getInstance().updateWhenTabSelected(); - } - ); } - /** - * 添加新tab并设置为选中状态 - * - * @param tab 新标签页 - */ - public void addNewTab(CenterTab tab) { - if (tab == null) { - return; - } - // 将标签页加入标签页列表 - this.getTabs().add(tab); - // 设置索引 - this.getSelectionModel().select(tab); - // 将标签页设置为选中状态 - fireTabSelected(); - } - - /** - * 获取选中的标签页 - * - * @return 当前选中的标签页 - */ - public CenterTab getSelected() { - return (CenterTab) this.getSelectionModel().getSelectedItem(); + public static CenterTabPane getInstance() { + return INSTANCE; } - /** - * tab选中行为。 - * 应用当前菜单上选中的自动换行设置。 - */ - public void fireTabSelected() { - CenterTab selectedTab = getSelected(); - if (selectedTab == null) { - return; - } - selectedTab.setAutoLine(AppConfigController.getInstance().getAutoLineConfig()); - BottomStatusBox.getInstance().updateWhenTabSelected(); - } } diff --git a/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java b/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java index a5c0cd7..550293b 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java @@ -1,8 +1,8 @@ package org.jcnc.jnotepad.views.root.top.menu; import javafx.scene.control.*; +import org.jcnc.jnotepad.views.manager.CenterTabPaneManager; import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab; -import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane; import java.util.HashMap; import java.util.Map; @@ -22,7 +22,7 @@ public class TopMenuBar extends MenuBar { /** * 标签页布局组件封装。 */ - CenterTabPane centerTabPane = CenterTabPane.getInstance(); + CenterTabPaneManager centerTabPane = CenterTabPaneManager.getInstance(); /** * 文件菜单 */ -- Gitee