概要

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

スクリーンショット

LineCursor.png

サンプルコード

class LineCursorTextArea extends JTextArea {
  private static final Color LINE_COLOR = Color.BLUE;
  private DefaultCaret caret;

  @Override public void updateUI() {
    super.updateUI();
    caret = new DefaultCaret() {
      @Override protected synchronized void damage(Rectangle r) {
        if (r != null) {
          JTextComponent c = getComponent();
          x = 0;
          y = r.y;
          width  = c.getSize().width;
          height = r.height;
          c.repaint();
        }
      }
    };
    caret.setBlinkRate(getCaret().getBlinkRate());
    setCaret(caret);
  }

  @Override protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g.create();
    Insets i = getInsets();
    int y = caret.y + caret.height - 1;
    g2.setPaint(LINE_COLOR);
    g2.drawLine(i.left, y, getSize().width - i.left - i.right, y);
    g2.dispose();
  }

  // public static int getLineAtCaret(JTextComponent component) {
  //   int caretPosition = component.getCaretPosition();
  //   Element root = component.getDocument().getDefaultRootElement();
  //   return root.getElementIndex(caretPosition) + 1;
  // }
}
view all

解説

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

  • Caretの移動に対応するため、DefaultCaret#damage(Rectangle)メソッドをオーバーライドして変更された領域を再描画
  • Highlighting Current Line のようにHighlighterを使用する方法もある

参考リンク

コメント