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

編集者:Terai Atsuhiro~

作成日:2006-01-16
更新日:2022-09-30 (金) 15:14:20
  • category: swing folder: OverTypeMode title: JTextAreaのキャレットを上書きモード対応にする tags: [JTextArea, Caret] author: aterai pubdate: 2006-01-16T15:56:38+09:00 description: JTextAreaにキャレット上の文字を上書きする上書きモードを追加します。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTQtaGO6gI/AAAAAAAAAgA/XPqHe-c_DUo/s800/OverTypeMode.png

概要

JTextAreaにキャレット上の文字を上書きする上書きモードを追加します。JTextPane edit mode (insert or overwrite)???のソースコードを変更して全角文字対応にしています。

概要

JTextAreaにキャレット上の文字を上書きする上書きモードを追加します。
Java Forums - JTextPane edit mode (insert or overwrite)???のソースコードを変更して全角文字対応にしています。

サンプルコード

#spanend
#spanadd
// Paint a horizontal line the width of a column and 1 pixel high
#spanend
#spanadd
class OvertypeCaret extends DefaultCaret {
#spanend
  // The overtype caret will simply be a horizontal line
  // one pixel high (once we determine where to paint it)
  @Override 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) {}
    }
  }

#spandel
http://terai.xrea.jp/swing/overtypemode/screenshot.png
#spanend
#spandel
**サンプルコード [#hf545cfe]
#spanend
 // 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();
     }
   }
 }
  // 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)
  @Override 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();
    }
  }
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、DefaultCaret#paint(...)メソッドなどをオーバーライドした上書きモード用のCaretを作成しInsertキーでこのCaretを表示するモードに切り替えることができます。

解説

上記のサンプルでは、上書きモード用のキャレットを作成して、Insertキーで切り替えるようになっています。
  • 上書きモード自体の動作はJTextArea#replaceSelection(...)メソッドをオーバーライドすることで実現
    • ここでキー入力を検知したとき次の文字までを選択置換する処理を実行
JTextArea#replaceSelectionメソッドをオーバーライドして、上書きモードの場合は次の文字までを選択して置き換える処理を追加しています。

参考リンク

参考リンク

コメント

  • 改行のあたりの処理がまだいい加減になっています。 -- terai
  • テキストを選択状態にしてInsertキーを押すと、反転されたままになるようなので修正。 -- terai

コメント