• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextPaneで全角スペースやタブを可視化
#navi(../)
#tags(JTextPane, LabelView)
RIGHT:Posted by &author(aterai); at 2007-09-17
* JTextPaneで全角スペースやタブを可視化 [#vbe52881]
`JTextPane`に表示した文字列中の全角スペースやタブを可視化します。

- &jnlp;
- &jar;
- &zip;

#ref(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTWpb1ogMI/AAAAAAAAApk/3IWJ2qvvECo/s800/WhitespaceMark.png)

** サンプルコード [#f57a2d79]
#code(link){{
class WhitespaceLabelView extends LabelView {
  private static final Color pc = new Color(130, 140, 120);
  private static final BasicStroke dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
       BasicStroke.JOIN_MITER, 10.0f, new float[] {1.0f}, 0.0f);
  public WhitespaceLabelView(Element elem) {
    super(elem);
  }
  public void paint(Graphics g, Shape a) {
  @Override public void paint(Graphics g, Shape a) {
    super.paint(g,a);
    Graphics2D g2 = (Graphics2D)g;
    Stroke stroke = g2.getStroke();
    Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
    FontMetrics fontMetrics = g.getFontMetrics();
    int spaceWidth = fontMetrics.stringWidth(" ");
    int sumOfTabs  = 0;
    String text = getText(getStartOffset(),getEndOffset()).toString();
    for(int i=0;i<text.length();i++) {
      String s = text.substring(i,i+1);
      int previousStringWidth = fontMetrics.stringWidth(text.substring(0,i)) + sumOfTabs;
      int sx = alloc.x+previousStringWidth;
      int sy = alloc.y+alloc.height-fontMetrics.getDescent();
      if(" ".equals(s)) {
        g2.setStroke(dashed);
        g2.setPaint(pc);
        g2.drawLine(sx+1, sy-1, sx+spaceWidth-2, sy-1);
        g2.drawLine(sx+2,   sy, sx+spaceWidth-2, sy);
      }else if("\t".equals(s)) {
        int tabWidth = (int)getTabExpander().nextTabStop((float)sx, i)-sx;
        g2.setColor(pc);
        g2.drawLine(sx+2, sy-0, sx+2+2, sy-0);
        g2.drawLine(sx+2, sy-1, sx+2+1, sy-1);
        g2.drawLine(sx+2, sy-2, sx+2+0, sy-2);
        g2.setStroke(dashed);
        g2.drawLine(sx+2, sy, sx+tabWidth-2, sy);
        sumOfTabs+=tabWidth;
      }
      g2.setStroke(stroke);
    }
  }
}
}}

** 解説 [#wfb05641]
上記のサンプルでは、`LabelView`を継承し、`LabelView#paint`メソッドをオーバーライドして全角スペースやタブの場合だけ、それぞれの図形を描画しています。

- 注: タブの図形は、`xyzzy`風だが、ドットの数は面倒なので適当

この`LabelView`を使用する`EditorKit(ViewFactory)`の作成は、[[JEditorPaneで改行を表示>Swing/ParagraphMark]]と同様になっています。

** 参考リンク [#ja0a61a4]
- [https://forums.oracle.com/thread/1374478 Swing - JTextPane View Problem]
- [http://java.sun.com/products/jlf/ed1/dg/higo.htm Design Guidelines: Text Components]
- [http://www.javafaq.nu/java-book-30.html Swing Chapter 19. (Advanced topics) Inside Text Components. Easy for reading, Click here!]
- [[JEditorPaneで改行を表示>Swing/ParagraphMark]]
- [[JTextPaneでタブサイズを設定>Swing/TabSize]]

** コメント [#j5c6e373]
#comment