JTextArea 的行号和调整 JTextArea 文本大小的问题
Problem with line number of JTextArea and resize JTextArea texts
此代码计算 JTextArea 的每一行并添加行数
左 JTextPane
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.MatteBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class LineNumber extends JFrame implements DocumentListener {
private static final long serialVersionUID = -1093726028044203117L;
private JScrollPane scroll;
private JTextArea textArea;
private TextPane lineArea;
public static void main(String[] args) {
new LineNumber().setVisible(true);
}
public LineNumber() {
super("Line Numbers");
setSize(500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUI();
}
private void setUI() {
textArea = new JTextArea();
textArea.getDocument().addDocumentListener(this);
lineArea = new TextPane(0, 3);
lineArea.setText(getLine());
lineArea.setEditable(false);
lineArea.setFocusable(false);
lineArea.setBorder(new MatteBorder(0, 0, 0, 1, new Color(248, 248, 248)));
lineArea.setBackground(new Color(255, 255, 255));
lineArea.setForeground(Color.GRAY);
scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setViewportView(textArea);
scroll.setRowHeaderView(lineArea);
getContentPane().add(scroll, BorderLayout.CENTER);
}
public void changedUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
public void insertUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
public void removeUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
private String getLine() {
int caretPos = 0;
String lines = "";
caretPos = textArea.getDocument().getLength();
Element root = textArea.getDocument().getDefaultRootElement();
for (int i = 1; i < root.getElementIndex(caretPos) + 2; i++)
lines += String.format("%s \n", i);
return lines;
}
private int getLength() {
int caretPos = 0;
int length = 0;
caretPos = textArea.getDocument().getLength();
Element root = textArea.getDocument().getDefaultRootElement();
int max = 0;
for (int i = 1; i < root.getElementIndex(caretPos) + 2; i++)
length = String.valueOf(Math.max(i, max)).length();
return length;
}
private void setRightAlign() {
StyledDocument doc = lineArea.getStyledDocument();
SimpleAttributeSet right = new SimpleAttributeSet();
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
doc.setParagraphAttributes(0, doc.getLength(), right, false);
}
}
如果 lineArea 和 textArea 使用相同大小的相同字体
程序运行良好,但如果更改或调整 textArea
的字体大小
它不适用于不同的字体大小
并且距离实际结束线太短
更改文本区域字体或字体大小后:
调整行区域和文本区域大小后不平衡
我不想改变文本区域字体的大小
只有带有行号
的平衡文本区域
我不知道 TextPane
class 是什么,因为那不是标准的 JDK 组件。
如果它是 JTextArea,那么也许您可以将 getRowHeight(..)
方法重写为 return 基于主 JTextArea 字体的高度。
如果它是 JTextPane,那么也许您可以使用 StyleConstants.setSpaceBelow(...)
在每行之后添加额外的 space。因此,您需要获取用于计算每种字体高度的两种字体的字体指标。那么区别就是您用于 space 下面的方法。
另一种选择是使用我在上一个问题中提供的 class。它已经支持此功能。
此代码计算 JTextArea 的每一行并添加行数
左 JTextPane
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.MatteBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class LineNumber extends JFrame implements DocumentListener {
private static final long serialVersionUID = -1093726028044203117L;
private JScrollPane scroll;
private JTextArea textArea;
private TextPane lineArea;
public static void main(String[] args) {
new LineNumber().setVisible(true);
}
public LineNumber() {
super("Line Numbers");
setSize(500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUI();
}
private void setUI() {
textArea = new JTextArea();
textArea.getDocument().addDocumentListener(this);
lineArea = new TextPane(0, 3);
lineArea.setText(getLine());
lineArea.setEditable(false);
lineArea.setFocusable(false);
lineArea.setBorder(new MatteBorder(0, 0, 0, 1, new Color(248, 248, 248)));
lineArea.setBackground(new Color(255, 255, 255));
lineArea.setForeground(Color.GRAY);
scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setViewportView(textArea);
scroll.setRowHeaderView(lineArea);
getContentPane().add(scroll, BorderLayout.CENTER);
}
public void changedUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
public void insertUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
public void removeUpdate(DocumentEvent event) {
lineArea.setText(getLine());
}
private String getLine() {
int caretPos = 0;
String lines = "";
caretPos = textArea.getDocument().getLength();
Element root = textArea.getDocument().getDefaultRootElement();
for (int i = 1; i < root.getElementIndex(caretPos) + 2; i++)
lines += String.format("%s \n", i);
return lines;
}
private int getLength() {
int caretPos = 0;
int length = 0;
caretPos = textArea.getDocument().getLength();
Element root = textArea.getDocument().getDefaultRootElement();
int max = 0;
for (int i = 1; i < root.getElementIndex(caretPos) + 2; i++)
length = String.valueOf(Math.max(i, max)).length();
return length;
}
private void setRightAlign() {
StyledDocument doc = lineArea.getStyledDocument();
SimpleAttributeSet right = new SimpleAttributeSet();
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
doc.setParagraphAttributes(0, doc.getLength(), right, false);
}
}
如果 lineArea 和 textArea 使用相同大小的相同字体
程序运行良好,但如果更改或调整 textArea
的字体大小
它不适用于不同的字体大小
并且距离实际结束线太短
更改文本区域字体或字体大小后:
调整行区域和文本区域大小后不平衡
我不想改变文本区域字体的大小
只有带有行号
我不知道 TextPane
class 是什么,因为那不是标准的 JDK 组件。
如果它是 JTextArea,那么也许您可以将 getRowHeight(..)
方法重写为 return 基于主 JTextArea 字体的高度。
如果它是 JTextPane,那么也许您可以使用 StyleConstants.setSpaceBelow(...)
在每行之后添加额外的 space。因此,您需要获取用于计算每种字体高度的两种字体的字体指标。那么区别就是您用于 space 下面的方法。
另一种选择是使用我在上一个问题中提供的 class。它已经支持此功能。