JNotepad/src/main/java/org/jcnc/jnotepad/ui/LineNumberTextArea.java

84 lines
3.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.jcnc.jnotepad.ui;
import javafx.beans.property.StringProperty;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
/**
* @author 许轲
*/
public class LineNumberTextArea extends BorderPane {
private final TextArea mainTextArea;
private final TextArea lineNumberArea;
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;
public LineNumberTextArea() {
mainTextArea = new TextArea();
lineNumberArea = new TextArea();
lineNumberArea.setEditable(false);
lineNumberArea.setPrefWidth(MIN_LINE_NUMBER_WIDTH);
lineNumberArea.setMinWidth(MIN_LINE_NUMBER_WIDTH);
// 设定自定义样式
lineNumberArea.getStyleClass().add("text-line-number");
mainTextArea.getStyleClass().add("main-text-area");
lineNumberArea.textProperty().addListener((observable, oldValue, newValue) -> updateLineNumberWidth());
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);
}
private void updateLineNumberWidth() {
int numOfLines = mainTextArea.getParagraphs().size();
int count = 1;
for (int i = 0; i < SIZE_TABLE.length; i++) {
if (numOfLines <= SIZE_TABLE[i]) {
count = i + 1;
break;
}
}
// 单数字宽度10像素4为padding=左3+右1
int actualWidth = Math.max(count * 10 + 11, MIN_LINE_NUMBER_WIDTH);
if (actualWidth != lineNumberArea.getWidth()) {
lineNumberArea.setPrefWidth(actualWidth);
}
}
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 - 8);
}
public TextArea getMainTextArea() {
return mainTextArea;
}
}