♻️ 重构代码 创建单例组件管理类,将单例组件初始化与单例组件分离
This commit is contained in:
parent
bf5284e6de
commit
f61d308a90
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ActionEvent> {
|
||||
// 设置当前标签页与本地文件无关联
|
||||
centerTab.setRelevance(false);
|
||||
// 将Tab页添加到TabPane中
|
||||
CenterTabPane.getInstance().addNewTab(centerTab);
|
||||
CenterTabPaneManager.getInstance().addNewTab(centerTab);
|
||||
// 更新编码信息
|
||||
BottomStatusBox.getInstance().updateEncodingLabel();
|
||||
BottomStatusBoxManager.getInstance().updateEncodingLabel();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ActionEvent> {
|
||||
// 设置当前标签页关联本地文件
|
||||
tab.setRelevance(true);
|
||||
tab.setUserData(file);
|
||||
CenterTabPane.getInstance().addNewTab(tab);
|
||||
CenterTabPaneManager.getInstance().addNewTab(tab);
|
||||
});
|
||||
} catch (IOException ignored) {
|
||||
LogUtil.getLogger(this.getClass()).info("已忽视IO异常!");
|
||||
|
||||
@ -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<ActionEvent> {
|
||||
@Override
|
||||
public void handle(ActionEvent actionEvent) {
|
||||
// 获取当前标签页
|
||||
CenterTab centerTab = CenterTabPane.getInstance().getSelected();
|
||||
CenterTab centerTab = CenterTabPaneManager.getInstance().getSelected();
|
||||
if (centerTab == null || centerTab.getText().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -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<ActionEvent> {
|
||||
@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<ActionEvent> {
|
||||
* @see LogUtil
|
||||
*/
|
||||
protected void saveTab(Class<?> currentClass) {
|
||||
CenterTab selectedTab = CenterTabPane.getInstance().getSelected();
|
||||
CenterTab selectedTab = CenterTabPaneManager.getInstance().getSelected();
|
||||
if (selectedTab == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ public class PluginManager {
|
||||
/**
|
||||
* 初始化所有启用的插件
|
||||
*/
|
||||
public void initializePlugins() {
|
||||
public void initPlugins() {
|
||||
for (PluginDescriptor pluginDescriptor : pluginDescriptors) {
|
||||
if (pluginDescriptor.isEnabled()) {
|
||||
pluginDescriptor.getPlugin().initialize();
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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选中时,更新状态栏
|
||||
* <br>1. 状态栏更新当前选中tab的数字统计
|
||||
* <br>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<Number>) (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);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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选中时,更新状态栏
|
||||
* <br>1. 状态栏更新当前选中tab的数字统计
|
||||
* <br>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<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> 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()));
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取光标所在行号。
|
||||
*
|
||||
* @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 Label getStatusLabel() {
|
||||
return statusLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取光标所在列号。
|
||||
*
|
||||
* @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
|
||||
);
|
||||
}
|
||||
|
||||
protected String getEncodingFormattedText(String encoding) {
|
||||
String encodingLabelFormat = "%s : %s";
|
||||
return String.format(encodingLabelFormat, UiResourceBundle.getContent(TextConstants.ENCODE), encoding);
|
||||
public Label getEncodingLabel() {
|
||||
return encodingLabel;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化监听器
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* tab选中行为。
|
||||
* 应用当前菜单上选中的自动换行设置。
|
||||
*/
|
||||
public void fireTabSelected() {
|
||||
CenterTab selectedTab = getSelected();
|
||||
if (selectedTab == null) {
|
||||
return;
|
||||
}
|
||||
selectedTab.setAutoLine(AppConfigController.getInstance().getAutoLineConfig());
|
||||
BottomStatusBox.getInstance().updateWhenTabSelected();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
/**
|
||||
* 文件菜单
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user