!166 ♻️ ⚡️ 优化性能重构并优化标签页右键菜单
Merge pull request !166 from 格物方能致知/refactor-I884CX
This commit is contained in:
commit
950b15880e
@ -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.*;
|
||||
|
||||
/**
|
||||
* 抽象菜单建造者类
|
||||
*
|
||||
* <p>
|
||||
* 该抽象类用于构建菜单,包括菜单项、单选菜单项、复选菜单项、分割线等。
|
||||
* 子类应继承此类以实现具体的菜单构建逻辑。
|
||||
* </p>
|
||||
*
|
||||
* @param <B> 建造者类型
|
||||
* @param <T> 构建结果类型
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public abstract class AbstractMenuBuilder<B, T> {
|
||||
/**
|
||||
* 获取子类的建造者实例
|
||||
*
|
||||
* @return 建造者实例
|
||||
*/
|
||||
protected abstract B getBuilder();
|
||||
|
||||
/**
|
||||
* 获取菜单的菜单项列表
|
||||
*
|
||||
* @return 菜单项列表
|
||||
*/
|
||||
protected abstract ObservableList<MenuItem> getItems();
|
||||
|
||||
/**
|
||||
* 添加菜单项
|
||||
*
|
||||
* @param label 菜单项名称
|
||||
* @param eventHandler 事件处理器
|
||||
* @return 当前建造者实例
|
||||
*/
|
||||
public B addMenuItem(String label, EventHandler<ActionEvent> 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<ActionEvent> 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<ActionEvent> 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<ActionEvent> 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();
|
||||
}
|
||||
@ -22,7 +22,6 @@ import java.nio.file.Paths;
|
||||
* </p>
|
||||
*
|
||||
* @param <T> 配置文件类型
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public abstract class BaseConfigController<T> implements ConfigController<T> {
|
||||
@ -30,9 +29,8 @@ public abstract class BaseConfigController<T> implements ConfigController<T> {
|
||||
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类。
|
||||
|
||||
@ -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<Menu> {
|
||||
protected final TopMenuBar topMenuBar = TopMenuBar.getInstance();
|
||||
protected final UserConfigController userConfigController = UserConfigController.getInstance();
|
||||
|
||||
/**
|
||||
* 获取菜单名称
|
||||
@ -30,23 +26,13 @@ public abstract class AbstractBaseMenu extends AbstractMenu<Menu> {
|
||||
public abstract String getMenuName();
|
||||
|
||||
/**
|
||||
* 初始化菜单项
|
||||
* 获取菜单项
|
||||
*
|
||||
* @param menuItems 菜单项集合
|
||||
* @param menu 菜单
|
||||
* @return 菜单项集合
|
||||
*/
|
||||
@Override
|
||||
protected void initMenuItems(Map<String, MenuItem> menuItems, Menu menu) {
|
||||
logger.info("初始化菜单项!");
|
||||
Map<String, MenuItem> 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<MenuItem> getItems() {
|
||||
return getMenu().getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,6 +46,6 @@ public abstract class AbstractBaseMenu extends AbstractMenu<Menu> {
|
||||
// 菜单名称国际化
|
||||
UiResourceBundle.bindStringProperty(menu.textProperty(), getMenuName());
|
||||
// 初始化菜单项
|
||||
initMenuItems(getMenuItems(), menu);
|
||||
initMenuItems(getMenuItems());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<T> {
|
||||
protected Logger logger = LogUtil.getLogger(this.getClass());
|
||||
UserConfigController userConfigController = UserConfigController.getInstance();
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
@ -44,6 +48,13 @@ public abstract class AbstractMenu<T> {
|
||||
*/
|
||||
protected abstract void initMenu();
|
||||
|
||||
/**
|
||||
* 获取菜单项
|
||||
*
|
||||
* @return 菜单项集合
|
||||
*/
|
||||
protected abstract ObservableList<MenuItem> getItems();
|
||||
|
||||
|
||||
/**
|
||||
* 注册菜单项
|
||||
@ -59,20 +70,6 @@ public abstract class AbstractMenu<T> {
|
||||
menuItem.setOnAction(eventHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册菜单项
|
||||
*
|
||||
* @param menuItem 菜单项
|
||||
* @param menuItemName 菜单项名称
|
||||
* @param userData 用户数据,用来存放必要的数据,比如按钮菜单项名称
|
||||
* @param eventHandler 事件处理器
|
||||
*/
|
||||
public void registerMenuItem(MenuItem menuItem, String menuItemName, Object userData, EventHandler<ActionEvent> eventHandler, boolean isDisable) {
|
||||
if (!isDisable) {
|
||||
registerMenuItem(menuItem, menuItemName, userData, eventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册检查菜单项
|
||||
*
|
||||
@ -87,32 +84,6 @@ public abstract class AbstractMenu<T> {
|
||||
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<T> {
|
||||
radioMenuItem.setOnAction(eventHandler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化菜单项
|
||||
*
|
||||
* @param menuItems 菜单项集合
|
||||
* @param menu 菜单
|
||||
*/
|
||||
protected abstract void initMenuItems(Map<String, MenuItem> menuItems, T menu);
|
||||
protected void initMenuItems(Map<String, MenuItem> menuItems) {
|
||||
logger.info("初始化菜单项!");
|
||||
Map<String, MenuItem> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<B, T> {
|
||||
/**
|
||||
* 上下文菜单项
|
||||
*/
|
||||
protected final Map<String, MenuItem> menuItems = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Get subclass builder
|
||||
*
|
||||
@ -18,6 +29,13 @@ public abstract class AbstractMenuBuilder<B, T> {
|
||||
*/
|
||||
protected abstract B getBuilder();
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*
|
||||
* @return 菜单
|
||||
*/
|
||||
protected abstract T getMenu();
|
||||
|
||||
/**
|
||||
* Retrieves the items of the menu.
|
||||
*
|
||||
@ -35,6 +53,7 @@ public abstract class AbstractMenuBuilder<B, T> {
|
||||
public B addMenuItem(String label, EventHandler<ActionEvent> 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<B, T> {
|
||||
*
|
||||
* @param label 菜单项名称
|
||||
* @param eventHandler 事件
|
||||
* @param disable 是否禁用
|
||||
* @param visible 是否可见
|
||||
* @return 建造者
|
||||
*/
|
||||
public B addMenuItem(String label, EventHandler<ActionEvent> eventHandler, boolean disable) {
|
||||
if (!disable) {
|
||||
return getBuilder();
|
||||
}
|
||||
public B addMenuItem(String label, EventHandler<ActionEvent> 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<B, T> {
|
||||
public B addRadioMenuItem(String label, EventHandler<ActionEvent> 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<B, T> {
|
||||
public B addCheckMenuItem(String label, EventHandler<ActionEvent> eventHandler) {
|
||||
CheckMenuItem menuItem = new CheckMenuItem(label);
|
||||
menuItem.setOnAction(eventHandler);
|
||||
menuItems.put(label, menuItem);
|
||||
getItems().add(menuItem);
|
||||
return getBuilder();
|
||||
}
|
||||
|
||||
|
||||
public B addCheckMenuItem(CheckMenuItem checkMenuItem, EventHandler<ActionEvent> eventHandler) {
|
||||
checkMenuItem.setOnAction(eventHandler);
|
||||
menuItems.put(checkMenuItem.getText(), checkMenuItem);
|
||||
getItems().add(checkMenuItem);
|
||||
return getBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加菜单
|
||||
*
|
||||
@ -92,6 +121,7 @@ public abstract class AbstractMenuBuilder<B, T> {
|
||||
* @return 建造者
|
||||
*/
|
||||
public B addMenu(Menu menu) {
|
||||
menuItems.put(menu.getText(), menu);
|
||||
getItems().add(menu);
|
||||
return getBuilder();
|
||||
}
|
||||
@ -100,17 +130,18 @@ public abstract class AbstractMenuBuilder<B, T> {
|
||||
* 添加菜单
|
||||
*
|
||||
* @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<B, T> {
|
||||
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<String, MenuItem> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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,28 +14,15 @@ import javafx.scene.control.MenuItem;
|
||||
* </p>
|
||||
*
|
||||
* @author gewuyou
|
||||
*
|
||||
*/
|
||||
public class ContextMenuBuilder extends AbstractMenuBuilder<ContextMenuBuilder, ContextMenu> {
|
||||
|
||||
private final ContextMenu contextMenu;
|
||||
|
||||
/**
|
||||
* 构造上下文菜单建造者
|
||||
*/
|
||||
public ContextMenuBuilder() {
|
||||
contextMenu = new ContextMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回上下文菜单对象。
|
||||
*
|
||||
* @return 构建的上下文菜单对象
|
||||
*/
|
||||
@Override
|
||||
public ContextMenu build() {
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子类的建造者实例
|
||||
*
|
||||
@ -44,6 +33,16 @@ public class ContextMenuBuilder extends AbstractMenuBuilder<ContextMenuBuilder,
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*
|
||||
* @return 菜单
|
||||
*/
|
||||
@Override
|
||||
protected ContextMenu getMenu() {
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上下文菜单的菜单项列表
|
||||
*
|
||||
@ -53,4 +52,19 @@ public class ContextMenuBuilder extends AbstractMenuBuilder<ContextMenuBuilder,
|
||||
protected ObservableList<MenuItem> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,11 +12,12 @@ import javafx.scene.control.MenuItem;
|
||||
* </p>
|
||||
*
|
||||
* @author gewuyou
|
||||
*
|
||||
*/
|
||||
public class MenuBuilder extends AbstractMenuBuilder<MenuBuilder, Menu> {
|
||||
|
||||
private final Menu menu;
|
||||
|
||||
|
||||
/**
|
||||
* 构造菜单建造者
|
||||
*
|
||||
@ -36,6 +37,16 @@ public class MenuBuilder extends AbstractMenuBuilder<MenuBuilder, Menu> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*
|
||||
* @return 菜单
|
||||
*/
|
||||
@Override
|
||||
protected Menu getMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单的菜单项列表
|
||||
*
|
||||
@ -46,13 +57,4 @@ public class MenuBuilder extends AbstractMenuBuilder<MenuBuilder, Menu> {
|
||||
return menu.getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建菜单
|
||||
*
|
||||
* @return 构建的菜单对象
|
||||
*/
|
||||
@Override
|
||||
public Menu build() {
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ import org.jcnc.jnotepad.ui.views.root.bottom.function.FunctionBox;
|
||||
* </p>
|
||||
*
|
||||
* @author gewuyou
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractFunctionChildrenBox {
|
||||
protected final FunctionBox functionBox;
|
||||
|
||||
@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@ -19,13 +19,8 @@ import static org.jcnc.jnotepad.app.common.constants.AppConstants.PROGRAM_FILE_D
|
||||
* </p>
|
||||
*
|
||||
* @author gewuyou
|
||||
*
|
||||
*/
|
||||
public class AppConfig {
|
||||
/**
|
||||
* 程序根路径
|
||||
*/
|
||||
private String rootPath;
|
||||
/**
|
||||
* 排除的文件夹
|
||||
*/
|
||||
@ -36,6 +31,10 @@ public class AppConfig {
|
||||
*/
|
||||
@JsonIgnore
|
||||
private final Set<File> ignoreFile;
|
||||
/**
|
||||
* 程序根路径
|
||||
*/
|
||||
private String rootPath;
|
||||
/**
|
||||
* 上次的程序根路径
|
||||
*/
|
||||
|
||||
@ -12,7 +12,6 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* @author gewuyou
|
||||
*
|
||||
*/
|
||||
public class PluginConfig {
|
||||
private List<PluginDescriptor> plugins;
|
||||
|
||||
@ -13,7 +13,6 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* @author luke
|
||||
*
|
||||
*/
|
||||
public class UserConfig {
|
||||
|
||||
|
||||
@ -316,5 +316,9 @@ public class FileUtil {
|
||||
}
|
||||
return orDefault;
|
||||
}
|
||||
|
||||
public static void openTerminal(File file) {
|
||||
//todo @luke 请你在此设置打开文件所在文件夹路径于终端
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -15,17 +15,11 @@ import static org.jcnc.jnotepad.app.common.constants.AppConstants.PROGRAM_FILE_D
|
||||
*/
|
||||
public class AppConfigController extends BaseConfigController<AppConfig> {
|
||||
|
||||
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<AppConfig> {
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
public static AppConfigController getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置文件Class类
|
||||
*
|
||||
|
||||
@ -66,6 +66,10 @@ public class PluginConfigController extends BaseConfigController<PluginConfig> {
|
||||
return configDir;
|
||||
}
|
||||
|
||||
public void setConfigDir(String configDir) {
|
||||
this.configDir = configDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建配置文件实体
|
||||
*
|
||||
@ -79,11 +83,6 @@ public class PluginConfigController extends BaseConfigController<PluginConfig> {
|
||||
return pluginConfig;
|
||||
}
|
||||
|
||||
|
||||
public void setConfigDir(String configDir) {
|
||||
this.configDir = configDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件路径
|
||||
*
|
||||
|
||||
@ -34,11 +34,9 @@ public class UserConfigController extends BaseConfigController<UserConfig> {
|
||||
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<Map<String, MenuItem>> 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();
|
||||
|
||||
@ -25,10 +25,10 @@ import java.io.File;
|
||||
*/
|
||||
public class OpenDirectory implements EventHandler<ActionEvent> {
|
||||
|
||||
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) {
|
||||
// 获取缓存
|
||||
|
||||
@ -8,7 +8,6 @@ import org.jcnc.jnotepad.ui.views.manager.BuildPanelManager;
|
||||
/**
|
||||
* 终端处理器
|
||||
*
|
||||
*
|
||||
* @author cccqyu
|
||||
*/
|
||||
public class RunBtn implements EventHandler<ActionEvent> {
|
||||
|
||||
@ -34,16 +34,15 @@ public class PluginManager {
|
||||
* 插件类别
|
||||
*/
|
||||
private final Map<String, List<String>> categories = new HashMap<>();
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
/**
|
||||
* 插件信息
|
||||
*/
|
||||
private List<PluginDescriptor> pluginDescriptors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 插件信息临时集合
|
||||
*/
|
||||
private List<PluginDescriptor> temporaryPluginDescriptors;
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
private PluginManager() {
|
||||
|
||||
@ -134,6 +133,7 @@ public class PluginManager {
|
||||
|
||||
/**
|
||||
* 执行加载的插件
|
||||
*
|
||||
* @deprecated 待删除
|
||||
*/
|
||||
public void executePlugins() {
|
||||
|
||||
@ -48,6 +48,10 @@ public class DirFileModel {
|
||||
return childFile;
|
||||
}
|
||||
|
||||
public void setChildFile(List<DirFileModel> 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<DirFileModel> childFile) {
|
||||
this.childFile = childFile;
|
||||
public void setIconIsSelected(Node iconIsSelected) {
|
||||
this.iconIsSelected = iconIsSelected;
|
||||
}
|
||||
}
|
||||
@ -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<Collection<String>> computeHighlighting(String text) {
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
int lastKwEnd = 0;
|
||||
StyleSpansBuilder<Collection<String>> 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<String, String> patternToStyleClass = new HashMap<>(16);
|
||||
patternToStyleClass.put("keyword", matcher.group("KEYWORD"));
|
||||
@ -143,4 +125,19 @@ public class TextCodeArea extends CodeArea {
|
||||
// 永不发生
|
||||
return null;
|
||||
}
|
||||
|
||||
private StyleSpans<Collection<String>> computeHighlighting(String text) {
|
||||
Matcher matcher = PATTERN.matcher(text);
|
||||
int lastKwEnd = 0;
|
||||
StyleSpansBuilder<Collection<String>> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,33 +13,18 @@ import org.jcnc.jnotepad.ui.component.module.vbox.components.RunBox;
|
||||
*
|
||||
* <p>可以通过调用getInstance方法获取单例实例。</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取命令终端组件。
|
||||
*
|
||||
|
||||
@ -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对象的构造函数。
|
||||
*/
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 私有构造方法以实现单例模式。
|
||||
|
||||
@ -53,27 +53,23 @@ import java.util.Map;
|
||||
* @author luke
|
||||
*/
|
||||
public class PluginManagementPane extends AbstractPaneStage {
|
||||
PluginManager pluginManager = PluginManager.getInstance();
|
||||
|
||||
/**
|
||||
* 图标大小常量
|
||||
*/
|
||||
public static int ICON_SIZE = 40;
|
||||
|
||||
/**
|
||||
* 日志记录器
|
||||
*/
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 自定义分割面板
|
||||
*/
|
||||
private CustomSplitPane customSplitPane;
|
||||
|
||||
/**
|
||||
* 用于存储Tile与其内容节点的映射关系
|
||||
*/
|
||||
private final Map<Tile, Node> tileContentMap = new HashMap<>();
|
||||
PluginManager pluginManager = PluginManager.getInstance();
|
||||
/**
|
||||
* 日志记录器
|
||||
*/
|
||||
Logger logger = LogUtil.getLogger(this.getClass());
|
||||
/**
|
||||
* 自定义分割面板
|
||||
*/
|
||||
private CustomSplitPane customSplitPane;
|
||||
|
||||
/**
|
||||
* 创建一个插件管理面板的实例。
|
||||
@ -81,6 +77,7 @@ public class PluginManagementPane extends AbstractPaneStage {
|
||||
public PluginManagementPane() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件管理面板。
|
||||
*/
|
||||
|
||||
@ -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<Tab> tabs) {
|
||||
ObservableList<Node> 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)) {
|
||||
icon = FontIcon.of(UNLOCK);
|
||||
readOnlyButton.setGraphic(icon);
|
||||
} else {
|
||||
registerChildren(builder
|
||||
.setFontIcon(icon)
|
||||
.setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(tab))
|
||||
.build());
|
||||
}
|
||||
|
||||
} else {
|
||||
FontIcon icon = FontIcon.of(LOCK);
|
||||
if (children.contains(readOnlyButton)) {
|
||||
icon = FontIcon.of(LOCK);
|
||||
readOnlyButton.setGraphic(icon);
|
||||
} else {
|
||||
registerChildren(builder
|
||||
.setFontIcon(icon)
|
||||
.setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(tab))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
if (tabs.isEmpty()) {
|
||||
children.remove(readOnlyButton);
|
||||
}
|
||||
}
|
||||
tab.getReadOnly().setSelected(!tab.getTextCodeArea().isEditable());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 控制终端显示
|
||||
*/
|
||||
|
||||
@ -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() {
|
||||
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,96 +228,20 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否有左侧标签页
|
||||
*
|
||||
* @param centerTab 标签页
|
||||
* @apiNote 由于不知道怎么监听固定状态,因此,还是使用简单的判断,如果能够监听固定状态时可以把代码修改为
|
||||
* <blockquote><pre>
|
||||
* public boolean hasLeftTabs(CenterTab centerTab) {
|
||||
* ObservableList<Tab> 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;
|
||||
* }
|
||||
* <blockquote><pre>
|
||||
* @return 是否有左侧标签页
|
||||
*/
|
||||
public boolean hasLeftTabs(CenterTab centerTab) {
|
||||
int index = centerTabPane.getTabs().indexOf(centerTab);
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有右侧标签页
|
||||
*
|
||||
* @param centerTab 标签页
|
||||
* @return 是否有右侧标签页
|
||||
* @apiNote 由于不知道怎么监听固定状态,因此,还是使用简单的判断,如果能够监听固定状态时可以把代码修改为
|
||||
* <blockquote><pre>
|
||||
* public boolean hasRightTabs(CenterTab centerTab) {
|
||||
* ObservableList<Tab> 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;
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*/
|
||||
public boolean hasRightTabs(CenterTab centerTab) {
|
||||
ObservableList<Tab> tabs = centerTabPane.getTabs();
|
||||
int index = tabs.indexOf(centerTab);
|
||||
return index != tabs.size() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener for the tabs in the center tab pane.
|
||||
*
|
||||
* @param tab the tab to set the listener for
|
||||
*/
|
||||
public void setTabsListener(CenterTab tab) {
|
||||
ObservableList<Tab> tabs = centerTabPane.getTabs();
|
||||
tabs.addListener((ListChangeListener<Tab>) c -> {
|
||||
tab.contextMenuMonitor();
|
||||
BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, tabs);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the pinned state of the given center tab.
|
||||
*
|
||||
* @param tab the center tab to update
|
||||
*/
|
||||
public void updateTabPinnedState(CenterTab tab) {
|
||||
tab.setFixed(!tab.isFixed());
|
||||
tab.setClosable(!tab.isFixed());
|
||||
tab.setFixedProperty(tab.getNotFixedProperty());
|
||||
tab.setClosable(tab.getNotFixedProperty());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,7 +252,57 @@ public class CenterTabPaneManager {
|
||||
public void updateReadOnlyProperty(CenterTab tab) {
|
||||
TextCodeArea textCodeArea = tab.getTextCodeArea();
|
||||
textCodeArea.setEditable(!textCodeArea.isEditable());
|
||||
tab.contextMenuMonitor();
|
||||
BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, centerTabPane.getTabs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to the tabs in the center tab pane.
|
||||
*/
|
||||
private void addTabsListener() {
|
||||
centerTabPane.getTabs().addListener((ListChangeListener<Tab>) change -> {
|
||||
ObservableList<? extends Tab> list = change.getList();
|
||||
list.forEach(tab -> {
|
||||
CenterTab centerTab = (CenterTab) tab;
|
||||
// 判断标签页
|
||||
checkTabs(list, centerTab);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the tabs in the given list and updates the properties of the centerTab accordingly.
|
||||
*
|
||||
* @param list the list of tabs to check
|
||||
* @param centerTab the centerTab to update
|
||||
*/
|
||||
public void checkTabs(ObservableList<? extends Tab> list, CenterTab centerTab) {
|
||||
int index = list.indexOf(centerTab);
|
||||
boolean hasOther = false;
|
||||
boolean hasLeft = false;
|
||||
boolean hasRight = false;
|
||||
int tabCount = list.size();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
/**
|
||||
* 设置文件树项监听事件
|
||||
*
|
||||
* @param item 文件树项
|
||||
* @return 监听事件
|
||||
*/
|
||||
private static ChangeListener<Boolean> getTreeItemListener(TreeItem<DirFileModel> item) {
|
||||
return (observable, oldValue, newValue) -> {
|
||||
if (Boolean.TRUE.equals(newValue)) {
|
||||
item.setGraphic(item.getValue().getIconIsSelected());
|
||||
} else {
|
||||
item.setGraphic(item.getValue().getIconIsNotSelected());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final DirectorySidebarPane DIRECTORY_SIDEBAR_PANE = DirectorySidebarPane.getInstance();
|
||||
|
||||
|
||||
private static final double LAST_DIVIDER_POSITION = 0.3;
|
||||
|
||||
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<Boolean> getTreeItemListener(TreeItem<DirFileModel> 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
|
||||
*
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -19,11 +19,11 @@ import java.util.List;
|
||||
*/
|
||||
public class SidebarToolBarManager extends AbstractManager<Node> {
|
||||
private static final SidebarToolBarManager INSTANCE = new SidebarToolBarManager();
|
||||
private final List<Node> nodeList = new ArrayList<>();
|
||||
/**
|
||||
* 工具栏
|
||||
*/
|
||||
SidebarToolBar sidebarToolBar = SidebarToolBar.getInstance();
|
||||
private final List<Node> nodeList = new ArrayList<>();
|
||||
|
||||
public static SidebarToolBarManager getInstance() {
|
||||
return INSTANCE;
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
||||
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isRelevance() {
|
||||
return isRelevance;
|
||||
private void initFixedStateListener() {
|
||||
fixedProperty.addListener((observable, oldValue, newValue) -> {
|
||||
ObservableList<Tab> tabs = CenterTabPane.getInstance().getTabs();
|
||||
tabs.forEach(tab -> CenterTabPaneManager.getInstance().checkTabs(tabs, (CenterTab) tab));
|
||||
});
|
||||
}
|
||||
|
||||
public void setRelevance(boolean relevance) {
|
||||
isRelevance = relevance;
|
||||
|
||||
public boolean getRelevanceProperty() {
|
||||
return relevanceProperty.get();
|
||||
}
|
||||
|
||||
public void setRelevanceProperty(boolean relevanceProperty) {
|
||||
this.relevanceProperty.set(relevanceProperty);
|
||||
}
|
||||
|
||||
|
||||
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 setFixed(boolean fixed) {
|
||||
isFixed.set(fixed);
|
||||
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 setHasOtherTabsProperty(boolean hasOtherTabsProperty) {
|
||||
this.hasOtherTabsProperty.set(hasOtherTabsProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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<String, MenuItem> runMenuItems = new HashMap<>();
|
||||
EventHandler<ActionEvent> 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<ActionEvent> 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代码的方法
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -39,9 +39,7 @@ CLOSE_LEFT_TABS=关闭左侧标签页
|
||||
CLOSE_RIGHT_TABS=关闭右侧标签页
|
||||
CLOSE_OTHER_TABS=关闭其他标签页
|
||||
FIXED_TAB=固定标签页
|
||||
UNFIXED_TAB=取消固定
|
||||
READ_ONLY=只读
|
||||
UNREAD_ONLY=取消只读
|
||||
OPEN_ON=打开于
|
||||
|
||||
|
||||
|
||||
@ -28,3 +28,16 @@ ROW=Row
|
||||
FILE=File
|
||||
MANAGER_PLUGIN=Manager Plugin
|
||||
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
|
||||
|
||||
@ -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=打开于
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user