• title: JTextPaneでキーワードのSyntaxHighlight tags: [JTextPane, StyledDocument, Element, Highlight] author: aterai pubdate: 2009-09-21T02:07:00+09:00 description: JTextPaneでキーワードのSyntax Highlightを行います。

概要

JTextPaneでキーワードのSyntax Highlightを行います。このサンプルは、SyntaxDocument.javaからキーワードのハイライト部分を抜き出して作成しています。

サンプルコード

//This code is taken from:
//http://www.discoverteenergy.com/Files/SyntaxDocument.java SyntaxDocument.java
class SimpleSyntaxDocument extends DefaultStyledDocument {
  private final Style normal; //MutableAttributeSet normal = new SimpleAttributeSet();
  private static final String OPERANDS = ".,";
  public SimpleSyntaxDocument() {
    super();
    Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
    normal = addStyle("normal", def);
    StyleConstants.setForeground(normal, Color.BLACK);
    StyleConstants.setForeground(addStyle("red", normal), Color.RED);
    StyleConstants.setForeground(addStyle("green", normal), Color.GREEN);
    StyleConstants.setForeground(addStyle("blue", normal), Color.BLUE);
  }
  @Override public void insertString(int offset, String str, AttributeSet a)
        throws BadLocationException {
    super.insertString(offset, str, a);
    processChangedLines(offset, str.length());
  }
  @Override public void remove(int offset, int length)
        throws BadLocationException {
    super.remove(offset, length);
    processChangedLines(offset, 0);
  }
  private void processChangedLines(int offset, int length)
        throws BadLocationException {
    Element root = getDefaultRootElement();
    String content = getText(0, getLength());
    int startLine = root.getElementIndex(offset);
    int endLine = root.getElementIndex(offset + length);
    for (int i = startLine; i <= endLine; i++) {
      applyHighlighting(content, i);
    }
  }
  private void applyHighlighting(String content, int line)
        throws BadLocationException {
    Element root = getDefaultRootElement();
    int startOffset = root.getElement(line).getStartOffset();
    int endOffset = root.getElement(line).getEndOffset() - 1;
    int lineLength = endOffset - startOffset;
    int contentLength = content.length();
    if (endOffset >= contentLength) {
      endOffset = contentLength - 1;
    }
    setCharacterAttributes(startOffset, lineLength, normal, true);
    checkForTokens(content, startOffset, endOffset);
  }
  private void checkForTokens(String content, int startOffset, int endOffset) {
    int index = startOffset;
    while (index <= endOffset) {
      while (isDelimiter(content.substring(index, index + 1))) {
        if (index < endOffset) {
          index++;
        } else {
          return;
        }
      }
      index = getOtherToken(content, index, endOffset);
    }
  }
  private int getOtherToken(String content, int startOffset, int endOffset) {
    int endOfToken = startOffset + 1;
    while (endOfToken <= endOffset) {
      if (isDelimiter(content.substring(endOfToken, endOfToken + 1))) {
        break;
      }
      endOfToken++;
    }
    String token = content.substring(startOffset, endOfToken);
    Style s = getStyle(token);
    if (s != null) {
      setCharacterAttributes(startOffset, endOfToken - startOffset, s, false);
    }
    return endOfToken + 1;
  }
  protected boolean isDelimiter(String character) {
    return Character.isWhitespace(character.charAt(0))
            || OPERANDS.indexOf(character) != -1;
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、red, green, blueといったキーワードを入力すると、その色で文字列をハイライトするようになっています。区切り文字は、空白、.(ドット)、,(カンマ)の3つです。

Javaのシンタックスハイライトを行うサンプルコード(SyntaxDocument.java)からキーワードのハイライト部分を抜き出して作成しています。

参考リンク

コメント