Skip to content

Commit e55be4c

Browse files
committed
记事本添加 Tab 页支持,右键单击 Tab 页可切换自动换行
1 parent 340b206 commit e55be4c

5 files changed

Lines changed: 112 additions & 11 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,78 @@
11
package com.xwintop.xJavaFxTool.controller;
22

3+
import com.xwintop.xJavaFxTool.utils.NodeUtils;
34
import com.xwintop.xJavaFxTool.view.NotepadView;
5+
import java.io.IOException;
6+
import javafx.fxml.FXMLLoader;
7+
import javafx.scene.Node;
8+
import javafx.scene.control.CheckMenuItem;
9+
import javafx.scene.control.ContextMenu;
10+
import javafx.scene.control.Tab;
11+
import javafx.scene.control.TextArea;
12+
import lombok.extern.slf4j.Slf4j;
413

14+
@Slf4j
515
public class NotepadController extends NotepadView {
616

17+
private int counter = 0;
18+
719
public void initialize() {
20+
tabPane.getSelectionModel().selectedIndexProperty().addListener(((observable, oldValue, newValue) -> {
21+
int index = newValue.intValue();
22+
if (index + 1 == tabPane.getTabs().size()) {
23+
tabPane.getTabs().add(index, createTab());
24+
tabPane.getSelectionModel().select(index);
25+
}
26+
}));
27+
28+
Tab firstTab = tabPane.getTabs().get(0);
29+
setupTab(firstTab, firstTab.getContent());
30+
}
31+
32+
private Tab createTab() {
33+
counter += 1;
34+
Tab tab = new Tab("未命名" + counter);
35+
36+
try {
37+
Node content = FXMLLoader.load(NotepadController.class
38+
.getResource("/com/xwintop/xJavaFxTool/fxmlView/notepad-tab.fxml")
39+
);
40+
41+
setupTab(tab, content);
42+
43+
tab.setContent(content);
44+
} catch (IOException e) {
45+
log.error("读取 FXML 失败", e);
46+
}
47+
return tab;
48+
}
49+
50+
private void setupTab(Tab tab, Node content) {
51+
52+
TextArea textArea = (TextArea) content.lookup(".text-area");
53+
if (textArea != null) {
54+
NodeUtils.setUserData(textArea, "id", counter);
55+
textArea.textProperty().addListener((_ob, _old, _new) -> {
56+
if (_new.trim().length() == 0) {
57+
tab.setText("未命名" + NodeUtils.getUserData(textArea, "id"));
58+
} else if (_new.contains("\n")) {
59+
tab.setText(_new.substring(0, _new.indexOf("\n")));
60+
} else {
61+
tab.setText(_new);
62+
}
63+
});
64+
}
65+
66+
tab.setContextMenu(new ContextMenu(
67+
wrapTextMenuItem(textArea)
68+
));
69+
}
70+
71+
private CheckMenuItem wrapTextMenuItem(TextArea textArea) {
72+
CheckMenuItem menuItem = new CheckMenuItem("自动换行");
73+
if (textArea != null) {
74+
menuItem.setOnAction(event -> textArea.setWrapText(menuItem.isSelected()));
75+
}
76+
return menuItem;
877
}
978
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.xwintop.xJavaFxTool.utils;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import javafx.scene.Node;
6+
7+
@SuppressWarnings("unchecked")
8+
public class NodeUtils {
9+
10+
public static <T> T getUserData(Node node, String key) {
11+
return node.getUserData() == null ? null :
12+
!(node.getUserData() instanceof Map) ? null :
13+
(T) ((Map<String, Object>) node.getUserData()).get(key);
14+
}
15+
16+
public static void setUserData(Node node, String key, Object value) {
17+
Map<String, Object> map = (Map<String, Object>) node.getUserData();
18+
if (map == null) {
19+
map = new HashMap<>();
20+
node.setUserData(map);
21+
}
22+
map.put(key, value);
23+
}
24+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.xwintop.xJavaFxTool.view;
22

33
import javafx.fxml.FXML;
4-
import javafx.scene.control.TextArea;
4+
import javafx.scene.control.TabPane;
55

66
public abstract class NotepadView {
77

88
@FXML
9-
protected TextArea textArea;
9+
protected TabPane tabPane;
1010
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<?import javafx.scene.control.TextArea?>
4+
<?import javafx.scene.layout.VBox?>
5+
<VBox style="-fx-padding: 5">
6+
<TextArea VBox.vgrow="ALWAYS"
7+
style="-fx-font-size: 13; -fx-font-family: 'Fira Code', 'Consolas', monospace, 'Microsoft YaHei', sans-serif;-fx-border-color: #888888"/>
8+
</VBox>
9+
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

3-
<?import javafx.geometry.Insets?>
4-
<?import javafx.scene.control.TextArea?>
3+
<?import javafx.scene.control.Tab?>
4+
<?import javafx.scene.control.TabPane?>
55
<?import javafx.scene.layout.BorderPane?>
66
<BorderPane xmlns="http://javafx.com/javafx"
77
xmlns:fx="http://javafx.com/fxml"
88
fx:controller="com.xwintop.xJavaFxTool.controller.NotepadController">
9-
10-
<padding>
11-
<Insets topRightBottomLeft="5"/>
12-
</padding>
13-
149
<center>
15-
<TextArea fx:id="textArea"
16-
style="-fx-font-family:'Fira Code',Consolas,monospace,sans-serif;-fx-font-size:13;-fx-border-color:#888888"/>
10+
<TabPane tabMaxWidth="200" tabClosingPolicy="ALL_TABS" fx:id="tabPane">
11+
<Tab text="未命名" closable="false">
12+
<fx:include source="notepad-tab.fxml"/>
13+
</Tab>
14+
<Tab text="+" closable="false"/>
15+
</TabPane>
1716
</center>
1817
</BorderPane>

0 commit comments

Comments
 (0)