概要

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

サンプルコード

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メソッドを変更して、変更のあった領域を再描画
  • Highlighting Current Line のように、Highlighterを使用する方法もある

参考リンク

コメント

  • Caretの高さを使用するように変更しました。 -- aterai