JTextAreaに行番号を表示
Total: 22090
, Today: 1
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JTextArea
の行番号を表示するコンポーネントを作成し、これを対象となるJTextArea
と同じJScrollPane
のRowHeaderView
に設定します。
Screenshot
Advertisement
サンプルコード
class LineNumberView extends JComponent {
private static final int MARGIN = 5;
private final JTextArea textArea;
private final FontMetrics fontMetrics;
// private final int topInset;
private final int fontAscent;
private final int fontHeight;
private final int fontDescent;
private final int fontLeading;
public LineNumberView(JTextArea textArea) {
this.textArea = textArea;
Font font = textArea.getFont();
fontMetrics = getFontMetrics(font);
fontHeight = fontMetrics.getHeight();
fontAscent = fontMetrics.getAscent();
fontDescent = fontMetrics.getDescent();
fontLeading = fontMetrics.getLeading();
// topInset = textArea.getInsets().top;
textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override public void insertUpdate(DocumentEvent e) {
repaint();
}
@Override public void removeUpdate(DocumentEvent e) {
repaint();
}
@Override public void changedUpdate(DocumentEvent e) {
// repaint();
}
});
textArea.addComponentListener(new ComponentAdapter() {
@Override public void componentResized(ComponentEvent e) {
revalidate();
repaint();
}
});
Insets i = textArea.getInsets();
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(0, 0, 0, 1, Color.GRAY),
BorderFactory.createEmptyBorder(i.top, MARGIN, i.bottom, MARGIN - 1)));
setOpaque(true);
setBackground(Color.WHITE);
setFont(font);
}
private int getComponentWidth() {
Document doc = textArea.getDocument();
Element root = doc.getDefaultRootElement();
int lineCount = root.getElementIndex(doc.getLength());
int maxDigits = Math.max(3, String.valueOf(lineCount).length());
Insets i = getInsets();
return maxDigits * fontMetrics.stringWidth("0") + i.left + i.right;
// return 48;
}
private int getLineAtPoint(int y) {
Element root = textArea.getDocument().getDefaultRootElement();
int pos = textArea.viewToModel(new Point(0, y));
return root.getElementIndex(pos);
}
@Override public Dimension getPreferredSize() {
return new Dimension(getComponentWidth(), textArea.getHeight());
}
@Override protected void paintComponent(Graphics g) {
g.setColor(getBackground());
Rectangle clip = g.getClipBounds();
g.fillRect(clip.x, clip.y, clip.width, clip.height);
g.setColor(getForeground());
int base = clip.y;
int start = getLineAtPoint(base);
int end = getLineAtPoint(base + clip.height);
int y = start * fontHeight;
int rmg = getInsets().right;
for (int i = start; i <= end; i++) {
String text = String.valueOf(i + 1);
int x = getComponentWidth() - rmg - fontMetrics.stringWidth(text);
y += fontAscent;
g.drawString(text, x, y);
y += fontDescent + fontLeading;
}
}
}
View in GitHub: Java, Kotlin解説
Swing (Archive) - Advice for editor gutter implementation...を参考にして、JTextArea
に行番号を表示しています。
上記のサンプルで使用するJTextArea
は、使用するフォントや余白などは変更不可で各行の高さはすべて同一で不変と想定しています。
JTextPane
での行番号表示- 折り返しても表示は前の行を継続
- Swing - Line Number in JTextPaneの
LineNumberView
(@author Alan Moore) JTextPane
で各行の高さが異なる場合の行番号表示サンプル
- Swing - Line Number in JTextPaneの
- 折り返された行にも行番号を表示
- Swing - line number in jtextpane
EditorKit
を使って行番号を表示し、JTextPane
で折り返された行でも表示に従って行番号を割り当てる
- 折り返しても表示は前の行を継続
参考リンク
- Swing (Archive) - Advice for editor gutter implementation...
- Swing - Line Number in JTextPane
- Swing - line number in jtextpane