How to customize the font inside a JTextPane component (Java Swing) – Highlight Java Keywords inside a JTextPane

If you need to change the font, color, etc. of the text inside a JTextPane component you will basically need to follow the next steps:

private JTextPane textEditor;
private StyledDocument textEditorDoc;
...
textEditor = new JTextPane();
textEditorDoc = textEditor.getStyledDocument();
textEditor.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");
...
StyleContext sc = StyleContext.getDefaultStyleContext();
// We will make the text blue (Color.blue)
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,StyleConstants.Foreground, Color.blue);
...
textEditorDoc.setCharacterAttributes(offset, length, aset, true);

Where offset represents the starting position where you are going to insert the color and length represents the length (starting from the offset) that you wish color.

In the following scenario I will show you how to “highlight” the java keywords in a given text. To identify the keywords we will use Regular Expressions.

Capture

First we will have to a default color for text highlighting and blue is my color of choice.

public static final Color DEFAULT_KEYWORD_COLOR = Color.blue;

The second step will be to define a regular expression that contains all the Java Keywords. For simplicity I chose to use static variables “attached” to my GUI class:
       
       public static final String[] JAVA_KEYWORDS = new String[] { "abstract",
      "assert", "boolean", "break", "byte", "case", "catch", "char",
      "class", "const", "continue", "default", "do", "double", "else",
      "enum", "extends", "final", "finally", "float", "for", "goto",
      "if", "implements", "import", "instanceof", "int", "long",
      "native", "new", "package", "private", "protected", "public",
      "return", "short", "static", "strictfp", "super", "switch",
      "synchronized", "this", "throw", "throws", "transient", "try",
      "void", "volatile", "while", "false", "null", "true" };
  public static String JAVA_KEYWORDS_REGEX;

  static {
    StringBuilder buff = new StringBuilder("");
    buff.append("(");
    for (String keyword : JAVA_KEYWORDS) {
      buff.append("\\b").append(keyword).append("\\b").append("|");
    }
    buff.deleteCharAt(buff.length() - 1);
    buff.append(")");
    JAVA_KEYWORDS_REGEX = buff.toString();
  }

The resulting string (JAVA_KEYWORDS_REGEX) will look like this (something that it’s not advisable to write by hand):

(\babstract\b|\bassert\b|\bboolean\b|\bbreak\b|\bbyte\b|\bcase\b|\bcatch\b|\bchar\b|\bclass\b|\bconst\b|\bcontinue\b|\bdefault\b|\bdo\b|\bdouble\b|\belse\b|\benum\b|\bextends\b|\bfinal\b|\bfinally\b|\bfloat\b|\bfor\b|\bgoto\b|\bif\b|\bimplements\b|\bimport\b|\binstanceof\b|\bint\b|\blong\b|\bnative\b|\bnew\b|\bpackage\b|\bprivate\b|\bprotected\b|\bpublic\b|\breturn\b|\bshort\b|\bstatic\b|\bstrictfp\b|\bsuper\b|\bswitch\b|\bsynchronized\b|\bthis\b|\bthrow\b|\bthrows\b|\btransient\b|\btry\b|\bvoid\b|\bvolatile\b|\bwhile\b|\bfalse\b|\bnull\b|\btrue\b)"

For designing the GUI I’ve used an Eclipse plugin called WindowBuilder, and my component hierarchy looks like this:

Capture2

The functions that are modifying the text are:

  public void updateTextColor(int offset, int length, Color c) {
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
        StyleConstants.Foreground, c);
    textEditorDoc.setCharacterAttributes(offset, length, aset, true);
  }

  public void clearTextColors() {
    updateTextColor(0, textEditor.getText().length(), Color.BLACK);
  }

  public void updateTextColor(int offset, int length) {
    updateTextColor(offset, length, DEFAULT_KEYWORD_COLOR);
  }

And the action behind the button is: