From 694cd2a4481e317ba5457edf013d12ad99305908 Mon Sep 17 00:00:00 2001 From: gewuyou <1063891901@qq.com> Date: Sat, 14 Oct 2023 18:33:29 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=E2=9A=A1=EF=B8=8F=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=80=A7=E8=83=BD=E9=87=8D=E6=9E=84=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- .../component/stage/AbstractMenuBuilder.java | 138 ---------------- .../config/BaseConfigController.java | 4 +- .../api/core/views/menu/AbstractBaseMenu.java | 26 +--- .../api/core/views/menu/AbstractMenu.java | 67 +++----- .../menu/builder/AbstractMenuBuilder.java | 77 +++++++-- .../menu/builder/ContextMenuBuilder.java | 38 +++-- .../core/views/menu/builder/MenuBuilder.java | 20 +-- .../bottom/AbstractFunctionChildrenBox.java | 1 - .../app/common/constants/TextConstants.java | 75 +++++++++ .../manager/ApplicationCacheManager.java | 2 +- .../jcnc/jnotepad/app/config/AppConfig.java | 9 +- .../jnotepad/app/config/PluginConfig.java | 1 - .../jcnc/jnotepad/app/config/UserConfig.java | 1 - .../org/jcnc/jnotepad/app/utils/FileUtil.java | 4 + .../org/jcnc/jnotepad/app/utils/TabUtil.java | 85 +++++----- .../controller/cache/CacheController.java | 4 +- .../config/AppConfigController.java | 12 +- .../config/PluginConfigController.java | 9 +- .../config/UserConfigController.java | 4 +- .../event/handler/toolbar/OpenDirectory.java | 2 +- .../event/handler/toolbar/RunBtn.java | 1 - .../plugin/manager/PluginManager.java | 4 +- .../jnotepad/model/entity/DirFileModel.java | 13 +- .../ui/component/module/TextCodeArea.java | 33 ++-- .../ui/component/module/vbox/BuildPanel.java | 30 ++-- .../vbox/components/CmdTerminalBox.java | 3 +- .../factory/DirectoryChooserFactory.java | 4 +- .../impl/BasicDirectoryChooserFactory.java | 6 +- .../dialog/interfaces/DialogButtonAction.java | 1 + .../ui/component/stage/setting/SetStage.java | 3 +- .../stage/topmenu/plugin/CustomSplitPane.java | 10 +- .../topmenu/plugin/PluginManagementPane.java | 15 +- .../views/manager/BottomStatusBoxManager.java | 39 ++--- .../ui/views/manager/BuildPanelManager.java | 12 +- .../views/manager/CenterTabPaneManager.java | 147 ++++++++---------- .../manager/DirectorySidebarManager.java | 68 ++++---- .../ui/views/manager/RootManager.java | 35 ++--- .../views/manager/SidebarToolBarManager.java | 2 +- .../ui/views/manager/TopMenuBarManager.java | 2 +- .../bottom/RootBottomSideBarVerticalBox.java | 11 +- .../center/main/center/tab/CenterTab.java | 118 ++++++++++---- .../left/sidebar/tools/SidebarToolBar.java | 2 +- .../ui/views/root/top/menubar/TopMenuBar.java | 19 +-- .../root/top/menubar/menu/FileTopMenu.java | 6 +- .../root/top/menubar/menu/RunTopMenu.java | 39 +++-- src/main/resources/jcnc/app/css/styles.css | 1 + .../resources/jcnc/app/i18n/i18n.properties | 2 - .../jcnc/app/i18n/i18n_en.properties | 15 +- .../jcnc/app/i18n/i18n_zh_CN.properties | 13 ++ 50 files changed, 607 insertions(+), 628 deletions(-) delete mode 100644 src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractMenuBuilder.java diff --git a/.gitignore b/.gitignore index 06d0a2c..16c880f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,4 @@ logs/ /jnotepadConfig.json /qodana.yaml .mvn/ -/main.c +/main.c \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractMenuBuilder.java b/src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractMenuBuilder.java deleted file mode 100644 index 6d6d8f5..0000000 --- a/src/main/java/org/jcnc/jnotepad/api/core/component/stage/AbstractMenuBuilder.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.jcnc.jnotepad.api.core.component.stage; - -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.*; - -/** - * 抽象菜单建造者类 - * - *

- * 该抽象类用于构建菜单,包括菜单项、单选菜单项、复选菜单项、分割线等。 - * 子类应继承此类以实现具体的菜单构建逻辑。 - *

- * - * @param 建造者类型 - * @param 构建结果类型 - * - * @author gewuyou - */ -public abstract class AbstractMenuBuilder { - /** - * 获取子类的建造者实例 - * - * @return 建造者实例 - */ - protected abstract B getBuilder(); - - /** - * 获取菜单的菜单项列表 - * - * @return 菜单项列表 - */ - protected abstract ObservableList getItems(); - - /** - * 添加菜单项 - * - * @param label 菜单项名称 - * @param eventHandler 事件处理器 - * @return 当前建造者实例 - */ - public B addMenuItem(String label, EventHandler eventHandler) { - MenuItem menuItem = new MenuItem(label); - menuItem.setOnAction(eventHandler); - getItems().add(menuItem); - return getBuilder(); - } - - /** - * 添加菜单项 - * - * @param label 菜单项名称 - * @param eventHandler 事件处理器 - * @param disable 是否禁用 - * @return 当前建造者实例 - */ - public B addMenuItem(String label, EventHandler eventHandler, boolean disable) { - if (!disable) { - return getBuilder(); - } - MenuItem menuItem = new MenuItem(label); - menuItem.setOnAction(eventHandler); - getItems().add(menuItem); - return getBuilder(); - } - - /** - * 添加单选菜单项 - * - * @param label 菜单项名称 - * @param eventHandler 事件处理器 - * @return 当前建造者实例 - */ - public B addRadioMenuItem(String label, EventHandler eventHandler) { - RadioMenuItem menuItem = new RadioMenuItem(label); - menuItem.setOnAction(eventHandler); - getItems().add(menuItem); - return getBuilder(); - } - - /** - * 添加复选菜单项 - * - * @param label 菜单项名称 - * @param eventHandler 事件处理器 - * @return 当前建造者实例 - */ - public B addCheckMenuItem(String label, EventHandler eventHandler) { - CheckMenuItem menuItem = new CheckMenuItem(label); - menuItem.setOnAction(eventHandler); - getItems().add(menuItem); - return getBuilder(); - } - - /** - * 添加菜单 - * - * @param menu 菜单 - * @return 当前建造者实例 - */ - public B addMenu(Menu menu) { - getItems().add(menu); - return getBuilder(); - } - - /** - * 添加菜单 - * - * @param menu 菜单 - * @param disable 是否禁用 - * @return 当前建造者实例 - */ - public B addMenu(Menu menu, boolean disable) { - if (!disable) { - return getBuilder(); - } - getItems().add(menu); - return getBuilder(); - } - - /** - * 添加分割线 - * - * @return 当前建造者实例 - */ - public B addSeparatorMenuItem() { - getItems().add(new SeparatorMenuItem()); - return getBuilder(); - } - - /** - * 构建菜单 - * - * @return 构建的菜单 - */ - public abstract T build(); -} diff --git a/src/main/java/org/jcnc/jnotepad/api/core/controller/config/BaseConfigController.java b/src/main/java/org/jcnc/jnotepad/api/core/controller/config/BaseConfigController.java index 6fde0b8..2d520c4 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/controller/config/BaseConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/controller/config/BaseConfigController.java @@ -22,7 +22,6 @@ import java.nio.file.Paths; *

* * @param 配置文件类型 - * * @author gewuyou */ public abstract class BaseConfigController implements ConfigController { @@ -30,9 +29,8 @@ public abstract class BaseConfigController implements ConfigController { protected static final String ROOT_CONFIG_DIR = "config"; protected static final String SYSTEM_CONFIG_DIR = "system"; - - protected T config; private final Logger logger = LogUtil.getLogger(getClass()); + protected T config; /** * 获取配置文件Class类。 diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractBaseMenu.java b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractBaseMenu.java index 39debbf..d70b2df 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractBaseMenu.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractBaseMenu.java @@ -1,14 +1,11 @@ package org.jcnc.jnotepad.api.core.views.menu; +import javafx.collections.ObservableList; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import org.jcnc.jnotepad.app.i18n.UiResourceBundle; -import org.jcnc.jnotepad.controller.config.UserConfigController; import org.jcnc.jnotepad.ui.views.root.top.menubar.TopMenuBar; -import java.util.HashMap; -import java.util.Map; - /** * 抽象基础菜单类 * @@ -20,7 +17,6 @@ import java.util.Map; */ public abstract class AbstractBaseMenu extends AbstractMenu { protected final TopMenuBar topMenuBar = TopMenuBar.getInstance(); - protected final UserConfigController userConfigController = UserConfigController.getInstance(); /** * 获取菜单名称 @@ -30,23 +26,13 @@ public abstract class AbstractBaseMenu extends AbstractMenu { public abstract String getMenuName(); /** - * 初始化菜单项 + * 获取菜单项 * - * @param menuItems 菜单项集合 - * @param menu 菜单 + * @return 菜单项集合 */ @Override - protected void initMenuItems(Map menuItems, Menu menu) { - logger.info("初始化菜单项!"); - Map menuItemMap = new HashMap<>(16); - // 本地化 - menuItems.forEach((key, value) -> { - UiResourceBundle.bindStringProperty(value.textProperty(), key); - menuItemMap.put((String) value.getUserData(), value); - menu.getItems().add(value); - }); - userConfigController.getMenuItems().add(menuItemMap); - userConfigController.initShortcutKeys(menuItemMap); + protected ObservableList getItems() { + return getMenu().getItems(); } /** @@ -60,6 +46,6 @@ public abstract class AbstractBaseMenu extends AbstractMenu { // 菜单名称国际化 UiResourceBundle.bindStringProperty(menu.textProperty(), getMenuName()); // 初始化菜单项 - initMenuItems(getMenuItems(), menu); + initMenuItems(getMenuItems()); } } diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractMenu.java b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractMenu.java index 1b2755e..c438aa6 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractMenu.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/AbstractMenu.java @@ -1,15 +1,18 @@ package org.jcnc.jnotepad.api.core.views.menu; import javafx.beans.value.ChangeListener; +import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.CheckMenuItem; -import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.RadioMenuItem; +import org.jcnc.jnotepad.app.i18n.UiResourceBundle; import org.jcnc.jnotepad.app.utils.LogUtil; +import org.jcnc.jnotepad.controller.config.UserConfigController; import org.slf4j.Logger; +import java.util.HashMap; import java.util.Map; /** @@ -19,6 +22,7 @@ import java.util.Map; */ public abstract class AbstractMenu { protected Logger logger = LogUtil.getLogger(this.getClass()); + UserConfigController userConfigController = UserConfigController.getInstance(); /** * 获取菜单 @@ -44,6 +48,13 @@ public abstract class AbstractMenu { */ protected abstract void initMenu(); + /** + * 获取菜单项 + * + * @return 菜单项集合 + */ + protected abstract ObservableList getItems(); + /** * 注册菜单项 @@ -59,20 +70,6 @@ public abstract class AbstractMenu { menuItem.setOnAction(eventHandler); } - /** - * 注册菜单项 - * - * @param menuItem 菜单项 - * @param menuItemName 菜单项名称 - * @param userData 用户数据,用来存放必要的数据,比如按钮菜单项名称 - * @param eventHandler 事件处理器 - */ - public void registerMenuItem(MenuItem menuItem, String menuItemName, Object userData, EventHandler eventHandler, boolean isDisable) { - if (!isDisable) { - registerMenuItem(menuItem, menuItemName, userData, eventHandler); - } - } - /** * 注册检查菜单项 * @@ -87,32 +84,6 @@ public abstract class AbstractMenu { checkMenuItem.selectedProperty().addListener(listener); } - /** - * 在给定菜单映射中注册具有指定名称、用户数据和事件处理程序的菜单项。 - * - * @param menu 菜单项映射 - * @param menuItemName 要注册的菜单项的名称 - * @param userData 与菜单项关联的用户数据 - */ - public void registerMenu(Menu menu, String menuItemName, Object userData) { - getMenuItems().put(menuItemName, menu); - menu.setUserData(userData); - } - - /** - * Registers a menu item in the specified menu with the given name and user data. - * - * @param menu the menu to register the item in - * @param menuItemName the name of the menu item - * @param userData the user data associated with the menu item - * @param isDisable whether the menu item is disabled - */ - public void registerMenu(Menu menu, String menuItemName, Object userData, boolean isDisable) { - if (!isDisable) { - registerMenu(menu, menuItemName, userData); - } - } - /** * 注册单选菜单项 * @@ -127,12 +98,22 @@ public abstract class AbstractMenu { radioMenuItem.setOnAction(eventHandler); } + /** * 初始化菜单项 * * @param menuItems 菜单项集合 - * @param menu 菜单 */ - protected abstract void initMenuItems(Map menuItems, T menu); + protected void initMenuItems(Map menuItems) { + logger.info("初始化菜单项!"); + Map menuItemMap = new HashMap<>(16); + menuItems.forEach((key, value) -> { + UiResourceBundle.bindStringProperty(value.textProperty(), key); + menuItemMap.put((String) value.getUserData(), value); + getItems().add(value); + }); + userConfigController.getMenuItems().add(menuItemMap); + userConfigController.initShortcutKeys(menuItemMap); + } } diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/AbstractMenuBuilder.java b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/AbstractMenuBuilder.java index 8543f35..519fe54 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/AbstractMenuBuilder.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/AbstractMenuBuilder.java @@ -1,9 +1,15 @@ package org.jcnc.jnotepad.api.core.views.menu.builder; +import javafx.beans.property.BooleanProperty; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.*; +import org.jcnc.jnotepad.app.i18n.UiResourceBundle; +import org.jcnc.jnotepad.controller.config.UserConfigController; + +import java.util.HashMap; +import java.util.Map; /** * 抽象菜单建造者类 @@ -11,6 +17,11 @@ import javafx.scene.control.*; * @author gewuyou */ public abstract class AbstractMenuBuilder { + /** + * 上下文菜单项 + */ + protected final Map menuItems = new HashMap<>(); + /** * Get subclass builder * @@ -18,6 +29,13 @@ public abstract class AbstractMenuBuilder { */ protected abstract B getBuilder(); + /** + * 获取菜单 + * + * @return 菜单 + */ + protected abstract T getMenu(); + /** * Retrieves the items of the menu. * @@ -35,6 +53,7 @@ public abstract class AbstractMenuBuilder { public B addMenuItem(String label, EventHandler eventHandler) { MenuItem menuItem = new MenuItem(label); menuItem.setOnAction(eventHandler); + menuItems.put(label, menuItem); getItems().add(menuItem); return getBuilder(); } @@ -44,15 +63,15 @@ public abstract class AbstractMenuBuilder { * * @param label 菜单项名称 * @param eventHandler 事件 - * @param disable 是否禁用 + * @param visible 是否可见 * @return 建造者 */ - public B addMenuItem(String label, EventHandler eventHandler, boolean disable) { - if (!disable) { - return getBuilder(); - } + public B addMenuItem(String label, EventHandler eventHandler, BooleanProperty visible) { MenuItem menuItem = new MenuItem(label); menuItem.setOnAction(eventHandler); + menuItem.setVisible(visible.get()); + visible.addListener((observable, oldValue, newValue) -> menuItem.setVisible(Boolean.TRUE.equals(newValue))); + menuItems.put(label, menuItem); getItems().add(menuItem); return getBuilder(); } @@ -67,6 +86,7 @@ public abstract class AbstractMenuBuilder { public B addRadioMenuItem(String label, EventHandler eventHandler) { RadioMenuItem menuItem = new RadioMenuItem(label); menuItem.setOnAction(eventHandler); + menuItems.put(label, menuItem); getItems().add(menuItem); return getBuilder(); } @@ -81,10 +101,19 @@ public abstract class AbstractMenuBuilder { public B addCheckMenuItem(String label, EventHandler eventHandler) { CheckMenuItem menuItem = new CheckMenuItem(label); menuItem.setOnAction(eventHandler); + menuItems.put(label, menuItem); getItems().add(menuItem); return getBuilder(); } + + public B addCheckMenuItem(CheckMenuItem checkMenuItem, EventHandler eventHandler) { + checkMenuItem.setOnAction(eventHandler); + menuItems.put(checkMenuItem.getText(), checkMenuItem); + getItems().add(checkMenuItem); + return getBuilder(); + } + /** * 添加菜单 * @@ -92,6 +121,7 @@ public abstract class AbstractMenuBuilder { * @return 建造者 */ public B addMenu(Menu menu) { + menuItems.put(menu.getText(), menu); getItems().add(menu); return getBuilder(); } @@ -100,17 +130,18 @@ public abstract class AbstractMenuBuilder { * 添加菜单 * * @param menu 菜单 - * @param disable 是否禁用 + * @param visible 是否隐藏 * @return 建造者 */ - public B addMenu(Menu menu, boolean disable) { - if (!disable) { - return getBuilder(); - } + public B addMenu(Menu menu, BooleanProperty visible) { + menu.setVisible(visible.get()); + visible.addListener((observable, oldValue, newValue) -> menu.setVisible(Boolean.TRUE.equals(newValue))); + menuItems.put(menu.getText(), menu); getItems().add(menu); return getBuilder(); } + /** * 添加分割线 * @@ -121,11 +152,35 @@ public abstract class AbstractMenuBuilder { return getBuilder(); } + /** + * 添加分割线 + * + * @param visible 是否可见 + * @return 建造者 + */ + public B addSeparatorMenuItem(BooleanProperty visible) { + SeparatorMenuItem separatorMenuItem = new SeparatorMenuItem(); + separatorMenuItem.setVisible(visible.get()); + visible.addListener((observable, oldValue, newValue) -> separatorMenuItem.setVisible(Boolean.TRUE.equals(newValue))); + getItems().add(separatorMenuItem); + return getBuilder(); + } + /** * Build menu * * @return menu */ - public abstract T build(); + public T build() { + UserConfigController userConfigController = UserConfigController.getInstance(); + Map menuItemMap = new HashMap<>(16); + menuItems.forEach((key, value) -> { + UiResourceBundle.bindStringProperty(value.textProperty(), key); + menuItemMap.put((String) value.getUserData(), value); + }); + userConfigController.getMenuItems().add(menuItemMap); + userConfigController.initShortcutKeys(menuItemMap); + return getMenu(); + } } diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/ContextMenuBuilder.java b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/ContextMenuBuilder.java index 4947314..5ac3c6c 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/ContextMenuBuilder.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/ContextMenuBuilder.java @@ -1,7 +1,9 @@ package org.jcnc.jnotepad.api.core.views.menu.builder; +import javafx.beans.property.BooleanProperty; import javafx.collections.ObservableList; import javafx.scene.control.ContextMenu; +import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; /** @@ -12,36 +14,33 @@ import javafx.scene.control.MenuItem; *

* * @author gewuyou - * */ public class ContextMenuBuilder extends AbstractMenuBuilder { + private final ContextMenu contextMenu; - /** - * 构造上下文菜单建造者 - */ public ContextMenuBuilder() { contextMenu = new ContextMenu(); } /** - * 构建并返回上下文菜单对象。 + * 获取子类的建造者实例 * - * @return 构建的上下文菜单对象 + * @return 建造者实例 */ @Override - public ContextMenu build() { - return contextMenu; + protected ContextMenuBuilder getBuilder() { + return this; } /** - * 获取子类的建造者实例 + * 获取菜单 * - * @return 建造者实例 + * @return 菜单 */ @Override - protected ContextMenuBuilder getBuilder() { - return this; + protected ContextMenu getMenu() { + return contextMenu; } /** @@ -53,4 +52,19 @@ public class ContextMenuBuilder extends AbstractMenuBuilder getItems() { return contextMenu.getItems(); } + + /** + * 添加菜单 + * + * @param menu 菜单 + * @param visible 是否隐藏 + * @return 建造者 + */ + @Override + public ContextMenuBuilder addMenu(Menu menu, BooleanProperty visible) { + menu.setVisible(visible.get()); + visible.addListener((observable, oldValue, newValue) -> menu.setVisible(Boolean.TRUE.equals(newValue))); + getItems().add(menu); + return getBuilder(); + } } diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/MenuBuilder.java b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/MenuBuilder.java index 789c6a7..75fba6d 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/MenuBuilder.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/menu/builder/MenuBuilder.java @@ -12,11 +12,12 @@ import javafx.scene.control.MenuItem; *

* * @author gewuyou - * */ public class MenuBuilder extends AbstractMenuBuilder { + private final Menu menu; + /** * 构造菜单建造者 * @@ -37,22 +38,23 @@ public class MenuBuilder extends AbstractMenuBuilder { } /** - * 获取菜单的菜单项列表 + * 获取菜单 * - * @return 菜单项列表 + * @return 菜单 */ @Override - protected ObservableList getItems() { - return menu.getItems(); + protected Menu getMenu() { + return menu; } /** - * 构建菜单 + * 获取菜单的菜单项列表 * - * @return 构建的菜单对象 + * @return 菜单项列表 */ @Override - public Menu build() { - return menu; + protected ObservableList getItems() { + return menu.getItems(); } + } diff --git a/src/main/java/org/jcnc/jnotepad/api/core/views/sidebar/bottom/AbstractFunctionChildrenBox.java b/src/main/java/org/jcnc/jnotepad/api/core/views/sidebar/bottom/AbstractFunctionChildrenBox.java index 7e61c8a..cd2081b 100644 --- a/src/main/java/org/jcnc/jnotepad/api/core/views/sidebar/bottom/AbstractFunctionChildrenBox.java +++ b/src/main/java/org/jcnc/jnotepad/api/core/views/sidebar/bottom/AbstractFunctionChildrenBox.java @@ -13,7 +13,6 @@ import org.jcnc.jnotepad.ui.views.root.bottom.function.FunctionBox; *

* * @author gewuyou - * */ public abstract class AbstractFunctionChildrenBox { protected final FunctionBox functionBox; diff --git a/src/main/java/org/jcnc/jnotepad/app/common/constants/TextConstants.java b/src/main/java/org/jcnc/jnotepad/app/common/constants/TextConstants.java index a881d26..a389507 100644 --- a/src/main/java/org/jcnc/jnotepad/app/common/constants/TextConstants.java +++ b/src/main/java/org/jcnc/jnotepad/app/common/constants/TextConstants.java @@ -169,6 +169,81 @@ public class TextConstants { */ public static final String CHINESE = "chinese"; + /** + * 关闭 + */ + public static final String CLOSE = "CLOSE"; + + /** + * 关闭其他标签页 + */ + public static final String CLOSE_OTHER_TABS = "CLOSE_OTHER_TABS"; + + /** + * 关闭所有标签页 + */ + public static final String CLOSE_ALL_TABS = "CLOSE_ALL_TABS"; + + /** + * 关闭左侧标签 + */ + public static final String CLOSE_LEFT_TABS = "CLOSE_LEFT_TABS"; + + /** + * 关闭右侧标签 + */ + public static final String CLOSE_RIGHT_TABS = "CLOSE_RIGHT_TABS"; + + /** + * 复制 + */ + public static final String COPY = "COPY"; + + /** + * 粘贴 + */ + public static final String PASTE = "PASTE"; + + /** + * 剪切 + */ + public static final String SHEAR = "SHEAR"; + + /** + * 文件名 + */ + public static final String FILE_NAME = "FILE_NAME"; + + /** + * 文件路径 + */ + public static final String FILE_PATH = "FILE_PATH"; + + + /** + * 所在文件夹 + */ + public static final String FOLDER_PATH = "FOLDER_PATH"; + /** + * 固定标签页 + */ + public static final String FIXED_TAB = "FIXED_TAB"; + /** + * 只读 + */ + public static final String READ_ONLY = "READ_ONLY"; + + public static final String SEPARATOR = "separator"; + + /** + * 打开于 + */ + public static final String OPEN_ON = "OPEN_ON"; + /** + * 资源管理器 + */ + public static final String EXPLORER = "EXPLORER"; + private TextConstants() { } diff --git a/src/main/java/org/jcnc/jnotepad/app/common/manager/ApplicationCacheManager.java b/src/main/java/org/jcnc/jnotepad/app/common/manager/ApplicationCacheManager.java index 7a88c5a..95c76dc 100644 --- a/src/main/java/org/jcnc/jnotepad/app/common/manager/ApplicationCacheManager.java +++ b/src/main/java/org/jcnc/jnotepad/app/common/manager/ApplicationCacheManager.java @@ -7,7 +7,7 @@ import org.jcnc.jnotepad.api.core.manager.AbstractCacheManager; *

* 该类用于管理应用程序中的缓存数据。 *

- * + * * @author gewuyou */ public class ApplicationCacheManager extends AbstractCacheManager { diff --git a/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java b/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java index c12acc9..7cf97ed 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/AppConfig.java @@ -19,13 +19,8 @@ import static org.jcnc.jnotepad.app.common.constants.AppConstants.PROGRAM_FILE_D *

* * @author gewuyou - * */ public class AppConfig { - /** - * 程序根路径 - */ - private String rootPath; /** * 排除的文件夹 */ @@ -36,6 +31,10 @@ public class AppConfig { */ @JsonIgnore private final Set ignoreFile; + /** + * 程序根路径 + */ + private String rootPath; /** * 上次的程序根路径 */ 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 2b110b2..f06bf57 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/PluginConfig.java @@ -12,7 +12,6 @@ import java.util.List; *

* * @author gewuyou - * */ public class PluginConfig { private List plugins; 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 8a05648..022351d 100644 --- a/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java +++ b/src/main/java/org/jcnc/jnotepad/app/config/UserConfig.java @@ -13,7 +13,6 @@ import java.util.List; *

* * @author luke - * */ public class UserConfig { diff --git a/src/main/java/org/jcnc/jnotepad/app/utils/FileUtil.java b/src/main/java/org/jcnc/jnotepad/app/utils/FileUtil.java index b9fbc62..4b03345 100644 --- a/src/main/java/org/jcnc/jnotepad/app/utils/FileUtil.java +++ b/src/main/java/org/jcnc/jnotepad/app/utils/FileUtil.java @@ -316,5 +316,9 @@ public class FileUtil { } return orDefault; } + + public static void openTerminal(File file) { + //todo @luke 请你在此设置打开文件所在文件夹路径于终端 + } } diff --git a/src/main/java/org/jcnc/jnotepad/app/utils/TabUtil.java b/src/main/java/org/jcnc/jnotepad/app/utils/TabUtil.java index e50fe5c..01befa8 100644 --- a/src/main/java/org/jcnc/jnotepad/app/utils/TabUtil.java +++ b/src/main/java/org/jcnc/jnotepad/app/utils/TabUtil.java @@ -28,6 +28,7 @@ import java.nio.charset.Charset; import java.util.Comparator; import java.util.List; +import static org.jcnc.jnotepad.app.common.constants.TextConstants.*; import static org.jcnc.jnotepad.app.utils.FileUtil.getFileText; import static org.jcnc.jnotepad.controller.config.UserConfigController.CONFIG_NAME; @@ -51,7 +52,7 @@ public class TabUtil { return; } // 如果打开的是非关联文件,则调用另存为方法 - if (!tab.isRelevance()) { + if (!tab.getRelevanceProperty()) { logger.info("当前保存文件为非关联打开文件,调用另存为方法"); saveAsFile(tab); } else { @@ -99,7 +100,7 @@ public class TabUtil { logger.info("正在保存文件: {}", file.getName()); tab.save(file); // 将保存后的文件设置为关联文件 - tab.setRelevance(true); + tab.setRelevanceProperty(true); // 更新标签页上的文件名 tab.setText(file.getName()); } @@ -113,7 +114,7 @@ public class TabUtil { return; } // 判断当前是否为关联文件 - if (tab.isRelevance()) { + if (tab.getRelevanceProperty()) { // 重命名关联文件 handleRenameRelevanceFile(tab); } @@ -273,8 +274,6 @@ public class TabUtil { CenterTab centerTab = new CenterTab( tabTitle.toString(), textArea); - // 设置当前标签页与本地文件无关联 - centerTab.setRelevance(false); // 将Tab页添加到TabPane中 CenterTabPaneManager.getInstance().addNewTab(centerTab); // 更新编码信息 @@ -317,11 +316,8 @@ public class TabUtil { String fileText = getFileText(file, encoding); LogUtil.getLogger(OpenFile.class).info("已调用读取文件功能"); textCodeArea.appendText(fileText); - CenterTab tab = new CenterTab(file.getName(), textCodeArea, encoding); - // 设置当前标签页关联本地文件 - tab.setRelevance(true); - // 设置标签页关联文件 - tab.setUserData(file); + // 设置当前标签页关联本地文件 设置标签页关联文件 + CenterTab tab = new CenterTab(file.getName(), textCodeArea, encoding, file, true); // 设置关联文件最后的修改时间 tab.setLastModifiedTimeOfAssociatedFile(file.lastModified()); CenterTabPaneManager.getInstance().addNewTab(tab); @@ -332,76 +328,69 @@ public class TabUtil { * * @param tab The tab for which the context menu is being updated. */ - public static void updateTabContextMenu(CenterTab tab) { + public static void initTabContextMenu(CenterTab tab) { ContextMenuBuilder builder = new ContextMenuBuilder(); CenterTabPaneManager centerTabPaneManager = CenterTabPaneManager.getInstance(); File file = (File) tab.getUserData(); - //todo 设置上下文菜单 + // 设置上下文菜单 tab.setContextMenu( builder .addMenuItem( - "关闭", + CLOSE, e -> centerTabPaneManager.removeTab(tab)) .addMenuItem( - "关闭其它标签页", + CLOSE_OTHER_TABS, e -> centerTabPaneManager.removeOtherTabs(tab), - centerTabPaneManager.hasOtherTabs() + tab.hasOtherTabsPropertyProperty() ) .addMenuItem( - "关闭所有标签页", + CLOSE_ALL_TABS, e -> centerTabPaneManager.removeAllTabs()) .addMenuItem( - "关闭左侧标签页", + CLOSE_LEFT_TABS, e -> centerTabPaneManager.removeLeftTabs(tab), - centerTabPaneManager.hasLeftTabs(tab) + tab.hasLeftTabsPropertyProperty() ) .addMenuItem( - "关闭右侧标签页", + CLOSE_RIGHT_TABS, e -> centerTabPaneManager.removeRightTabs(tab), - centerTabPaneManager.hasRightTabs(tab) + tab.hasRightTabsPropertyProperty() ) - .addSeparatorMenuItem() + .addSeparatorMenuItem(tab.relevancePropertyProperty()) .addMenu( - new MenuBuilder("复制") - .addMenuItem("文件名", e -> { + new MenuBuilder(COPY) + .addMenuItem(FILE_NAME, e -> { ClipboardUtil.writeTextToClipboard(file.getName()); NotificationUtil.infoNotification("已复制文件名!"); - }, tab.isRelevance()) - .addMenuItem("文件路径", e -> { + }) + .addMenuItem(FILE_PATH, e -> { ClipboardUtil.writeTextToClipboard(file.getAbsolutePath()); NotificationUtil.infoNotification("已复制文件路径!"); - }, tab.isRelevance()) - .addMenuItem("所在文件夹", e -> { + }) + .addMenuItem(FOLDER_PATH, e -> { ClipboardUtil.writeTextToClipboard(file.getParent()); NotificationUtil.infoNotification("已复制所在文件夹!"); - }, tab.isRelevance()) + }) .build() + , tab.relevancePropertyProperty() ) .addSeparatorMenuItem() - .addMenuItem("保存", e -> saveFile(tab)) - .addMenuItem("另存为", e -> saveAsFile(tab), tab.isRelevance()) - .addMenuItem("重命名", e -> rename(tab)) - .addSeparatorMenuItem() - .addMenu(new MenuBuilder("打开于") - .addMenuItem("资源管理器", e -> FileUtil.openExplorer(file)) - .addMenuItem("终端", e -> { + .addMenuItem(SAVE, e -> saveFile(tab)) + .addMenuItem(SAVE_AS, e -> saveAsFile(tab), tab.relevancePropertyProperty()) + .addMenuItem(RENAME, e -> rename(tab)) + .addSeparatorMenuItem(tab.relevancePropertyProperty()) + .addMenu(new MenuBuilder(OPEN_ON) + .addMenuItem(EXPLORER, e -> FileUtil.openExplorer(file)) + .addMenuItem(TERMINAL, e -> { //todo @luke 请你在此设置打开文件所在文件夹路径于终端 }) - .build(), tab.isRelevance()) + .build(), tab.relevancePropertyProperty()) .addSeparatorMenuItem() - .addMenuItem("固定标签页", - e -> centerTabPaneManager.updateTabPinnedState(tab), - !tab.isFixed()) - .addMenuItem("取消固定", - e -> centerTabPaneManager.updateTabPinnedState(tab), - tab.isFixed()) + .addCheckMenuItem(FIXED_TAB, + e -> centerTabPaneManager.updateTabPinnedState(tab)) .addSeparatorMenuItem() - .addMenuItem("只读", - e -> centerTabPaneManager.updateReadOnlyProperty(tab), - tab.getTextCodeArea().isEditable()) - .addMenuItem("取消只读", - e -> centerTabPaneManager.updateReadOnlyProperty(tab), - !tab.getTextCodeArea().isEditable()) + .addCheckMenuItem(tab.getReadOnly(), + e -> centerTabPaneManager.updateReadOnlyProperty(tab)) .build()); } } 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 830356b..66934cb 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/cache/CacheController.java @@ -27,10 +27,8 @@ import java.util.Set; public class CacheController { private static final ApplicationCacheManager APPLICATION_CACHE_MANAGER = ApplicationCacheManager.getInstance(); - Logger logger = LogUtil.getLogger(this.getClass()); - private static final CacheController INSTANCE = new CacheController(); - + Logger logger = LogUtil.getLogger(this.getClass()); private String cacheDir; private CacheController() { diff --git a/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java index fb40bcb..3186a41 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/config/AppConfigController.java @@ -15,17 +15,11 @@ import static org.jcnc.jnotepad.app.common.constants.AppConstants.PROGRAM_FILE_D */ public class AppConfigController extends BaseConfigController { - private static final AppConfigController INSTANCE = new AppConfigController(); - - public static AppConfigController getInstance() { - return INSTANCE; - } - /** * 配置文件名 */ public static final String CONFIG_NAME = "JNotepadConfig.json"; - + private static final AppConfigController INSTANCE = new AppConfigController(); private final String configDir; public AppConfigController() { @@ -33,6 +27,10 @@ public class AppConfigController extends BaseConfigController { loadConfig(); } + public static AppConfigController getInstance() { + return INSTANCE; + } + /** * 获取配置文件Class类 * diff --git a/src/main/java/org/jcnc/jnotepad/controller/config/PluginConfigController.java b/src/main/java/org/jcnc/jnotepad/controller/config/PluginConfigController.java index bce610f..c81d06e 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/config/PluginConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/config/PluginConfigController.java @@ -66,6 +66,10 @@ public class PluginConfigController extends BaseConfigController { return configDir; } + public void setConfigDir(String configDir) { + this.configDir = configDir; + } + /** * 创建配置文件实体 * @@ -79,11 +83,6 @@ public class PluginConfigController extends BaseConfigController { return pluginConfig; } - - public void setConfigDir(String configDir) { - this.configDir = configDir; - } - /** * 获取插件路径 * 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 3ae5725..dada7ba 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java +++ b/src/main/java/org/jcnc/jnotepad/controller/config/UserConfigController.java @@ -34,11 +34,9 @@ public class UserConfigController extends BaseConfigController { private static final String CTRL_ALT_S = "ctrl+alt+s"; private static final String ALT_S = "alt+s"; private static final UserConfigController INSTANCE = new UserConfigController(); - private String configDir; - private final List> menuItems = new ArrayList<>(); - Logger logger = LogUtil.getLogger(this.getClass()); + private String configDir; private UserConfigController() { configDir = Paths.get(AppConfigController.getInstance().getConfig().getRootPath(), PROGRAM_FILE_DIRECTORY, ROOT_CONFIG_DIR).toString(); diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/OpenDirectory.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/OpenDirectory.java index 05be499..60dcce0 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/OpenDirectory.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/OpenDirectory.java @@ -25,10 +25,10 @@ import java.io.File; */ public class OpenDirectory implements EventHandler { + public static final String GROUP = "directory"; private static final ApplicationCacheManager CACHE_MANAGER = ApplicationCacheManager.getInstance(); private static final DirectorySidebarManager DIRECTORY_SIDEBAR_MANAGER = DirectorySidebarManager.getInstance(); - public static final String GROUP = "directory"; @Override public void handle(ActionEvent actionEvent) { // 获取缓存 diff --git a/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/RunBtn.java b/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/RunBtn.java index 0150bc3..3ab1927 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/RunBtn.java +++ b/src/main/java/org/jcnc/jnotepad/controller/event/handler/toolbar/RunBtn.java @@ -8,7 +8,6 @@ import org.jcnc.jnotepad.ui.views.manager.BuildPanelManager; /** * 终端处理器 * - * * @author cccqyu */ public class RunBtn implements EventHandler { diff --git a/src/main/java/org/jcnc/jnotepad/controller/plugin/manager/PluginManager.java b/src/main/java/org/jcnc/jnotepad/controller/plugin/manager/PluginManager.java index 9714f36..b6312f5 100644 --- a/src/main/java/org/jcnc/jnotepad/controller/plugin/manager/PluginManager.java +++ b/src/main/java/org/jcnc/jnotepad/controller/plugin/manager/PluginManager.java @@ -34,16 +34,15 @@ public class PluginManager { * 插件类别 */ private final Map> categories = new HashMap<>(); + Logger logger = LogUtil.getLogger(this.getClass()); /** * 插件信息 */ private List pluginDescriptors = new ArrayList<>(); - /** * 插件信息临时集合 */ private List temporaryPluginDescriptors; - Logger logger = LogUtil.getLogger(this.getClass()); private PluginManager() { @@ -134,6 +133,7 @@ public class PluginManager { /** * 执行加载的插件 + * * @deprecated 待删除 */ public void executePlugins() { diff --git a/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java index 49a6084..3ae2f8a 100644 --- a/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java +++ b/src/main/java/org/jcnc/jnotepad/model/entity/DirFileModel.java @@ -48,6 +48,10 @@ public class DirFileModel { return childFile; } + public void setChildFile(List childFile) { + this.childFile = childFile; + } + public String getPath() { return path; } @@ -77,16 +81,11 @@ public class DirFileModel { this.iconIsNotSelected = iconIsNotSelected; } - public void setIconIsSelected(Node iconIsSelected) { - this.iconIsSelected = iconIsSelected; - } - public Node getIconIsSelected() { return iconIsSelected; } - - public void setChildFile(List childFile) { - this.childFile = childFile; + public void setIconIsSelected(Node iconIsSelected) { + this.iconIsSelected = iconIsSelected; } } \ No newline at end of file diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/module/TextCodeArea.java b/src/main/java/org/jcnc/jnotepad/ui/component/module/TextCodeArea.java index c5ac2f4..4760349 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/module/TextCodeArea.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/module/TextCodeArea.java @@ -52,8 +52,6 @@ public class TextCodeArea extends CodeArea { "//[^\n]*" + "|" + "/\\*(.|\\R)*?\\*/" // 用于可见段落处理(逐行) + "|" + "/\\*\\V*" + "|" + "^\\h*\\*(\\V*|/)"; - - /** * 使用正则表达式将关键字、括号、分号、字符串和注释的模式组合成一个复合模式 */ @@ -110,22 +108,6 @@ public class TextCodeArea extends CodeArea { this.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/jcnc/app/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")); @@ -143,4 +125,19 @@ public class TextCodeArea extends CodeArea { // 永不发生 return null; } + + 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(); + } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/BuildPanel.java b/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/BuildPanel.java index 19eb2ae..a15c3de 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/BuildPanel.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/BuildPanel.java @@ -13,33 +13,18 @@ import org.jcnc.jnotepad.ui.component.module.vbox.components.RunBox; * *

可以通过调用getInstance方法获取单例实例。

* + * @author cccqyu * @see CmdTerminalBox * @see RunBox * @see DebugBox * @see TabPane - * @author cccqyu */ public class BuildPanel extends TabPane { private static BuildPanel instance = null; - - /** - * 获取BuildPanel的单例实例。 - * - * @return BuildPanel的单例实例 - */ - public static BuildPanel getInstance() { - - if (instance == null) { - instance = new BuildPanel(); - } - return instance; - } - private final CmdTerminalBox cmdTerminalBox; private final RunBox runBox; private final DebugBox debugBox; - private BuildPanel() { cmdTerminalBox = new CmdTerminalBox(); runBox = new RunBox(); @@ -56,6 +41,19 @@ public class BuildPanel extends TabPane { this.getTabs().addAll(runTab, buildTab, cmdTab); } + /** + * 获取BuildPanel的单例实例。 + * + * @return BuildPanel的单例实例 + */ + public static BuildPanel getInstance() { + + if (instance == null) { + instance = new BuildPanel(); + } + return instance; + } + /** * 获取命令终端组件。 * diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/components/CmdTerminalBox.java b/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/components/CmdTerminalBox.java index 97ed871..18534fe 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/components/CmdTerminalBox.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/module/vbox/components/CmdTerminalBox.java @@ -36,6 +36,7 @@ public class CmdTerminalBox extends VBox { * 用户输入命令的文本框 */ private final TextField cmdInput; + String currentDirectory; /** * 用于运行命令的进程 */ @@ -45,8 +46,6 @@ public class CmdTerminalBox extends VBox { */ private PrintWriter cmdInputWriter; - String currentDirectory; - /** * 创建CmdTerminal对象的构造函数。 */ diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/DirectoryChooserFactory.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/DirectoryChooserFactory.java index 0958a10..5c68426 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/DirectoryChooserFactory.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/DirectoryChooserFactory.java @@ -23,8 +23,8 @@ public interface DirectoryChooserFactory { /** * 创建详细的文件选择对话框。 * - * @param title 对话框标题 - * @param directory 初始目录 + * @param title 对话框标题 + * @param directory 初始目录 * @return javafx.stage.FileChooser 详细文件选择对话框对象 */ DirectoryChooser createDirectoryChooser(String title, File directory); diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/impl/BasicDirectoryChooserFactory.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/impl/BasicDirectoryChooserFactory.java index 7870fcf..ca90ce5 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/impl/BasicDirectoryChooserFactory.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/factory/impl/BasicDirectoryChooserFactory.java @@ -37,14 +37,14 @@ public class BasicDirectoryChooserFactory implements DirectoryChooserFactory { /** * 创建详细的文件选择对话框。 * - * @param title 对话框标题 - * @param directory 初始目录 + * @param title 对话框标题 + * @param directory 初始目录 * @return javafx.stage.FileChooser 详细文件选择对话框对象 */ @Override public DirectoryChooser createDirectoryChooser(String title, File directory) { - DirectoryChooser directoryChooser= createDirectoryChooser(); + DirectoryChooser directoryChooser = createDirectoryChooser(); // 设置窗口名称 directoryChooser.setTitle(title); diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/interfaces/DialogButtonAction.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/interfaces/DialogButtonAction.java index 8a27e43..f688c31 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/interfaces/DialogButtonAction.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/dialog/interfaces/DialogButtonAction.java @@ -10,6 +10,7 @@ import org.jcnc.jnotepad.ui.component.stage.dialog.AppDialogStage; public interface DialogButtonAction { /** * 处理按钮的操作。子类必须实现此方法以定义按钮的行为 + * * @param appDialogStage 对话框 * @apiNote * @since 2023/9/3 22:53 diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/setting/SetStage.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/setting/SetStage.java index 6be26fc..04181ab 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/setting/SetStage.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/setting/SetStage.java @@ -52,9 +52,8 @@ public class SetStage { public static final String SECURITY_SETTING_2 = "安全设置项2"; private static SetStage instance; - private StackPane contentDisplay; - private final ApplicationCacheManager cacheManager = ApplicationCacheManager.getInstance(); + private StackPane contentDisplay; /** * 私有构造方法以实现单例模式。 diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/CustomSplitPane.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/CustomSplitPane.java index 4018f0a..54eab51 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/CustomSplitPane.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/CustomSplitPane.java @@ -6,9 +6,9 @@ import javafx.scene.layout.HBox; /** * 自定义分割面板,用于将两个组件以水平方向分割显示。 - * + * *

该分割面板包含左侧和右侧两个区域,可分别设置内容。

- * + * * @author luke */ public class CustomSplitPane extends SplitPane { @@ -18,7 +18,7 @@ public class CustomSplitPane extends SplitPane { /** * 创建一个自定义分割面板,指定左侧和右侧的文本标签。 - * + * * @param leftText 左侧区域的文本标签 * @param rightText 右侧区域的文本标签 */ @@ -43,7 +43,7 @@ public class CustomSplitPane extends SplitPane { /** * 设置左侧区域的内容。 - * + * * @param content 左侧区域的内容节点 */ public void setLeftContent(javafx.scene.Node content) { @@ -53,7 +53,7 @@ public class CustomSplitPane extends SplitPane { /** * 设置右侧区域的内容。 - * + * * @param content 右侧区域的内容节点 */ public void setRightContent(javafx.scene.Node content) { diff --git a/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/PluginManagementPane.java b/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/PluginManagementPane.java index 7717116..87b0c0c 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/PluginManagementPane.java +++ b/src/main/java/org/jcnc/jnotepad/ui/component/stage/topmenu/plugin/PluginManagementPane.java @@ -53,34 +53,31 @@ import java.util.Map; * @author luke */ public class PluginManagementPane extends AbstractPaneStage { - PluginManager pluginManager = PluginManager.getInstance(); - /** * 图标大小常量 */ public static int ICON_SIZE = 40; - + /** + * 用于存储Tile与其内容节点的映射关系 + */ + private final Map tileContentMap = new HashMap<>(); + PluginManager pluginManager = PluginManager.getInstance(); /** * 日志记录器 */ Logger logger = LogUtil.getLogger(this.getClass()); - /** * 自定义分割面板 */ private CustomSplitPane customSplitPane; - /** - * 用于存储Tile与其内容节点的映射关系 - */ - private final Map tileContentMap = new HashMap<>(); - /** * 创建一个插件管理面板的实例。 */ public PluginManagementPane() { initialize(); } + /** * 初始化插件管理面板。 */ diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/BottomStatusBoxManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/BottomStatusBoxManager.java index afb5bed..3c356e3 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/BottomStatusBoxManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/BottomStatusBoxManager.java @@ -71,6 +71,14 @@ public class BottomStatusBoxManager { registerChildren(statusLabel); statusLabel.setText(getStatusBarFormattedText(0, 0, 1)); registerChildren(BOTTOM_STATUS_BOX.getEncodingLabel()); + + Button readOnlyButton = BOTTOM_STATUS_BOX.getReadOnlyButton(); + BottomStatusBoxButtonBuilder builder = new BottomStatusBoxButtonBuilder(readOnlyButton); + FontIcon icon = FontIcon.of(UNLOCK); + registerChildren(builder + .setFontIcon(icon) + .setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(CenterTabPaneManager.getInstance().getSelected())) + .build()); } /** @@ -213,33 +221,16 @@ public class BottomStatusBoxManager { * @param tabs the list of tabs in the center tab pane */ public void updateReadOnlyProperty(CenterTab tab, ObservableList tabs) { - ObservableList children = BOTTOM_STATUS_BOX.getChildren(); Button readOnlyButton = BOTTOM_STATUS_BOX.getReadOnlyButton(); - BottomStatusBoxButtonBuilder builder = new BottomStatusBoxButtonBuilder(readOnlyButton); + readOnlyButton.setVisible(!tabs.isEmpty()); + FontIcon icon; if (tab.getTextCodeArea().isEditable()) { - FontIcon icon = FontIcon.of(UNLOCK); - if (children.contains(readOnlyButton)) { - readOnlyButton.setGraphic(icon); - } else { - registerChildren(builder - .setFontIcon(icon) - .setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(tab)) - .build()); - } - + icon = FontIcon.of(UNLOCK); + readOnlyButton.setGraphic(icon); } else { - FontIcon icon = FontIcon.of(LOCK); - if (children.contains(readOnlyButton)) { - readOnlyButton.setGraphic(icon); - } else { - registerChildren(builder - .setFontIcon(icon) - .setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(tab)) - .build()); - } - } - if (tabs.isEmpty()) { - children.remove(readOnlyButton); + icon = FontIcon.of(LOCK); + readOnlyButton.setGraphic(icon); } + tab.getReadOnly().setSelected(!tab.getTextCodeArea().isEditable()); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/BuildPanelManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/BuildPanelManager.java index 4ba4cb2..76ea5a9 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/BuildPanelManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/BuildPanelManager.java @@ -13,23 +13,21 @@ import org.jcnc.jnotepad.ui.views.root.center.main.MainBorderPane; */ public class BuildPanelManager { - private BuildPanelManager() { - } - /** * 单例模式,保证只有一个 BuildPanelManager 实例 */ private static final BuildPanelManager INSTANCE = new BuildPanelManager(); + private static final MainBorderPane MAIN_BORDER_PANE = MainBorderPane.getInstance(); + private boolean isShow = false; + + private BuildPanelManager() { + } public static BuildPanelManager getInstance() { return INSTANCE; } - - private static final MainBorderPane MAIN_BORDER_PANE = MainBorderPane.getInstance(); - private boolean isShow = false; - /** * 控制终端显示 */ diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/CenterTabPaneManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/CenterTabPaneManager.java index 4d3cbc9..c673ff4 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/CenterTabPaneManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/CenterTabPaneManager.java @@ -1,5 +1,6 @@ package org.jcnc.jnotepad.ui.views.manager; +import javafx.application.Platform; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.scene.control.Tab; @@ -44,7 +45,10 @@ public class CenterTabPaneManager { * 初始化标签页布局组件 */ public void initCenterTabPane() { - initListeners(); + Platform.runLater(() -> { + initListeners(); + addTabsListener(); + }); } @@ -79,7 +83,7 @@ public class CenterTabPaneManager { if (tab == null) { return; } - if (tab.isRelevance()) { + if (tab.getRelevanceProperty()) { // 获取当前文本域对象 TextCodeArea textCodeArea = tab.getTextCodeArea(); // 获取当前标签页对应文件上次修改时间 @@ -115,9 +119,8 @@ public class CenterTabPaneManager { } // 将标签页加入标签页列表 centerTabPane.getTabs().add(tab); - // 设置索引 - centerTabPane.getSelectionModel().select(tab); - // 将标签页设置为选中状态 + // 异步刷新界面 将标签页设置为选中状态 + Platform.runLater(() -> centerTabPane.getSelectionModel().select(tab)); fireTabSelected(); } @@ -187,7 +190,7 @@ public class CenterTabPaneManager { if (centerTab.equals(currTab)) { return false; } - return !centerTab.isFixed() && !centerTab.equals(currTab); + return centerTab.getNotFixedProperty() && !centerTab.equals(currTab); }); } @@ -204,7 +207,7 @@ public class CenterTabPaneManager { if (tab.equals(centerTab)) { return; } - if (!tab.isFixed()) { + if (tab.getNotFixedProperty()) { iterator.remove(); } } @@ -225,107 +228,81 @@ public class CenterTabPaneManager { flag = true; continue; } - if (flag && !tab.isFixed()) { + if (flag && tab.getNotFixedProperty()) { iterator.remove(); } } } /** - * 判断是否有其它标签页 - * - * @return 是否有其它标签页 - */ - public boolean hasOtherTabs() { - return centerTabPane.getTabs().size() > 1; - } - - - /** - * 判断是否有左侧标签页 + * Updates the pinned state of the given center tab. * - * @param centerTab 标签页 - * @apiNote 由于不知道怎么监听固定状态,因此,还是使用简单的判断,如果能够监听固定状态时可以把代码修改为 - *
-     *  public boolean hasLeftTabs(CenterTab centerTab) {
-     *     ObservableList tabs = centerTabPane.getTabs();
-     *     int edge = tabs.indexOf(centerTab);
-     *     if (edge == 0) {
-     *         return false;
-     *     }
-     *     for (int i = 0; i < edge; i++) {
-     *         CenterTab tab = (CenterTab) tabs.get(i);
-     *         if (!tab.isFixed()) {
-     *             return true;
-     *         }
-     *     }
-     *     return false;
-     * }
-     * 
-     * @return 是否有左侧标签页
+     * @param tab the center tab to update
      */
-    public boolean hasLeftTabs(CenterTab centerTab) {
-        int index = centerTabPane.getTabs().indexOf(centerTab);
-        return index > 0;
+    public void updateTabPinnedState(CenterTab tab) {
+        tab.setFixedProperty(tab.getNotFixedProperty());
+        tab.setClosable(tab.getNotFixedProperty());
     }
 
     /**
-     * 判断是否有右侧标签页
+     * Updates the read-only property of a given tab and its associated check menu item.
      *
-     * @param centerTab 标签页
-     * @return 是否有右侧标签页
-     * @apiNote 由于不知道怎么监听固定状态,因此,还是使用简单的判断,如果能够监听固定状态时可以把代码修改为
-     * 
-     *  public boolean hasRightTabs(CenterTab centerTab) {
-     *         ObservableList tabs = centerTabPane.getTabs();
-     *         for (int i = tabs.indexOf(centerTab)+1; i < tabs.size(); i++) {
-     *             CenterTab tab = (CenterTab) tabs.get(i);
-     *             if (!tab.isFixed()) {
-     *                 return true;
-     *             }
-     *         }
-     *         return false;
-     *     }
-     * 
+ * @param tab the center tab to update */ - public boolean hasRightTabs(CenterTab centerTab) { - ObservableList tabs = centerTabPane.getTabs(); - int index = tabs.indexOf(centerTab); - return index != tabs.size() - 1; + public void updateReadOnlyProperty(CenterTab tab) { + TextCodeArea textCodeArea = tab.getTextCodeArea(); + textCodeArea.setEditable(!textCodeArea.isEditable()); + BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, centerTabPane.getTabs()); } /** - * Sets a listener for the tabs in the center tab pane. - * - * @param tab the tab to set the listener for + * Adds a listener to the tabs in the center tab pane. */ - public void setTabsListener(CenterTab tab) { - ObservableList tabs = centerTabPane.getTabs(); - tabs.addListener((ListChangeListener) c -> { - tab.contextMenuMonitor(); - BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, tabs); + private void addTabsListener() { + centerTabPane.getTabs().addListener((ListChangeListener) change -> { + ObservableList list = change.getList(); + list.forEach(tab -> { + CenterTab centerTab = (CenterTab) tab; + // 判断标签页 + checkTabs(list, centerTab); + }); }); } /** - * Updates the pinned state of the given center tab. + * Checks the tabs in the given list and updates the properties of the centerTab accordingly. * - * @param tab the center tab to update + * @param list the list of tabs to check + * @param centerTab the centerTab to update */ - public void updateTabPinnedState(CenterTab tab) { - tab.setFixed(!tab.isFixed()); - tab.setClosable(!tab.isFixed()); - } + public void checkTabs(ObservableList list, CenterTab centerTab) { + int index = list.indexOf(centerTab); + boolean hasOther = false; + boolean hasLeft = false; + boolean hasRight = false; + int tabCount = list.size(); - /** - * Updates the read-only property of a given tab and its associated check menu item. - * - * @param tab the center tab to update - */ - public void updateReadOnlyProperty(CenterTab tab) { - TextCodeArea textCodeArea = tab.getTextCodeArea(); - textCodeArea.setEditable(!textCodeArea.isEditable()); - tab.contextMenuMonitor(); - BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, centerTabPane.getTabs()); + for (int i = 0; i < tabCount; i++) { + CenterTab temp = (CenterTab) list.get(i); + + // 判断是否有其他标签页 + if (!centerTab.equals(temp) && temp.getNotFixedProperty()) { + hasOther = true; + } + + // 判断是否有左侧标签页 + if (!centerTab.equals(temp) && i < index && temp.getNotFixedProperty()) { + hasLeft = true; + } + + // 判断是否有右侧标签页 + if (!centerTab.equals(temp) && i > index && temp.getNotFixedProperty()) { + hasRight = true; + } + } + + centerTab.setHasOtherTabsProperty(hasOther); + centerTab.setHasLeftTabsProperty(hasLeft); + centerTab.setHasRightTabsProperty(hasRight); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/DirectorySidebarManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/DirectorySidebarManager.java index f774190..4e0f941 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/DirectorySidebarManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/DirectorySidebarManager.java @@ -23,29 +23,49 @@ import java.util.List; */ public class DirectorySidebarManager { - private DirectorySidebarManager() { - } - private static final ApplicationCacheManager CACHE_MANAGER = ApplicationCacheManager.getInstance(); - /** * 单例模式,保证只有一个 DirectorySidebar 实例 */ private static final DirectorySidebarManager INSTANCE = new DirectorySidebarManager(); + private static final MainBorderPane MAIN_BORDER_PANE = MainBorderPane.getInstance(); + private static final DirectorySidebarPane DIRECTORY_SIDEBAR_PANE = DirectorySidebarPane.getInstance(); + private static final double LAST_DIVIDER_POSITION = 0.3; + private static boolean isShow = false; + private DirectorySidebarManager() { + } + public static DirectorySidebarManager getInstance() { return INSTANCE; } - private static final MainBorderPane MAIN_BORDER_PANE = MainBorderPane.getInstance(); - - private static final DirectorySidebarPane DIRECTORY_SIDEBAR_PANE = DirectorySidebarPane.getInstance(); - - - private static final double LAST_DIVIDER_POSITION = 0.3; + /** + * 设置文件树项监听事件 + * + * @param item 文件树项 + * @return 监听事件 + */ + private static ChangeListener getTreeItemListener(TreeItem item) { + return (observable, oldValue, newValue) -> { + if (Boolean.TRUE.equals(newValue)) { + item.setGraphic(item.getValue().getIconIsSelected()); + } else { + item.setGraphic(item.getValue().getIconIsNotSelected()); + } + }; + } - private static boolean isShow = false; + /** + * Check if the given `DirFileModel` represents a directory. + * + * @param childFile the `DirFileModel` to check + * @return `true` if the `childFile` represents a directory, `false` otherwise + */ + private static boolean isDirectoryByDirFileModel(DirFileModel childFile) { + return new File(childFile.getPath()).isDirectory(); + } /** * 控制文件树显示 @@ -83,22 +103,6 @@ public class DirectorySidebarManager { } } - /** - * 设置文件树项监听事件 - * - * @param item 文件树项 - * @return 监听事件 - */ - private static ChangeListener getTreeItemListener(TreeItem item) { - return (observable, oldValue, newValue) -> { - if (Boolean.TRUE.equals(newValue)) { - item.setGraphic(item.getValue().getIconIsSelected()); - } else { - item.setGraphic(item.getValue().getIconIsNotSelected()); - } - }; - } - /** * 设置文件树内容 * @@ -112,16 +116,6 @@ public class DirectorySidebarManager { expandFolder(dirFileModel, rootItem); } - /** - * Check if the given `DirFileModel` represents a directory. - * - * @param childFile the `DirFileModel` to check - * @return `true` if the `childFile` represents a directory, `false` otherwise - */ - private static boolean isDirectoryByDirFileModel(DirFileModel childFile) { - return new File(childFile.getPath()).isDirectory(); - } - /** * 递归展开 dirFileModel * diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/RootManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/RootManager.java index 5e0fb37..99e00ed 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/RootManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/RootManager.java @@ -24,11 +24,11 @@ import org.jcnc.jnotepad.ui.views.root.RootBorderPane; public class RootManager { private static RootManager instance = null; - StackPane rootStackPane; /** * 主布局 */ private final BorderPane root; + StackPane rootStackPane; /** * 私有构造函数。设置场景和根布局。 @@ -67,23 +67,6 @@ public class RootManager { } } - - /** - * 初始化屏幕组件。 - * - * @param scene 与视图相关联的 JavaFX 场景。 - */ - public void initScreen(Scene scene) { - rootStackPane = new StackPane(); - - // 创建主界面布局 - root.setCenter(RootBorderPane.getInstance()); - - rootStackPane.getChildren().addAll(root); - scene.setRoot(rootStackPane); - - } - /** * 将提示框添加到 StackPane 中。 * @@ -155,6 +138,22 @@ public class RootManager { timeline.play(); } + /** + * 初始化屏幕组件。 + * + * @param scene 与视图相关联的 JavaFX 场景。 + */ + public void initScreen(Scene scene) { + rootStackPane = new StackPane(); + + // 创建主界面布局 + root.setCenter(RootBorderPane.getInstance()); + + rootStackPane.getChildren().addAll(root); + scene.setRoot(rootStackPane); + + } + public StackPane getRootStackPane() { return rootStackPane; } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/SidebarToolBarManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/SidebarToolBarManager.java index ba25342..b8f57bd 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/SidebarToolBarManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/SidebarToolBarManager.java @@ -19,11 +19,11 @@ import java.util.List; */ public class SidebarToolBarManager extends AbstractManager { private static final SidebarToolBarManager INSTANCE = new SidebarToolBarManager(); + private final List nodeList = new ArrayList<>(); /** * 工具栏 */ SidebarToolBar sidebarToolBar = SidebarToolBar.getInstance(); - private final List nodeList = new ArrayList<>(); public static SidebarToolBarManager getInstance() { return INSTANCE; diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/manager/TopMenuBarManager.java b/src/main/java/org/jcnc/jnotepad/ui/views/manager/TopMenuBarManager.java index 707924c..c2db679 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/manager/TopMenuBarManager.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/manager/TopMenuBarManager.java @@ -31,7 +31,7 @@ public class TopMenuBarManager extends AbstractManager { SettingTopMenu settingTopMenu = SettingTopMenu.getInstance(); - RunTopMenu runTopMenu=RunTopMenu.getInstance(); + RunTopMenu runTopMenu = RunTopMenu.getInstance(); PluginTopMenu pluginTopMenu = PluginTopMenu.getInstance(); HelpTopMenu helpTopMenu = HelpTopMenu.getInstance(); diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/bottom/RootBottomSideBarVerticalBox.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/bottom/RootBottomSideBarVerticalBox.java index 1b785bb..cf1a1b9 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/bottom/RootBottomSideBarVerticalBox.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/bottom/RootBottomSideBarVerticalBox.java @@ -12,11 +12,16 @@ import org.jcnc.jnotepad.ui.component.module.base.AbstractVerticalBox; */ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { + private static final RootBottomSideBarVerticalBox INSTANCE = new RootBottomSideBarVerticalBox(); /** * VBox实例 */ private final VBox vBox = new VBox(); + private RootBottomSideBarVerticalBox() { + + } + /** * 获取 RootBottomSideBarVerticalBox 的唯一实例。 * @@ -26,10 +31,6 @@ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { return INSTANCE; } - private RootBottomSideBarVerticalBox() { - - } - /** * 获取vbox实例 * @@ -39,6 +40,4 @@ public class RootBottomSideBarVerticalBox extends AbstractVerticalBox { return vBox; } - private static final RootBottomSideBarVerticalBox INSTANCE = new RootBottomSideBarVerticalBox(); - } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/center/main/center/tab/CenterTab.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/center/main/center/tab/CenterTab.java index 6d1001f..64b47e6 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/center/main/center/tab/CenterTab.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/center/main/center/tab/CenterTab.java @@ -1,7 +1,10 @@ package org.jcnc.jnotepad.ui.views.root.center.main.center.tab; +import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.collections.ObservableList; +import javafx.scene.control.CheckMenuItem; import javafx.scene.control.Tab; import org.fxmisc.flowless.VirtualizedScrollPane; import org.jcnc.jnotepad.app.utils.FileUtil; @@ -19,6 +22,8 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.charset.Charset; +import static org.jcnc.jnotepad.app.common.constants.TextConstants.READ_ONLY; + /** * 封装标签页组件,增加属于标签页的属性,例如:自动换行开关。 * 每个Tab关联一个TextCodeArea。 @@ -26,55 +31,81 @@ import java.nio.charset.Charset; * @author songdragon */ public class CenterTab extends Tab { - Logger logger = LogUtil.getLogger(this.getClass()); private final TextCodeArea textCodeArea; - /** - * 默认关闭自动换行 - */ - private boolean autoLine = false; /** * 是否与本地文件关联 */ - private boolean isRelevance = false; - + private final BooleanProperty relevanceProperty = new SimpleBooleanProperty(false); /** * 是否固定 */ - private final BooleanProperty isFixed = new SimpleBooleanProperty(false); + private final BooleanProperty fixedProperty = new SimpleBooleanProperty(false); + /** + * 只读菜单项 + */ + private final CheckMenuItem readOnly = new CheckMenuItem(READ_ONLY); + private final BooleanProperty hasLeftTabsProperty = new SimpleBooleanProperty(false); + private final BooleanProperty hasRightTabsProperty = new SimpleBooleanProperty(false); + private final BooleanProperty hasOtherTabsProperty = new SimpleBooleanProperty(false); + Logger logger = LogUtil.getLogger(this.getClass()); + /** + * 默认关闭自动换行 + */ + private boolean autoLine; /** * 关联文件上次修改时间 */ private Long lastModifiedTimeOfAssociatedFile; - private Charset charset = Charset.defaultCharset(); + /** + * 编码 + */ + private Charset charset; public CenterTab(String tabTitle) { this(tabTitle, new TextCodeArea()); } public CenterTab(String tabTitle, TextCodeArea textArea) { - this(tabTitle, textArea, Charset.defaultCharset()); + this(tabTitle, textArea, Charset.defaultCharset(), null, false); } - public CenterTab(String tabTitle, TextCodeArea textArea, Charset charset) { + public CenterTab(String tabTitle, TextCodeArea textCodeArea, Charset charset, File file, boolean relevanceProperty) { super(tabTitle); // 在此根据标签页名称设置文件图标 this.setGraphic(FileUtil.getIconCorrespondingToFileName(tabTitle)); - textCodeArea = textArea; - initTextAreaListeners(); - this.setContent(new VirtualizedScrollPane<>(textCodeArea)); - setAutoLine(UserConfigController.getInstance().getAutoLineConfig()); + this.textCodeArea = textCodeArea; + this.setContent(new VirtualizedScrollPane<>(this.textCodeArea)); + this.autoLine = UserConfigController.getInstance().getAutoLineConfig(); this.charset = charset; - // 绑定标签页监听 - CenterTabPaneManager.getInstance().setTabsListener(this); - isFixed.addListener((observable, oldValue, newValue) -> this.contextMenuMonitor()); + this.relevanceProperty.set(relevanceProperty); + this.setUserData(file); + // 将监听器于上下文菜单集中处理 + Platform.runLater(() -> { + initTextAreaListeners(); + this.contextMenuMonitor(); + initFixedStateListener(); + }); + } + + private void initFixedStateListener() { + fixedProperty.addListener((observable, oldValue, newValue) -> { + ObservableList tabs = CenterTabPane.getInstance().getTabs(); + tabs.forEach(tab -> CenterTabPaneManager.getInstance().checkTabs(tabs, (CenterTab) tab)); + }); + } + + + public boolean getRelevanceProperty() { + return relevanceProperty.get(); } - public boolean isRelevance() { - return isRelevance; + public void setRelevanceProperty(boolean relevanceProperty) { + this.relevanceProperty.set(relevanceProperty); } - public void setRelevance(boolean relevance) { - isRelevance = relevance; + + public BooleanProperty relevancePropertyProperty() { + return relevanceProperty; } public boolean isAutoLine() { @@ -102,7 +133,7 @@ public class CenterTab extends Tab { * Monitors the context menu. */ public void contextMenuMonitor() { - TabUtil.updateTabContextMenu(this); + TabUtil.initTabContextMenu(this); } @@ -144,7 +175,7 @@ public class CenterTab extends Tab { } /** - * 初始化监听器方法 + * 初始化文本监听器方法 */ private void initTextAreaListeners() { // 监听主要文本区域的文本变化 @@ -175,11 +206,42 @@ public class CenterTab extends Tab { this.lastModifiedTimeOfAssociatedFile = lastModifiedTimeOfAssociatedFile; } - public boolean isFixed() { - return isFixed.get(); + public boolean getNotFixedProperty() { + return !fixedProperty.get(); + } + + public void setFixedProperty(boolean fixedProperty) { + this.fixedProperty.set(fixedProperty); + } + + + public BooleanProperty hasLeftTabsPropertyProperty() { + return hasLeftTabsProperty; + } + + + public BooleanProperty hasRightTabsPropertyProperty() { + return hasRightTabsProperty; + } + + + public BooleanProperty hasOtherTabsPropertyProperty() { + return hasOtherTabsProperty; + } + + public CheckMenuItem getReadOnly() { + return readOnly; + } + + public void setHasLeftTabsProperty(boolean hasLeftTabsProperty) { + this.hasLeftTabsProperty.set(hasLeftTabsProperty); + } + + public void setHasRightTabsProperty(boolean hasRightTabsProperty) { + this.hasRightTabsProperty.set(hasRightTabsProperty); } - public void setFixed(boolean fixed) { - isFixed.set(fixed); + public void setHasOtherTabsProperty(boolean hasOtherTabsProperty) { + this.hasOtherTabsProperty.set(hasOtherTabsProperty); } } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/left/sidebar/tools/SidebarToolBar.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/left/sidebar/tools/SidebarToolBar.java index 268e441..2a0acc8 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/left/sidebar/tools/SidebarToolBar.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/left/sidebar/tools/SidebarToolBar.java @@ -38,7 +38,7 @@ public class SidebarToolBar extends javafx.scene.control.ToolBar { private SidebarToolBar() { // 垂直排列 this.setOrientation(Orientation.VERTICAL); - this.setPadding(new Insets(1,5,0,0)); + this.setPadding(new Insets(1, 5, 0, 0)); this.setOnMouseClicked(event -> { // SidebarToolBar 点击事件 }); diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/TopMenuBar.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/TopMenuBar.java index acce617..c5818e3 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/TopMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/TopMenuBar.java @@ -12,10 +12,6 @@ import org.jcnc.jnotepad.ui.views.root.center.main.center.tab.CenterTab; public class TopMenuBar extends MenuBar { private static final TopMenuBar MENU_BAR = new TopMenuBar(); - /** - * 标签页布局组件封装。 - */ - CenterTabPaneManager centerTabPane = CenterTabPaneManager.getInstance(); /** * 文件菜单 */ @@ -24,23 +20,20 @@ public class TopMenuBar extends MenuBar { * 设置菜单 */ private final Menu setMenu = new Menu(); - /** * 帮助菜单 */ private final Menu helpMenu = new Menu(); - /** * 运行菜单 */ private final Menu runMenu = new Menu(); - - /// 菜单按钮 /** * 插件菜单 */ private final Menu pluginMenu = new Menu(); + /// 菜单按钮 /** * 语言菜单 */ @@ -49,12 +42,10 @@ public class TopMenuBar extends MenuBar { * 新建 */ private final MenuItem newItem = new MenuItem(); - /** * 关于 */ private final MenuItem aboutItem = new MenuItem(); - /** * 调试 */ @@ -64,9 +55,7 @@ public class TopMenuBar extends MenuBar { */ private final MenuItem runItem = new MenuItem(); - private final MenuItem developerItem = new MenuItem(); - /** * 打开 */ @@ -87,7 +76,6 @@ public class TopMenuBar extends MenuBar { * 重命名 */ private final MenuItem renameItem = new MenuItem(); - /** * 查看 */ @@ -112,11 +100,14 @@ public class TopMenuBar extends MenuBar { * 英文选项 */ private final RadioMenuItem englishItem = new RadioMenuItem(); - /** * 插件管理菜单项 */ private final MenuItem pluginManagerItem = new MenuItem(); + /** + * 标签页布局组件封装。 + */ + CenterTabPaneManager centerTabPane = CenterTabPaneManager.getInstance(); private TopMenuBar() { } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/FileTopMenu.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/FileTopMenu.java index 3cc7d02..3696c5d 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/FileTopMenu.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/FileTopMenu.java @@ -63,9 +63,9 @@ public class FileTopMenu extends AbstractBaseMenu { // 文件菜单 registerMenuItem(topMenuBar.getNewItem(), NEW, "newItem", new NewFile()); registerMenuItem(topMenuBar.getOpenItem(), OPEN, "openItem", new OpenFile()); - registerMenuItem(topMenuBar.getSaveItem(), SAVE, "saveItem", new SaveFile()); - registerMenuItem(topMenuBar.getSaveAsItem(), SAVE_AS, "saveAsItem", new SaveAsFile()); - registerMenuItem(topMenuBar.getRenameItem(), RENAME, "renameItem", new RenameFile()); + registerMenuItem(topMenuBar.getSaveItem(), SAVE, SAVE.toLowerCase(), new SaveFile()); + registerMenuItem(topMenuBar.getSaveAsItem(), SAVE_AS, SAVE_AS.toLowerCase(), new SaveAsFile()); + registerMenuItem(topMenuBar.getRenameItem(), RENAME, RENAME.toLowerCase(), new RenameFile()); // 打开文件夹按钮 registerMenuItem(topMenuBar.getOpenDirItem(), OPEN_DIRECTORY, "openDirItem", new OpenDirectory()); } diff --git a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/RunTopMenu.java b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/RunTopMenu.java index dc72198..6aac921 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/RunTopMenu.java +++ b/src/main/java/org/jcnc/jnotepad/ui/views/root/top/menubar/menu/RunTopMenu.java @@ -28,6 +28,25 @@ public class RunTopMenu extends AbstractBaseMenu { private static final BuildPanel BUILD_PANEL = BuildPanel.getInstance(); private static final RunTopMenu INSTANCE = new RunTopMenu(); private final Map runMenuItems = new HashMap<>(); + EventHandler codeRun = event -> { + + // 获取TextCodeArea的文本内容 + CenterTab centerTab = CenterTabPaneManager.getInstance().getSelected(); + + String code = centerTab.getTextCodeArea().getText(); + + String fileName = centerTab.getText(); + + // 将C代码写入临时文件 + try (PrintWriter writer = new PrintWriter(new FileWriter(fileName))) { + writer.write(code); + } catch (IOException ex) { + LogUtil.getLogger(this.getClass()).info("正在写入:{}", code); + } + + // 编译C代码 + compileAndRunCode(fileName); + }; public static RunTopMenu getInstance() { return INSTANCE; @@ -63,26 +82,6 @@ public class RunTopMenu extends AbstractBaseMenu { return runMenuItems; } - EventHandler codeRun = event -> { - - // 获取TextCodeArea的文本内容 - CenterTab centerTab = CenterTabPaneManager.getInstance().getSelected(); - - String code = centerTab.getTextCodeArea().getText(); - - String fileName = centerTab.getText(); - - // 将C代码写入临时文件 - try (PrintWriter writer = new PrintWriter(new FileWriter(fileName))) { - writer.write(code); - } catch (IOException ex) { - LogUtil.getLogger(this.getClass()).info("正在写入:{}", code); - } - - // 编译C代码 - compileAndRunCode(fileName); - }; - /** * 编译和运行C代码的方法 */ diff --git a/src/main/resources/jcnc/app/css/styles.css b/src/main/resources/jcnc/app/css/styles.css index 73133ff..554a563 100644 --- a/src/main/resources/jcnc/app/css/styles.css +++ b/src/main/resources/jcnc/app/css/styles.css @@ -19,6 +19,7 @@ -fx-border-width: 0 1 0 0; -fx-border-color: -color-border-default; } + /*左侧边栏*/ .tool-horizontal-box { -fx-border-width: 0 1 0 0; diff --git a/src/main/resources/jcnc/app/i18n/i18n.properties b/src/main/resources/jcnc/app/i18n/i18n.properties index d73e8d2..2d0053e 100644 --- a/src/main/resources/jcnc/app/i18n/i18n.properties +++ b/src/main/resources/jcnc/app/i18n/i18n.properties @@ -39,9 +39,7 @@ CLOSE_LEFT_TABS=关闭左侧标签页 CLOSE_RIGHT_TABS=关闭右侧标签页 CLOSE_OTHER_TABS=关闭其他标签页 FIXED_TAB=固定标签页 -UNFIXED_TAB=取消固定 READ_ONLY=只读 -UNREAD_ONLY=取消只读 OPEN_ON=打开于 diff --git a/src/main/resources/jcnc/app/i18n/i18n_en.properties b/src/main/resources/jcnc/app/i18n/i18n_en.properties index 865178f..5826385 100644 --- a/src/main/resources/jcnc/app/i18n/i18n_en.properties +++ b/src/main/resources/jcnc/app/i18n/i18n_en.properties @@ -27,4 +27,17 @@ SAVE=Save ROW=Row FILE=File MANAGER_PLUGIN=Manager Plugin -ENCODE=Encoding \ No newline at end of file +ENCODE=Encoding +COPY=Copy +FILE_NAME=File Name +FILE_PATH=File Path +FOLDER_PATH=Folder Path +EXPLORER=Explorer +CLOSE=Close +CLOSE_ALL_TABS=Close All Tabs +CLOSE_LEFT_TABS=Close Left Tabs +CLOSE_RIGHT_TABS=Close Right Tabs +CLOSE_OTHER_TABS=Close Other Tabs +FIXED_TAB=Fixed Tab +READ_ONLY=Read Only +OPEN_ON=Open On diff --git a/src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties b/src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties index 4ee0f9f..cfde158 100644 --- a/src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties +++ b/src/main/resources/jcnc/app/i18n/i18n_zh_CN.properties @@ -28,3 +28,16 @@ ROW=行数 FILE=文件 MANAGER_PLUGIN=插件管理 ENCODE=编码 +COPY=复制 +FILE_NAME=文件名 +FILE_PATH=文件路径 +FOLDER_PATH=所在文件夹 +EXPLORER=资源管理器 +CLOSE=关闭 +CLOSE_ALL_TABS=关闭所有标签页 +CLOSE_LEFT_TABS=关闭左侧标签页 +CLOSE_RIGHT_TABS=关闭右侧标签页 +CLOSE_OTHER_TABS=关闭其他标签页 +FIXED_TAB=固定标签页 +READ_ONLY=只读 +OPEN_ON=打开于 -- Gitee