👔 完善标签页右键菜单的图标支持
This commit is contained in:
parent
249333b961
commit
6fee8fe4ee
@ -0,0 +1,46 @@
|
||||
package org.jcnc.jnotepad.api.core.views.manager.builder;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Button;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 下方状态栏按钮建造者
|
||||
*
|
||||
* @author gewuyou
|
||||
*/
|
||||
public class BottomStatusBoxButtonBuilder {
|
||||
private Button button;
|
||||
|
||||
private FontIcon fontIcon;
|
||||
|
||||
private EventHandler<ActionEvent> eventHandler;
|
||||
|
||||
public BottomStatusBoxButtonBuilder() {
|
||||
}
|
||||
|
||||
public BottomStatusBoxButtonBuilder(Button button) {
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
public BottomStatusBoxButtonBuilder setFontIcon(FontIcon fontIcon) {
|
||||
this.fontIcon = fontIcon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BottomStatusBoxButtonBuilder setEventHandler(EventHandler<ActionEvent> eventHandler) {
|
||||
this.eventHandler = eventHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button build() {
|
||||
Optional<Button> container = Optional.ofNullable(button);
|
||||
button = container.orElseGet(Button::new);
|
||||
button.setGraphic(fontIcon);
|
||||
button.setOnAction(eventHandler);
|
||||
return button;
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ public abstract class AbstractMenuBuilder<B, T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加单选菜单项 todo 待完善
|
||||
* 添加单选菜单项
|
||||
*
|
||||
* @param label 菜单项名称
|
||||
* @param eventHandler 事件
|
||||
|
||||
@ -160,7 +160,6 @@ public class SetStage {
|
||||
securityItem.getChildren().add(securityItem2);
|
||||
|
||||
|
||||
|
||||
root.getChildren().add(generalItem);
|
||||
root.getChildren().add(appearanceItem);
|
||||
root.getChildren().add(securityItem);
|
||||
@ -203,7 +202,6 @@ public class SetStage {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建常规设置项1的布局。
|
||||
*
|
||||
@ -225,12 +223,11 @@ public class SetStage {
|
||||
var fileChooseBtn = new Button();
|
||||
fileChooseBtn.setText("选择文件夹");
|
||||
fileChooseBtn.getStyleClass().addAll(Styles.SMALL);
|
||||
BasicDirectoryChooserFactory directoryChooserFactory = BasicDirectoryChooserFactory.getInstance();
|
||||
fileChooseBtn.setOnAction(event -> {
|
||||
// 获取打开目录缓存
|
||||
Cache cache = cacheManager.getCache(OpenDirectory.GROUP, "openDirectory");
|
||||
|
||||
File file = directoryChooserFactory.createDirectoryChooser(
|
||||
File file = BasicDirectoryChooserFactory.getInstance().createDirectoryChooser(
|
||||
UiResourceBundle.getContent(TextConstants.OPEN),
|
||||
cache == null ? null : new File((String) cache.getCacheData()))
|
||||
.showDialog(UiUtil.getAppWindow());
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package org.jcnc.jnotepad.util;
|
||||
|
||||
import javafx.scene.control.CheckMenuItem;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
@ -40,7 +39,7 @@ import static org.jcnc.jnotepad.util.FileUtil.getFileText;
|
||||
*/
|
||||
public class TabUtil {
|
||||
private static final ApplicationCacheManager CACHE_MANAGER = ApplicationCacheManager.getInstance();
|
||||
static Logger logger = LogUtil.getLogger(TabUtil.class);
|
||||
private static final Logger logger = LogUtil.getLogger(TabUtil.class);
|
||||
|
||||
private TabUtil() {
|
||||
}
|
||||
@ -91,7 +90,9 @@ public class TabUtil {
|
||||
.showSaveDialog(UiUtil.getAppWindow());
|
||||
if (file != null) {
|
||||
if (cache == null) {
|
||||
CACHE_MANAGER.addCache(CACHE_MANAGER.createCache("folder", "saveFile", file.getParent(), CacheExpirationTime.NEVER_EXPIRES.getValue()));
|
||||
CACHE_MANAGER.addCache(
|
||||
CACHE_MANAGER.createCache("folder", "saveFile", file.getParent(),
|
||||
CacheExpirationTime.NEVER_EXPIRES.getValue()));
|
||||
} else {
|
||||
cache.setCacheData(file.getParent());
|
||||
CACHE_MANAGER.addCache(cache);
|
||||
@ -202,9 +203,12 @@ public class TabUtil {
|
||||
* 显示警告弹窗,提示用户更换重复的名称。
|
||||
*/
|
||||
private static void showDuplicateNameAlert(String newTabName) {
|
||||
|
||||
PopUpUtil.errorAlert("重命名错误", "\" " + newTabName + "\" 和已有标签页名字重复", "请再次重命名", null, null);
|
||||
|
||||
PopUpUtil.errorAlert(
|
||||
"重命名错误",
|
||||
"\" " + newTabName + "\" 和已有标签页名字重复",
|
||||
"请再次重命名",
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -336,13 +340,17 @@ public class TabUtil {
|
||||
//todo 设置上下文菜单
|
||||
tab.setContextMenu(
|
||||
builder
|
||||
.addMenuItem("关闭", e -> centerTabPaneManager.removeTab(tab))
|
||||
.addMenuItem(
|
||||
"关闭",
|
||||
e -> centerTabPaneManager.removeTab(tab))
|
||||
.addMenuItem(
|
||||
"关闭其它标签页",
|
||||
e -> centerTabPaneManager.removeOtherTabs(tab),
|
||||
centerTabPaneManager.hasOtherTabs()
|
||||
)
|
||||
.addMenuItem("关闭所有标签页", e -> centerTabPaneManager.removeAllTabs())
|
||||
.addMenuItem(
|
||||
"关闭所有标签页",
|
||||
e -> centerTabPaneManager.removeAllTabs())
|
||||
.addMenuItem(
|
||||
"关闭左侧标签页",
|
||||
e -> centerTabPaneManager.removeLeftTabs(tab),
|
||||
@ -386,9 +394,19 @@ public class TabUtil {
|
||||
})
|
||||
.build(), tab.isRelevance())
|
||||
.addSeparatorMenuItem()
|
||||
.addCheckMenuItem("固定标签页", e -> centerTabPaneManager.updateTabPinnedState(tab, (CheckMenuItem) e.getSource()))
|
||||
.addMenuItem("固定标签页",
|
||||
e -> centerTabPaneManager.updateTabPinnedState(tab),
|
||||
!tab.isFixed())
|
||||
.addMenuItem("取消固定",
|
||||
e -> centerTabPaneManager.updateTabPinnedState(tab),
|
||||
tab.isFixed())
|
||||
.addSeparatorMenuItem()
|
||||
.addCheckMenuItem("只读", e -> centerTabPaneManager.updateReadOnlyProperty(tab, (CheckMenuItem) e.getSource()))
|
||||
.addMenuItem("只读",
|
||||
e -> centerTabPaneManager.updateReadOnlyProperty(tab),
|
||||
tab.getTextCodeArea().isEditable())
|
||||
.addMenuItem("取消只读",
|
||||
e -> centerTabPaneManager.updateReadOnlyProperty(tab),
|
||||
!tab.getTextCodeArea().isEditable())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,27 @@
|
||||
package org.jcnc.jnotepad.views.manager;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.jcnc.jnotepad.api.core.views.manager.builder.BottomStatusBoxButtonBuilder;
|
||||
import org.jcnc.jnotepad.app.i18n.UiResourceBundle;
|
||||
import org.jcnc.jnotepad.common.constants.TextConstants;
|
||||
import org.jcnc.jnotepad.component.module.TextCodeArea;
|
||||
import org.jcnc.jnotepad.views.root.bottom.status.BottomStatusBox;
|
||||
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled.LOCK;
|
||||
import static org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled.UNLOCK;
|
||||
|
||||
/**
|
||||
* 状态栏组件管理类
|
||||
*
|
||||
@ -58,10 +67,9 @@ public class BottomStatusBoxManager {
|
||||
*/
|
||||
public void registerBottomStatusBox() {
|
||||
Label statusLabel = BOTTOM_STATUS_BOX.getStatusLabel();
|
||||
registerChildrenByLabel(statusLabel);
|
||||
registerChildren(statusLabel);
|
||||
statusLabel.setText(getStatusBarFormattedText(0, 0, 1));
|
||||
|
||||
registerChildrenByLabel(BOTTOM_STATUS_BOX.getEncodingLabel());
|
||||
registerChildren(BOTTOM_STATUS_BOX.getEncodingLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,13 +81,14 @@ public class BottomStatusBoxManager {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册状态栏标签组件
|
||||
* Registers the given node as a child of the current node.
|
||||
*
|
||||
* @param label 标签组件
|
||||
* @param node the node to be registered as a child
|
||||
*/
|
||||
public void registerChildrenByLabel(Label label) {
|
||||
BOTTOM_STATUS_BOX.getChildren().add(label);
|
||||
public void registerChildren(Node node) {
|
||||
BOTTOM_STATUS_BOX.getChildren().add(node);
|
||||
}
|
||||
|
||||
public void updateEncodingLabel() {
|
||||
@ -195,4 +204,35 @@ public class BottomStatusBoxManager {
|
||||
String encodingLabelFormat = "%s : %s";
|
||||
return String.format(encodingLabelFormat, UiResourceBundle.getContent(TextConstants.ENCODE), encoding);
|
||||
}
|
||||
|
||||
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);
|
||||
if (tab.getTextCodeArea().isEditable()) {
|
||||
FontIcon icon = FontIcon.of(LOCK);
|
||||
if (children.contains(readOnlyButton)) {
|
||||
readOnlyButton.setGraphic(icon);
|
||||
} else {
|
||||
registerChildren(builder
|
||||
.setFontIcon(icon)
|
||||
.setEventHandler(e -> CenterTabPaneManager.getInstance().updateReadOnlyProperty(tab))
|
||||
.build());
|
||||
}
|
||||
|
||||
} else {
|
||||
FontIcon icon = FontIcon.of(UNLOCK);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package org.jcnc.jnotepad.views.manager;
|
||||
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.CheckMenuItem;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.stage.Stage;
|
||||
import org.jcnc.jnotepad.common.manager.ApplicationCacheManager;
|
||||
@ -14,15 +13,12 @@ import org.jcnc.jnotepad.util.PopUpUtil;
|
||||
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTab;
|
||||
import org.jcnc.jnotepad.views.root.center.main.center.tab.CenterTabPane;
|
||||
import org.jcnc.jnotepad.views.root.top.menubar.TopMenuBar;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.kordamp.ikonli.antdesignicons.AntDesignIconsFilled.PUSHPIN;
|
||||
|
||||
/**
|
||||
* 中心标签页窗格管理类
|
||||
*
|
||||
@ -276,7 +272,7 @@ public class CenterTabPaneManager {
|
||||
* <blockquote><pre>
|
||||
* public boolean hasRightTabs(CenterTab centerTab) {
|
||||
* ObservableList<Tab> tabs = centerTabPane.getTabs();
|
||||
* for (int i = tabs.indexOf(centerTab); i < tabs.size(); i++) {
|
||||
* for (int i = tabs.indexOf(centerTab)+1; i < tabs.size(); i++) {
|
||||
* CenterTab tab = (CenterTab) tabs.get(i);
|
||||
* if (!tab.isFixed()) {
|
||||
* return true;
|
||||
@ -298,7 +294,11 @@ public class CenterTabPaneManager {
|
||||
* @param tab the tab to set the listener for
|
||||
*/
|
||||
public void setTabsListener(CenterTab tab) {
|
||||
centerTabPane.getTabs().addListener((ListChangeListener<Tab>) c -> tab.contextMenuMonitor());
|
||||
ObservableList<Tab> tabs = centerTabPane.getTabs();
|
||||
tabs.addListener((ListChangeListener<Tab>) c -> {
|
||||
tab.contextMenuMonitor();
|
||||
BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, centerTabPane.getTabs());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,27 +306,20 @@ public class CenterTabPaneManager {
|
||||
*
|
||||
* @param tab the center tab to update
|
||||
*/
|
||||
public void updateTabPinnedState(CenterTab tab, CheckMenuItem checkMenuItem) {
|
||||
public void updateTabPinnedState(CenterTab tab) {
|
||||
tab.setFixed(!tab.isFixed());
|
||||
if (tab.isFixed()) {
|
||||
FontIcon icon = FontIcon.of(PUSHPIN);
|
||||
icon.setRotate(-45);
|
||||
tab.setGraphic(icon);
|
||||
} else {
|
||||
tab.setGraphic(new FontIcon());
|
||||
}
|
||||
checkMenuItem.setSelected(tab.isFixed());
|
||||
tab.setClosable(!tab.isFixed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the read-only property of a given tab and its associated check menu item.
|
||||
*
|
||||
* @param tab the center tab to update
|
||||
* @param checkMenuItem the check menu item associated with the tab
|
||||
*/
|
||||
public void updateReadOnlyProperty(CenterTab tab, CheckMenuItem checkMenuItem) {
|
||||
public void updateReadOnlyProperty(CenterTab tab) {
|
||||
TextCodeArea textCodeArea = tab.getTextCodeArea();
|
||||
textCodeArea.setEditable(!textCodeArea.isEditable());
|
||||
checkMenuItem.setSelected(!textCodeArea.isEditable());
|
||||
tab.contextMenuMonitor();
|
||||
BottomStatusBoxManager.getInstance().updateReadOnlyProperty(tab, centerTabPane.getTabs());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jcnc.jnotepad.views.root.bottom.status;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import org.jcnc.jnotepad.component.module.base.AbstractHorizontalBox;
|
||||
|
||||
@ -23,6 +24,11 @@ public class BottomStatusBox extends AbstractHorizontalBox {
|
||||
*/
|
||||
private final Label encodingLabel = new Label();
|
||||
|
||||
/**
|
||||
* 只读按钮
|
||||
*/
|
||||
private final Button readOnlyButton = new Button();
|
||||
|
||||
private BottomStatusBox() {
|
||||
|
||||
}
|
||||
@ -39,4 +45,8 @@ public class BottomStatusBox extends AbstractHorizontalBox {
|
||||
public Label getEncodingLabel() {
|
||||
return encodingLabel;
|
||||
}
|
||||
|
||||
public Button getReadOnlyButton() {
|
||||
return readOnlyButton;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
package org.jcnc.jnotepad.views.root.center.main.center.tab;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.control.Tab;
|
||||
import org.fxmisc.flowless.VirtualizedScrollPane;
|
||||
import org.jcnc.jnotepad.api.core.views.menu.builder.ContextMenuBuilder;
|
||||
import org.jcnc.jnotepad.api.core.views.menu.builder.MenuBuilder;
|
||||
import org.jcnc.jnotepad.component.module.TextCodeArea;
|
||||
import org.jcnc.jnotepad.controller.config.UserConfigController;
|
||||
import org.jcnc.jnotepad.controller.event.handler.menuitem.RenameFile;
|
||||
import org.jcnc.jnotepad.controller.event.handler.menuitem.SaveFile;
|
||||
import org.jcnc.jnotepad.util.ClipboardUtil;
|
||||
import org.jcnc.jnotepad.util.LogUtil;
|
||||
import org.jcnc.jnotepad.util.TabUtil;
|
||||
import org.jcnc.jnotepad.views.manager.BottomStatusBoxManager;
|
||||
@ -42,7 +39,7 @@ public class CenterTab extends Tab {
|
||||
/**
|
||||
* 是否固定
|
||||
*/
|
||||
private boolean isFixed = false;
|
||||
private final BooleanProperty isFixed = new SimpleBooleanProperty(false);
|
||||
/**
|
||||
* 关联文件上次修改时间
|
||||
*/
|
||||
@ -66,6 +63,7 @@ public class CenterTab extends Tab {
|
||||
this.charset = charset;
|
||||
// 绑定标签页监听
|
||||
CenterTabPaneManager.getInstance().setTabsListener(this);
|
||||
isFixed.addListener((observable, oldValue, newValue) -> this.contextMenuMonitor());
|
||||
}
|
||||
|
||||
public boolean isRelevance() {
|
||||
@ -175,10 +173,10 @@ public class CenterTab extends Tab {
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return isFixed;
|
||||
return isFixed.get();
|
||||
}
|
||||
|
||||
public void setFixed(boolean fixed) {
|
||||
isFixed = fixed;
|
||||
isFixed.set(fixed);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user