JTextAreaのキャレットを上書きモード対応にする

編集者:Terai Atsuhiro
作成日:2006-01-16
更新日:2022-09-30 (金) 15:14:20

概要

JTextAreaにキャレット上の文字を上書きする上書きモードを追加します。

Java Forums - JTextPane edit mode (insert or overwrite)???のソースコードを全角文字に対応するようにしています。

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

サンプルコード

// Paint a horizontal line the width of a column and 1 pixel high
class OvertypeCaret extends DefaultCaret {
  //The overtype caret will simply be a horizontal line
  //one pixel high (once we determine where to paint it)
  public void paint(Graphics g) {
    if(isVisible()) {
      try{
        JTextComponent component = getComponent();
        TextUI mapper = component.getUI();
        Rectangle r = mapper.modelToView(component, getDot());
        g.setColor(component.getCaretColor());
        int width = g.getFontMetrics().charWidth('w');
        //全角などに対応
        if(isOvertypeMode()) {
          int pos = getCaretPosition();
          if(pos<getDocument().getLength()) {
            if(getSelectedText()!=null) {
              width = 0;
            }else{
              String str = getText(pos, 1);
              width = g.getFontMetrics().stringWidth(str);
            }
          }
        } //ここまで追加
        int y = r.y + r.height - 2;
        g.drawLine(r.x, y, r.x + width - 2, y);
      }catch(BadLocationException e) {}
    }
  }
  // Damage must be overridden whenever the paint method is overridden
  // (The damaged area is the area the caret is painted in. We must
  // consider the area for the default caret and this caret)
  protected synchronized void damage(Rectangle r) {
    if(r != null) {
      JTextComponent c = getComponent();
      x = r.x;
      y = r.y;
      //width = c.getFontMetrics(c.getFont()).charWidth('w');
      //全角対応
      width = c.getFontMetrics(c.getFont()).charWidth('あ');
      height = r.height;
      repaint();
    }
  }
}

解説

上記のサンプルでは、上書きモード用のキャレットを作成して、Insertキーで切り替えるようになっています。

JTextArea#replaceSelectionメソッドをオーバーライドして、上書きモードの場合は次の文字までを選択して置き換える処理を追加しています。

参考リンク

コメント