• category: swing folder: WhitespaceMark title: JTextPaneで全角スペースやタブを可視化 tags: [JTextPane, LabelView] author: aterai pubdate: 2007-09-17T14:41:19+09:00 description: JTextPaneに表示した文字列中の全角スペースやタブを可視化します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTWpb1ogMI/AAAAAAAAApk/3IWJ2qvvECo/s800/WhitespaceMark.png

概要

JTextPaneに表示した文字列中の全角スペースやタブを可視化します。

サンプルコード

class WhitespaceLabelView extends LabelView {
  private static final String IDEOGRAPHIC_SPACE = "\u3000";
  private static final Color MARK_COLOR = new Color(130, 140, 120);
  private static final BasicStroke DASHED = new BasicStroke(
      1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, new float[] {1f}, 0f);
  protected WhitespaceLabelView(Element elem) {
    super(elem);
  }
  @Override public void paint(Graphics g, Shape a) {
    super.paint(g, a);
    Graphics2D g2 = (Graphics2D) g.create();
    Rectangle alloc = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
    FontMetrics fontMetrics = g.getFontMetrics();
    int spaceWidth = fontMetrics.stringWidth(IDEOGRAPHIC_SPACE);
    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 (IDEOGRAPHIC_SPACE.equals(s)) {
        g2.setStroke(DASHED);
        g2.setPaint(MARK_COLOR);
        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.setPaint(MARK_COLOR);
        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.dispose();
  }
}
View in GitHub: Java, Kotlin

解説

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

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

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

参考リンク

コメント