JTextAreaに行カーソルを表示

編集者:Terai Atsuhiro
作成日:2006-01-30
更新日:2022-10-07 (金) 15:03:11

概要

JTextAreaのカーソルがある行全体にアンダーラインを引きます。

http://terai.xrea.jp/swing/linecursor/screenshot.png

サンプルコード

class LineCursorTextArea extends JTextArea {
 public LineCursorTextArea() {
   super();
   Caret caret = new DefaultCaret() {
     protected synchronized void damage(Rectangle r) {
       if(r!=null) {
         JTextComponent c = getComponent();
         x = 0;
         y = r.y;
         width  = c.getSize().width;
         height = r.height;
         repaint();
       }
     }
   };
   caret.setBlinkRate(getCaret().getBlinkRate());
   setCaret(caret);
 }
 protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2 = (Graphics2D)g;
   Insets i = getInsets();
   int y = g2.getFontMetrics().getHeight()*getLineAtCaret(this)+i.top;
   g2.setPaint(SystemColor.activeCaption);
   g2.drawLine(i.left, y-1, getSize().width-i.left-i.right, y-1);
 }
 public static int getLineAtCaret(JTextComponent component) {
   int caretPosition = component.getCaretPosition();
   Element root = component.getDocument().getDefaultRootElement();
   return root.getElementIndex(caretPosition)+1;
 }
}

解説

JTextArea#paintComponentメソッドをオーバーライドして、カーソルがある行にアンダーラインを引いています。

キャレットの移動に対応するため、DefaultCaret#damageメソッドを変更して、描画に使われる領域を描画し直しています。

参考リンク

コメント

  • JEditPaneではgetRowHeight()が使えないようなので、Java低速GUI Swing 3を参考にしてg2.getFontMetrics().getHeight()にしました。 -- terai