实现带行标的textarea
(未隐藏滚动条)
This commit is contained in:
parent
9617ee5046
commit
b2718c1932
1
.gitignore
vendored
1
.gitignore
vendored
@ -38,3 +38,4 @@ build/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/JNotepad/
|
/JNotepad/
|
||||||
/src/main/JNotepad.java
|
/src/main/JNotepad.java
|
||||||
|
/.idea/
|
||||||
|
|||||||
@ -11,4 +11,5 @@ module org.jcnc.jnotepad {
|
|||||||
exports org.jcnc.jnotepad.view.init;
|
exports org.jcnc.jnotepad.view.init;
|
||||||
exports org.jcnc.jnotepad.view.manager;
|
exports org.jcnc.jnotepad.view.manager;
|
||||||
exports org.jcnc.jnotepad.constants;
|
exports org.jcnc.jnotepad.constants;
|
||||||
|
exports org.jcnc.jnotepad.ui;
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ package org.jcnc.jnotepad.Interface;
|
|||||||
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.TextArea;
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,7 +18,7 @@ public interface ControllerInterface {
|
|||||||
* @param rawParameters 原始参数列表
|
* @param rawParameters 原始参数列表
|
||||||
* @return 创建的 TextArea
|
* @return 创建的 TextArea
|
||||||
*/
|
*/
|
||||||
TextArea openAssociatedFileAndCreateTextArea(List<String> rawParameters);
|
LineNumberTextArea openAssociatedFileAndCreateTextArea(List<String> rawParameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取换行符处理事件处理程序
|
* 获取换行符处理事件处理程序
|
||||||
@ -26,7 +26,7 @@ public interface ControllerInterface {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
* @return 换行符处理事件处理程序
|
* @return 换行符处理事件处理程序
|
||||||
*/
|
*/
|
||||||
EventHandler<ActionEvent> getLineFeedEventHandler(TextArea textArea);
|
EventHandler<ActionEvent> getLineFeedEventHandler(LineNumberTextArea textArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取新建文件处理事件处理程序
|
* 获取新建文件处理事件处理程序
|
||||||
@ -34,7 +34,7 @@ public interface ControllerInterface {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
* @return 新建文件处理事件处理程序
|
* @return 新建文件处理事件处理程序
|
||||||
*/
|
*/
|
||||||
EventHandler<ActionEvent> getNewFileEventHandler(TextArea textArea);
|
EventHandler<ActionEvent> getNewFileEventHandler(LineNumberTextArea textArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取打开文件处理事件处理程序
|
* 获取打开文件处理事件处理程序
|
||||||
@ -56,14 +56,14 @@ public interface ControllerInterface {
|
|||||||
*
|
*
|
||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
*/
|
*/
|
||||||
void autoSave(TextArea textArea);
|
void autoSave(LineNumberTextArea textArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新状态标签
|
* 更新状态标签
|
||||||
*
|
*
|
||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
*/
|
*/
|
||||||
void updateStatusLabel(TextArea textArea);
|
void updateStatusLabel(LineNumberTextArea textArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开关联文件
|
* 打开关联文件
|
||||||
@ -109,5 +109,5 @@ public interface ControllerInterface {
|
|||||||
*/
|
*/
|
||||||
void initTabPane();
|
void initTabPane();
|
||||||
|
|
||||||
void updateUIWithNewTextArea(TextArea textArea);
|
void updateUIWithNewTextArea(LineNumberTextArea textArea);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,13 @@ import atlantafx.base.theme.PrimerLight;
|
|||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.jcnc.jnotepad.constants.Constants;
|
import org.jcnc.jnotepad.constants.Constants;
|
||||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||||
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
import org.jcnc.jnotepad.view.init.View;
|
import org.jcnc.jnotepad.view.init.View;
|
||||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ public class LunchApp extends Application {
|
|||||||
private static final ExecutorService threadPool = Executors.newCachedThreadPool();
|
private static final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||||
public static boolean isRelevance = true;
|
public static boolean isRelevance = true;
|
||||||
|
|
||||||
|
Scene scene;
|
||||||
Controller controller = new Controller();
|
Controller controller = new Controller();
|
||||||
|
|
||||||
View view;
|
View view;
|
||||||
@ -30,23 +31,24 @@ public class LunchApp extends Application {
|
|||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) {
|
public void start(Stage primaryStage) {
|
||||||
|
|
||||||
view =new View();
|
view = new View();
|
||||||
|
|
||||||
Pane root = new Pane();
|
Pane root = new Pane();
|
||||||
|
|
||||||
|
|
||||||
double width = Constants.SCREEN_WIDTH;
|
double width = Constants.SCREEN_WIDTH;
|
||||||
double length = Constants.SCREEN_LENGTH;
|
double length = Constants.SCREEN_LENGTH;
|
||||||
String name = Constants.APP_NAME;
|
String name = Constants.APP_NAME;
|
||||||
String icon = Constants.APP_ICON;
|
String icon = Constants.APP_ICON;
|
||||||
|
|
||||||
Scene scene = new Scene(root, width, length);
|
scene = new Scene(root, width, length);
|
||||||
|
|
||||||
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
||||||
|
|
||||||
primaryStage.setTitle(name);
|
primaryStage.setTitle(name);
|
||||||
primaryStage.setWidth(width);
|
primaryStage.setWidth(width);
|
||||||
primaryStage.setHeight(length);
|
primaryStage.setHeight(length);
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
|
|
||||||
primaryStage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource(icon)).toString()));
|
primaryStage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource(icon)).toString()));
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
ViewManager viewManager = ViewManager.getInstance(scene);
|
ViewManager viewManager = ViewManager.getInstance(scene);
|
||||||
@ -58,15 +60,17 @@ public class LunchApp extends Application {
|
|||||||
view.initShortcutKey();
|
view.initShortcutKey();
|
||||||
|
|
||||||
if (isRelevance) {
|
if (isRelevance) {
|
||||||
|
|
||||||
// 使用线程池加载关联文件并创建文本区域
|
// 使用线程池加载关联文件并创建文本区域
|
||||||
List<String> rawParameters = getParameters().getRaw();
|
List<String> rawParameters = getParameters().getRaw();
|
||||||
threadPool.execute(() -> {
|
threadPool.execute(() -> {
|
||||||
TextArea textArea = controller.openAssociatedFileAndCreateTextArea(rawParameters);
|
LineNumberTextArea textArea = controller.openAssociatedFileAndCreateTextArea(rawParameters);
|
||||||
if (!Objects.isNull(textArea)) {
|
if (!Objects.isNull(textArea)) {
|
||||||
Platform.runLater(() -> controller.updateUIWithNewTextArea(textArea));
|
Platform.runLater(() -> controller.updateUIWithNewTextArea(textArea));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package org.jcnc.jnotepad.controller.event.handler;
|
|||||||
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.TextArea;
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 换行程序。
|
* 换行程序。
|
||||||
@ -10,13 +10,13 @@ import javafx.scene.control.TextArea;
|
|||||||
* 用于在文本区域中插入一个换行符。
|
* 用于在文本区域中插入一个换行符。
|
||||||
*/
|
*/
|
||||||
public class LineFeed implements EventHandler<ActionEvent> {
|
public class LineFeed implements EventHandler<ActionEvent> {
|
||||||
private final TextArea textArea;
|
private final LineNumberTextArea textArea;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数,初始化 LineFeed 对象。
|
* 构造函数,初始化 LineFeed 对象。
|
||||||
* @param textArea 要操作的文本区域
|
* @param textArea 要操作的文本区域
|
||||||
*/
|
*/
|
||||||
public LineFeed(TextArea textArea) {
|
public LineFeed(LineNumberTextArea textArea) {
|
||||||
this.textArea = textArea;
|
this.textArea = textArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public class LineFeed implements EventHandler<ActionEvent> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent event) {
|
public void handle(ActionEvent event) {
|
||||||
String text = textArea.getText();
|
String text = textArea.getMainTextArea().getText();
|
||||||
textArea.setText(text + "\n");
|
textArea.getMainTextArea().setText(text + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,12 @@ package org.jcnc.jnotepad.controller.event.handler;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TextArea;
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||||
import org.jcnc.jnotepad.view.manager.ViewManager;
|
import org.jcnc.jnotepad.view.manager.ViewManager;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
|
import static org.jcnc.jnotepad.view.manager.ViewManager.tabPane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,15 +27,21 @@ public class NewFile implements EventHandler<ActionEvent> {
|
|||||||
// 获取控制器
|
// 获取控制器
|
||||||
Controller controller = new Controller();
|
Controller controller = new Controller();
|
||||||
|
|
||||||
|
LineNumberTextArea lineNumberTextArea = new LineNumberTextArea();
|
||||||
|
|
||||||
|
|
||||||
// 创建一个新的文本编辑区
|
// 创建一个新的文本编辑区
|
||||||
TextArea textArea = new TextArea();
|
LineNumberTextArea textArea = new LineNumberTextArea();
|
||||||
|
|
||||||
|
|
||||||
textArea.setStyle(
|
textArea.setStyle(
|
||||||
"-fx-border-color:white;" +
|
"-fx-border-color:white ;-fx-background-color:white;"
|
||||||
"-fx-background-color:white"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// 创建一个新的Tab页
|
// 创建一个新的Tab页
|
||||||
Tab tab = new Tab("新建文本 " + ++ViewManager.tabIndex);
|
Tab tab = new Tab("新建文本 " + ++ViewManager.tabIndex);
|
||||||
tab.setContent(textArea);
|
tab.setContent(lineNumberTextArea.getMainTextArea());
|
||||||
|
|
||||||
// 将Tab页添加到TabPane中
|
// 将Tab页添加到TabPane中
|
||||||
tabPane.getTabs().add(tab);
|
tabPane.getTabs().add(tab);
|
||||||
@ -42,9 +50,9 @@ public class NewFile implements EventHandler<ActionEvent> {
|
|||||||
tabPane.getSelectionModel().select(tab);
|
tabPane.getSelectionModel().select(tab);
|
||||||
|
|
||||||
// 更新状态标签
|
// 更新状态标签
|
||||||
controller.updateStatusLabel(textArea);
|
controller.updateStatusLabel(lineNumberTextArea);
|
||||||
|
|
||||||
// 更新编码信息
|
// 更新编码信息
|
||||||
controller.upDateEncodingLabel(textArea.getText());
|
controller.upDateEncodingLabel(lineNumberTextArea.getMainTextArea().getText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,8 +3,9 @@ package org.jcnc.jnotepad.controller.event.handler;
|
|||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -38,7 +39,7 @@ public class OpenFile implements EventHandler<ActionEvent> {
|
|||||||
// 调用控制器的getText方法,读取文件内容
|
// 调用控制器的getText方法,读取文件内容
|
||||||
controller.getText(file);
|
controller.getText(file);
|
||||||
// 更新编码标签
|
// 更新编码标签
|
||||||
controller.upDateEncodingLabel(((TextArea) tabPane.getSelectionModel().getSelectedItem().getContent()).getText());
|
controller.upDateEncodingLabel(((LineNumberTextArea) tabPane.getSelectionModel().getSelectedItem().getContent()).getMainTextArea().getText());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,9 +3,8 @@ package org.jcnc.jnotepad.controller.event.handler;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -39,8 +38,8 @@ public class SaveAsFile implements EventHandler<ActionEvent> {
|
|||||||
if (file != null) {
|
if (file != null) {
|
||||||
try {
|
try {
|
||||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||||
TextArea textArea = (TextArea) selectedTab.getContent(); // 获取当前Tab页的文本编辑区
|
LineNumberTextArea textArea = (LineNumberTextArea) selectedTab.getContent(); // 获取当前Tab页的文本编辑区
|
||||||
String text = textArea.getText();
|
String text = textArea.getMainTextArea().getText();
|
||||||
writer.write(text); // 写入文件内容
|
writer.write(text); // 写入文件内容
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|||||||
@ -5,10 +5,9 @@ import javafx.concurrent.Task;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.paint.Color;
|
|
||||||
import javafx.scene.shape.Rectangle;
|
|
||||||
import org.jcnc.jnotepad.Interface.ControllerInterface;
|
import org.jcnc.jnotepad.Interface.ControllerInterface;
|
||||||
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
import org.jcnc.jnotepad.LunchApp;
|
import org.jcnc.jnotepad.LunchApp;
|
||||||
import org.jcnc.jnotepad.controller.event.handler.LineFeed;
|
import org.jcnc.jnotepad.controller.event.handler.LineFeed;
|
||||||
import org.jcnc.jnotepad.controller.event.handler.NewFile;
|
import org.jcnc.jnotepad.controller.event.handler.NewFile;
|
||||||
@ -33,13 +32,13 @@ public class Controller implements ControllerInterface {
|
|||||||
* @return 创建的文本区域
|
* @return 创建的文本区域
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TextArea openAssociatedFileAndCreateTextArea(List<String> rawParameters) {
|
public LineNumberTextArea openAssociatedFileAndCreateTextArea(List<String> rawParameters) {
|
||||||
if (!rawParameters.isEmpty()) {
|
if (!rawParameters.isEmpty()) {
|
||||||
String filePath = rawParameters.get(0);
|
String filePath = rawParameters.get(0);
|
||||||
openAssociatedFile(filePath);
|
openAssociatedFile(filePath);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
TextArea textArea = createNewTextArea();
|
LineNumberTextArea textArea = createNewTextArea();
|
||||||
configureTextArea(textArea);
|
configureTextArea(textArea);
|
||||||
return textArea;
|
return textArea;
|
||||||
}
|
}
|
||||||
@ -52,7 +51,7 @@ public class Controller implements ControllerInterface {
|
|||||||
* @return 行分隔事件处理程序
|
* @return 行分隔事件处理程序
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public EventHandler<ActionEvent> getLineFeedEventHandler(TextArea textArea) {
|
public EventHandler<ActionEvent> getLineFeedEventHandler(LineNumberTextArea textArea) {
|
||||||
return new LineFeed(textArea);
|
return new LineFeed(textArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ public class Controller implements ControllerInterface {
|
|||||||
* @return 新建文件事件处理程序
|
* @return 新建文件事件处理程序
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public EventHandler<ActionEvent> getNewFileEventHandler(TextArea textArea) {
|
public EventHandler<ActionEvent> getNewFileEventHandler(LineNumberTextArea textArea) {
|
||||||
return new NewFile();
|
return new NewFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +82,7 @@ public class Controller implements ControllerInterface {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void autoSave(TextArea textArea) {
|
public void autoSave(LineNumberTextArea textArea) {
|
||||||
textArea.textProperty().addListener((observable, oldValue, newValue) -> {
|
textArea.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
Tab tab = ViewManager.tabPane.getSelectionModel().getSelectedItem();
|
Tab tab = ViewManager.tabPane.getSelectionModel().getSelectedItem();
|
||||||
if (tab != null) {
|
if (tab != null) {
|
||||||
@ -116,11 +115,11 @@ public class Controller implements ControllerInterface {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateStatusLabel(TextArea textArea) {
|
public void updateStatusLabel(LineNumberTextArea textArea) {
|
||||||
int caretPosition = textArea.getCaretPosition();
|
int caretPosition = textArea.getMainTextArea().getCaretPosition();
|
||||||
int row = getRow(caretPosition, textArea.getText());
|
int row = getRow(caretPosition, textArea.getMainTextArea().getText());
|
||||||
int column = getColumn(caretPosition, textArea.getText());
|
int column = getColumn(caretPosition, textArea.getMainTextArea().getText());
|
||||||
int length = textArea.getLength();
|
int length = textArea.getMainTextArea().getLength();
|
||||||
ViewManager.statusLabel.setText("行: " + row + " \t列: " + column + " \t字数: " + length);
|
ViewManager.statusLabel.setText("行: " + row + " \t列: " + column + " \t字数: " + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +144,7 @@ public class Controller implements ControllerInterface {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void getText(File file) {
|
public void getText(File file) {
|
||||||
TextArea textArea = createNewTextArea();
|
LineNumberTextArea textArea = createNewTextArea();
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
StringBuilder textBuilder = new StringBuilder();
|
StringBuilder textBuilder = new StringBuilder();
|
||||||
String line;
|
String line;
|
||||||
@ -155,7 +154,7 @@ public class Controller implements ControllerInterface {
|
|||||||
String text = textBuilder.toString();
|
String text = textBuilder.toString();
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
textArea.setText(text);
|
textArea.getMainTextArea().setText(text);
|
||||||
|
|
||||||
Tab tab = createNewTab(file.getName(), textArea);
|
Tab tab = createNewTab(file.getName(), textArea);
|
||||||
tab.setUserData(file);
|
tab.setUserData(file);
|
||||||
@ -224,22 +223,22 @@ public class Controller implements ControllerInterface {
|
|||||||
ViewManager.tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> {
|
ViewManager.tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> {
|
||||||
if (newTab != null) {
|
if (newTab != null) {
|
||||||
// 获取新选定的标签页并关联的文本区域
|
// 获取新选定的标签页并关联的文本区域
|
||||||
TextArea textArea = (TextArea) newTab.getContent();
|
LineNumberTextArea textArea = (LineNumberTextArea) newTab.getContent();
|
||||||
|
|
||||||
// 更新状态标签
|
// 更新状态标签
|
||||||
controller.updateStatusLabel(textArea);
|
controller.updateStatusLabel(textArea);
|
||||||
|
|
||||||
// 监听文本光标位置的变化,更新状态标签
|
// 监听文本光标位置的变化,更新状态标签
|
||||||
textArea.caretPositionProperty().addListener((caretObservable, oldPosition, newPosition) -> controller.updateStatusLabel(textArea));
|
textArea.getMainTextArea().caretPositionProperty().addListener((caretObservable, oldPosition, newPosition) -> controller.updateStatusLabel(textArea));
|
||||||
|
|
||||||
// 更新编码标签
|
// 更新编码标签
|
||||||
controller.upDateEncodingLabel(textArea.getText());
|
controller.upDateEncodingLabel(textArea.getMainTextArea().getText());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUIWithNewTextArea(TextArea textArea) {
|
public void updateUIWithNewTextArea(LineNumberTextArea textArea) {
|
||||||
Tab tab = new Tab("新建文件 " + (++ViewManager.tabIndex));
|
Tab tab = new Tab("新建文件 " + (++ViewManager.tabIndex));
|
||||||
tab.setContent(textArea);
|
tab.setContent(textArea);
|
||||||
ViewManager.tabPane.getTabs().add(tab);
|
ViewManager.tabPane.getTabs().add(tab);
|
||||||
@ -252,9 +251,9 @@ public class Controller implements ControllerInterface {
|
|||||||
*
|
*
|
||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
*/
|
*/
|
||||||
private void configureTextArea(TextArea textArea) {
|
private void configureTextArea(LineNumberTextArea textArea) {
|
||||||
textArea.setWrapText(true);
|
textArea.getMainTextArea().setWrapText(true);
|
||||||
upDateEncodingLabel(textArea.getText());
|
upDateEncodingLabel(textArea.getMainTextArea().getText());
|
||||||
updateStatusLabel(textArea);
|
updateStatusLabel(textArea);
|
||||||
|
|
||||||
textArea.textProperty().addListener((observable, oldValue, newValue) -> updateStatusLabel(textArea));
|
textArea.textProperty().addListener((observable, oldValue, newValue) -> updateStatusLabel(textArea));
|
||||||
@ -267,8 +266,8 @@ public class Controller implements ControllerInterface {
|
|||||||
*
|
*
|
||||||
* @return 新的文本区域
|
* @return 新的文本区域
|
||||||
*/
|
*/
|
||||||
private TextArea createNewTextArea() {
|
private LineNumberTextArea createNewTextArea() {
|
||||||
TextArea textArea = new TextArea();
|
LineNumberTextArea textArea = new LineNumberTextArea();
|
||||||
textArea.setStyle(
|
textArea.setStyle(
|
||||||
"-fx-border-color:white;" +
|
"-fx-border-color:white;" +
|
||||||
"-fx-background-color:white"
|
"-fx-background-color:white"
|
||||||
@ -283,7 +282,7 @@ public class Controller implements ControllerInterface {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
* @return 新的标签页
|
* @return 新的标签页
|
||||||
*/
|
*/
|
||||||
private Tab createNewTab(String tabName, TextArea textArea) {
|
private Tab createNewTab(String tabName, LineNumberTextArea textArea) {
|
||||||
Tab tab = new Tab(tabName);
|
Tab tab = new Tab(tabName);
|
||||||
tab.setContent(textArea);
|
tab.setContent(textArea);
|
||||||
tab.setUserData(null);
|
tab.setUserData(null);
|
||||||
@ -297,12 +296,12 @@ public class Controller implements ControllerInterface {
|
|||||||
* @return 打开文件的任务
|
* @return 打开文件的任务
|
||||||
*/
|
*/
|
||||||
private Task<Void> createOpenFileTask(File file) {
|
private Task<Void> createOpenFileTask(File file) {
|
||||||
TextArea textArea = createNewTextArea();
|
LineNumberTextArea textArea = createNewTextArea();
|
||||||
return new Task<>() {
|
return new Task<>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void call() {
|
protected Void call() {
|
||||||
getText(file);
|
getText(file);
|
||||||
upDateEncodingLabel(textArea.getText());
|
upDateEncodingLabel(textArea.getMainTextArea().getText());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package org.jcnc.jnotepad.tool;
|
package org.jcnc.jnotepad.tool;
|
||||||
|
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -16,8 +17,8 @@ public class EncodingDetector {
|
|||||||
* @param textArea 文本区域
|
* @param textArea 文本区域
|
||||||
* @return 字符串表示的编码,如果检测失败则返回 "UNKNOWN"
|
* @return 字符串表示的编码,如果检测失败则返回 "UNKNOWN"
|
||||||
*/
|
*/
|
||||||
public static String detectEncoding(TextArea textArea) {
|
public static String detectEncoding(LineNumberTextArea textArea) {
|
||||||
String text = textArea.getText();
|
String text = textArea.getMainTextArea().getText();
|
||||||
|
|
||||||
return detectEncoding(text);
|
return detectEncoding(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package org.jcnc.jnotepad.tool;
|
package org.jcnc.jnotepad.tool;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 一个大转盘
|
* @author 一个大转盘
|
||||||
@ -18,7 +19,7 @@ public class FileUtil {
|
|||||||
String jsonStr = "";
|
String jsonStr = "";
|
||||||
try {
|
try {
|
||||||
FileReader fileReader = new FileReader(jsonFile);
|
FileReader fileReader = new FileReader(jsonFile);
|
||||||
Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
|
Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8);
|
||||||
int ch = 0;
|
int ch = 0;
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
while ((ch = reader.read()) != -1) {
|
while ((ch = reader.read()) != -1) {
|
||||||
|
|||||||
70
src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
Normal file
70
src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package org.jcnc.jnotepad.ui;
|
||||||
|
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class LineNumberTextArea extends BorderPane {
|
||||||
|
|
||||||
|
|
||||||
|
private final TextArea mainTextArea;
|
||||||
|
private final TextArea lineNumberArea;
|
||||||
|
|
||||||
|
public LineNumberTextArea() {
|
||||||
|
mainTextArea = new TextArea();
|
||||||
|
lineNumberArea = new TextArea();
|
||||||
|
lineNumberArea.setEditable(false);
|
||||||
|
lineNumberArea.setMinWidth(55);
|
||||||
|
lineNumberArea.setMaxWidth(55);
|
||||||
|
// 设置显示滚动条样式类
|
||||||
|
/* lineNumberArea.getStyleClass().add("hide-scrollbars");
|
||||||
|
mainTextArea.getStyleClass().add("show-scrollbars"); */
|
||||||
|
|
||||||
|
mainTextArea.textProperty().addListener((observable, oldValue, newValue) -> updateLineNumberArea());
|
||||||
|
|
||||||
|
// 当主要文本区域的垂直滚动位置发生变化时,使行号文本区域的滚动位置保持一致
|
||||||
|
mainTextArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
lineNumberArea.setScrollTop(mainTextArea.getScrollTop());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 当行号文本区域的垂直滚动位置发生变化时,使主要文本区域的滚动位置保持一致
|
||||||
|
lineNumberArea.scrollTopProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
mainTextArea.setScrollTop(lineNumberArea.getScrollTop());
|
||||||
|
});
|
||||||
|
|
||||||
|
setCenter(mainTextArea);
|
||||||
|
setLeft(lineNumberArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty textProperty() {
|
||||||
|
return mainTextArea.textProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void updateLineNumberArea() {
|
||||||
|
// 保存当前的滚动位置
|
||||||
|
/*
|
||||||
|
更新行号文本区域的内容,根据主要文本区域的段落数生成行号。
|
||||||
|
*/
|
||||||
|
double mainTextAreaScrollTop = mainTextArea.getScrollTop();
|
||||||
|
double lineNumberAreaScrollTop = lineNumberArea.getScrollTop();
|
||||||
|
|
||||||
|
int numOfLines = mainTextArea.getParagraphs().size();
|
||||||
|
StringBuilder lineNumberText = new StringBuilder();
|
||||||
|
for (int i = 1; i <= numOfLines; i++) {
|
||||||
|
lineNumberText.append(i).append("\n");
|
||||||
|
}
|
||||||
|
lineNumberArea.setText(lineNumberText.toString());
|
||||||
|
|
||||||
|
// 恢复之前的滚动位置
|
||||||
|
mainTextArea.setScrollTop(mainTextAreaScrollTop);
|
||||||
|
lineNumberArea.setScrollTop(lineNumberAreaScrollTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextArea getMainTextArea() {
|
||||||
|
return mainTextArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,7 @@ package org.jcnc.jnotepad.view.init;
|
|||||||
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.Scene;
|
import org.jcnc.jnotepad.ui.LineNumberTextArea;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.input.KeyCode;
|
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
|
||||||
import javafx.scene.input.KeyCombination;
|
|
||||||
import org.jcnc.jnotepad.controller.manager.Controller;
|
import org.jcnc.jnotepad.controller.manager.Controller;
|
||||||
import org.jcnc.jnotepad.controller.manager.ShortcutKey;
|
import org.jcnc.jnotepad.controller.manager.ShortcutKey;
|
||||||
|
|
||||||
@ -21,13 +17,13 @@ public class View {
|
|||||||
|
|
||||||
public void initItem() {
|
public void initItem() {
|
||||||
// 初始化菜单项的事件处理器
|
// 初始化菜单项的事件处理器
|
||||||
EventHandler<ActionEvent> newFileEventHandler = new Controller().getNewFileEventHandler(new TextArea());
|
EventHandler<ActionEvent> newFileEventHandler = new Controller().getNewFileEventHandler(new LineNumberTextArea());
|
||||||
newItem.setOnAction(newFileEventHandler);
|
newItem.setOnAction(newFileEventHandler);
|
||||||
EventHandler<ActionEvent> openFileEventHandler = new Controller().getOpenFileEventHandler();
|
EventHandler<ActionEvent> openFileEventHandler = new Controller().getOpenFileEventHandler();
|
||||||
openItem.setOnAction(openFileEventHandler);
|
openItem.setOnAction(openFileEventHandler);
|
||||||
EventHandler<ActionEvent> saveAsFileEventHandler = new Controller().getSaveAsFileEventHandler();
|
EventHandler<ActionEvent> saveAsFileEventHandler = new Controller().getSaveAsFileEventHandler();
|
||||||
saveAsItem.setOnAction(saveAsFileEventHandler);
|
saveAsItem.setOnAction(saveAsFileEventHandler);
|
||||||
lineFeedItem.setOnAction(new Controller().getLineFeedEventHandler(new TextArea()));
|
lineFeedItem.setOnAction(new Controller().getLineFeedEventHandler(new LineNumberTextArea()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initTabPane() {
|
public void initTabPane() {
|
||||||
|
|||||||
@ -3,12 +3,12 @@ package org.jcnc.jnotepad.view.manager;
|
|||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.input.KeyCombination;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该类管理记事本应用程序的视图组件。
|
* 该类管理记事本应用程序的视图组件。
|
||||||
@ -30,6 +30,8 @@ public class ViewManager {
|
|||||||
// 主界面布局
|
// 主界面布局
|
||||||
public static BorderPane root; //主布局
|
public static BorderPane root; //主布局
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 多个标签页
|
// 多个标签页
|
||||||
public static TabPane tabPane; //标签页栏
|
public static TabPane tabPane; //标签页栏
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ public class ViewManager {
|
|||||||
* @return ViewManager的实例。
|
* @return ViewManager的实例。
|
||||||
*/
|
*/
|
||||||
public static ViewManager getInstance(Scene scene) {
|
public static ViewManager getInstance(Scene scene) {
|
||||||
|
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new ViewManager(scene);
|
instance = new ViewManager(scene);
|
||||||
}
|
}
|
||||||
@ -60,7 +63,11 @@ public class ViewManager {
|
|||||||
*/
|
*/
|
||||||
private ViewManager(Scene scene) {
|
private ViewManager(Scene scene) {
|
||||||
root = new BorderPane();
|
root = new BorderPane();
|
||||||
|
|
||||||
scene.setRoot(root);
|
scene.setRoot(root);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,5 +132,8 @@ public class ViewManager {
|
|||||||
BorderPane.setMargin(statusBox, new Insets(5, 10, 5, 10));
|
BorderPane.setMargin(statusBox, new Insets(5, 10, 5, 10));
|
||||||
|
|
||||||
scene.setRoot(root);
|
scene.setRoot(root);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/resources/styles.css
Normal file
11
src/main/resources/styles.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* 显示滚动条 */
|
||||||
|
.show-scrollbars .scroll-pane {
|
||||||
|
-fx-hbar-policy: as-needed;
|
||||||
|
-fx-vbar-policy: as-needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 不显示滚动条 */
|
||||||
|
.hide-scrollbars .scroll-pane {
|
||||||
|
-fx-hbar-policy: never;
|
||||||
|
-fx-vbar-policy: never;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user