diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123c2b23e069e35ed634d687e17f731cc702..0000000000000000000000000000000000000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 106fade22c4fe3820fec6d28326ef2162989e064..0000000000000000000000000000000000000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/fileTemplates/code/JavaDoc Class.java b/.idea/fileTemplates/code/JavaDoc Class.java
deleted file mode 100644
index 8c770c86169568f8aaec3fd46acd79eea65db516..0000000000000000000000000000000000000000
--- a/.idea/fileTemplates/code/JavaDoc Class.java
+++ /dev/null
@@ -1,7 +0,0 @@
-#foreach($param in $RECORD_COMPONENTS)
- * @param $param
-#end
-#foreach($param in $TYPE_PARAMS)
- * @param <$param>
-#end
- * @author $USER
diff --git a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
index acb4a036a308512d511cb156b018667cad901a71..539932c4842393d88218fb8165bc7cf3d4c4cc22 100644
--- a/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
+++ b/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java
@@ -1,12 +1,11 @@
package org.jcnc.jnotepad.ui;
import javafx.beans.property.StringProperty;
+import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
-import org.jcnc.jnotepad.app.config.AppConfig;
import org.jcnc.jnotepad.controller.config.AppConfigController;
import org.jcnc.jnotepad.tool.LogUtil;
-import org.jcnc.jnotepad.ui.menu.JNotepadMenuBar;
import org.jcnc.jnotepad.ui.status.JNotepadStatusBox;
import org.jcnc.jnotepad.ui.tab.JNotepadTab;
import org.jcnc.jnotepad.ui.tab.JNotepadTabPane;
@@ -15,6 +14,7 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.List;
/**
* @author 许轲
@@ -26,17 +26,27 @@ public class LineNumberTextArea extends BorderPane {
private boolean isRelevance = false;
private final TextArea mainTextArea;
private final TextArea lineNumberArea;
+ private List paragraphs; // 缓存段落列表
+ private String fullLineNumberText; // 缓存完整行号文本
+ private boolean needToUpdateLineNumbers = false;
+ private static final int MIN_LINE_NUMBER_WIDTH = 30;
static final int[] SIZE_TABLE = {9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE};
- private static final int MIN_LINE_NUMBER_WIDTH = 30;
+ private final ScrollPane scrollPane;
+
+ private int cachedNumOfLines = 0;
+
public LineNumberTextArea() {
+
mainTextArea = new TextArea();
mainTextArea.setWrapText(AppConfigController.getInstance().getAutoLineConfig());
+ scrollPane = new ScrollPane(mainTextArea);
lineNumberArea = new TextArea();
lineNumberArea.setEditable(false);
+
lineNumberArea.setPrefWidth(MIN_LINE_NUMBER_WIDTH);
lineNumberArea.setMinWidth(MIN_LINE_NUMBER_WIDTH);
// 设定自定义样式
@@ -47,12 +57,36 @@ public class LineNumberTextArea extends BorderPane {
"-fx-background-color:white"
);
- initListeners();
+ scrollPane.setFitToWidth(true);
+ scrollPane.viewportBoundsProperty().addListener((observable, oldValue, newValue) -> {
+ int firstVisibleLine = calculateFirstVisibleLine();
+ int lastVisibleLine = calculateLastVisibleLine();
+ loadVisibleLines(firstVisibleLine, lastVisibleLine);
+
+ loadVisibleLineNumbers(firstVisibleLine, lastVisibleLine);
+
+
+ // 如果标记为需要更新行号,则执行更新行号的操作
+ if (needToUpdateLineNumbers) {
+ updateLineNumberArea();
+ needToUpdateLineNumbers = false; // 重置标记
+ }
+ });
+ initListeners();
+ paragraphs = mainTextArea.getParagraphs(); // 缓存段落列表
+ generateFullLineNumberText(); // 初始化缓存的行号文本
setCenter(mainTextArea);
setLeft(lineNumberArea);
+ }
-
+ private void generateFullLineNumberText() {
+ StringBuilder lineNumberText = new StringBuilder();
+ int numOfLines = paragraphs.size();
+ for (int i = 1; i <= numOfLines; i++) {
+ lineNumberText.append(i).append("\n");
+ }
+ fullLineNumberText = lineNumberText.toString();
}
private void initListeners() {
@@ -72,6 +106,9 @@ public class LineNumberTextArea extends BorderPane {
JNotepadStatusBox.getInstance().updateWordCountStatusLabel();
// 自动保存
save();
+
+ needToUpdateLineNumbers = true;
+
});
}
@@ -124,10 +161,6 @@ public class LineNumberTextArea extends BorderPane {
private void updateLineNumberArea() {
- // 保存当前的滚动位置
- /*
- 更新行号文本区域的内容,根据主要文本区域的段落数生成行号。
- */
double mainTextAreaScrollTop = mainTextArea.getScrollTop();
double lineNumberAreaScrollTop = lineNumberArea.getScrollTop();
@@ -138,14 +171,60 @@ public class LineNumberTextArea extends BorderPane {
}
lineNumberArea.setText(lineNumberText.toString());
- // 恢复之前的滚动位置
mainTextArea.setScrollTop(mainTextAreaScrollTop);
lineNumberArea.setScrollTop(lineNumberAreaScrollTop);
+
+ if (cachedNumOfLines != numOfLines) {
+ updateLineNumberWidth();
+ cachedNumOfLines = numOfLines;
+ }
+
+ }
+
+
+ private int calculateFirstVisibleLine() {
+ double scrollTop = scrollPane.getVvalue() * mainTextArea.getParagraphs().size();
+ return (int) Math.floor(scrollTop);
}
+ private int calculateLastVisibleLine() {
+ double scrollTop = scrollPane.getVvalue() * mainTextArea.getParagraphs().size();
+ double viewportHeight = scrollPane.getViewportBounds().getHeight();
+ int lastVisibleLine = (int) Math.floor(scrollTop + viewportHeight / mainTextArea.getHeight());
+ return Math.min(lastVisibleLine, mainTextArea.getParagraphs().size() - 1);
+ }
+
+
+ // 加载可见区域的数据到 mainTextArea
+ private void loadVisibleLines(int firstVisibleLine, int lastVisibleLine) {
+ StringBuilder visibleText = new StringBuilder();
+ String[] lines = mainTextArea.getText().split("\n");
+
+ for (int i = firstVisibleLine; i <= lastVisibleLine && i < lines.length; i++) {
+ visibleText.append(lines[i]);
+ if (i < lastVisibleLine && i < lines.length - 1) {
+ visibleText.append("\n");
+ }
+ }
+
+ mainTextArea.setText(visibleText.toString());
+ }
+
+ // 加载可见区域的行号到 lineNumberArea
+ private void loadVisibleLineNumbers(int firstVisibleLine, int lastVisibleLine) {
+ StringBuilder visibleLineNumbers = new StringBuilder();
+
+ String[] lineNumbers = fullLineNumberText.split("\n");
+ for (int i = firstVisibleLine; i <= lastVisibleLine; i++) {
+ visibleLineNumbers.append(lineNumbers[i]).append("\n");
+ }
+
+ lineNumberArea.setText(visibleLineNumbers.toString());
+ }
+
+
public TextArea getMainTextArea() {
return mainTextArea;
}
-}
-
+}
\ No newline at end of file