• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextAreaに行番号を表示
#navi(../)
*JTextAreaに行番号を表示 [#l3a54503]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2006-02-20~
更新日:&lastmod;

#contents

**概要 [#r4312460]
JTextAreaに行番号を表示します。

http://terai.xrea.jp/swing/linenumber/screenshot.png
#screenshot

**サンプルコード [#caf6edeb]
 class LineNumberView extends JComponent {
   private static final int MARGIN = 5;
   private final JTextArea text;
   private final FontMetrics fontMetrics;
   private final int topInset;
   private final int fontAscent;
   private final int fontHeight;
   public LineNumberView(JTextArea textArea) {
     text = textArea;
     fontMetrics = getFontMetrics(text.getFont());
     fontHeight  = fontMetrics.getHeight();
     fontAscent  = fontMetrics.getAscent();
     topInset    = text.getInsets().top;
     text.getDocument().addDocumentListener(new DocumentListener() {
       public void insertUpdate(DocumentEvent e) {
         repaint();
       }
       public void removeUpdate(DocumentEvent e) {
         repaint();
       }
       public void changedUpdate(DocumentEvent e) {}
     });
     text.addComponentListener(new ComponentAdapter() {
       public void componentResized(ComponentEvent e) {
         revalidate();
         repaint();
       }
     });
     setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.GRAY));
   }
   private int getComponentWidth() {
     Document doc  = text.getDocument();
     Element root  = doc.getDefaultRootElement();
     int lineCount = root.getElementIndex(doc.getLength());
     int maxDigits = Math.max(3, String.valueOf(lineCount).length());
     return maxDigits*fontMetrics.stringWidth("0")+MARGIN*2;
   }
   private int getLineAtPoint(int y) {
     Element root = text.getDocument().getDefaultRootElement();
     int pos = text.viewToModel(new Point(0, y));
     return root.getElementIndex(pos);
   }
   public Dimension getPreferredSize() {
     return new Dimension(getComponentWidth(), text.getHeight());
   }
   public void paintComponent(Graphics g) {
     Rectangle clip = g.getClipBounds();
     g.setColor(getBackground());
     g.fillRect(clip.x, clip.y, clip.width, clip.height);
     g.setColor(getForeground());
     int base  = clip.y - topInset;
     int start = getLineAtPoint(base);
     int end   = getLineAtPoint(base+clip.height);
     int y = topInset-fontHeight+fontAscent+start*fontHeight;
     for(int i=start;i<=end;i++) {
       String text = String.valueOf(i+1);
       int x = getComponentWidth()-MARGIN-fontMetrics.stringWidth(text);
       y = y + fontHeight;
       g.drawString(text, x, y);
     }
   }
 }

-[[サンプルを起動>http://terai.xrea.jp/swing/linenumber/sample.jnlp]]
-[[jarファイル>http://terai.xrea.jp/swing/linenumber/sample.jar]]
-[[ソース>http://terai.xrea.jp/swing/linenumber/src.zip]]
-&jnlp;
-&jar;
-&zip;

**解説 [#mcee74d1]
[[Java Forums - Line Number in JTextPane>http://forum.java.sun.com/thread.jspa?threadID=585673]]を参考にして、JTextAreaに行番号を表示しています。

上記のサンプルで使用するJTextAreaは、行の高さはすべて一定で、フォントや余白などは変更されないものと想定しています。

**参考リンク [#qeacb6f7]
-[[Java Forums - Line Number in JTextPane>http://forum.java.sun.com/thread.jspa?threadID=585673]]
-[[Java Forums - line number in jtextpane>http://forum.java.sun.com/thread.jspa?threadID=422802]]

**コメント [#eb1fb225]
#comment