RSyntaxTextArea - Changing the Color Scheme
Back to Example Index
Download as Eclipse project
Back to RSyntaxTextArea Home


Description

What if you don't like the colors RSyntaxTextArea uses to highlight code by default? What if the default font isn't to your liking? What if you're crazy and like to use proportional fonts while programming?

Changing the color scheme (or fonts used) can be done either programmatically, or via loading an XML file conforming to the project's theme DTD. While this example will cover both methods, he latter is of course preferred, because it separates styling logic from code, and gives your users an easy way to configure the code editor in your application.

Care must be taken when using the API to change the syntax scheme, because in the default scheme, keywords are bold and comments are italicized - in other words, these token types use a different java.awt.Font than the default. This means when changing the font, you'll have to make more than a single method call.

RSyntaxTextArea includes some default themes. They aren't bundled in the actual jar file, but you're free to grab them from the source distribution or from Subversion, and either ship them with your application as-is, or modify them however you like.

Loading a Theme Via XML

Loading a theme for RSyntaxTextArea via XML is easy. Simply create an XML file that follows the theme DTD, and use the Theme class to load it and apply it to RSyntaxTextArea instances. The API to do so is simple:

  • Theme.load(InputStream in) - Load a theme from XML.
  • theme.apply(RSyntaxTextArea textArea) - Apply a theme to a text editor.
Use the sample theme provided with this demo, or any of the sample themes included in the project, as a guide to create your own themes.

Using the API

As with all JTextComponents, an RSyntaxTextArea's base font is accessed with getFont() and setFont(Font). This is the font that is used for a token type (i.e. keyword, variable) if no font is specified for that type. Similarly, the text area's foreground color (getForeground()/setForeground(Color) is used as the color for a token type if no foreground color is explicitly specified.

Token type-specific colors and fonts are specified in an RSyntaxTextArea's SyntaxScheme. You can grab an RSTA's SyntaxScheme via the getSyntaxScheme() and setSyntaxScheme(SyntaxScheme) methods. A SyntaxScheme contains several different Style objects, one per token type supported by RSTA. You reference a Style for a particular token type by using one of the integer constants defined in the TokenTypes class, such as Token.RESERVED_WORD or Token.COMMENT_EOL, and calling syntaxScheme.getStyle(tokenType).

A Style has public fields allowing you to change the following properties of a token type and how it is painted:

  • background - The background color to use. If this is null, the background for the token will not be painted.
  • font - The font to use for this token type. If this is null, the text area's default font (i.e. getFont()) will be used.
  • foreground - The foreground color to use. If this is null, the text area's foreground color (i.e. getForeground()) will be used.
  • underline - Whether this token type should be underlined.

Modifying these fields (and revalidating the text area via "textArea.revalidate(); textArea.repaint();") will cause the RSTA to take the changes at runtime.

The Example Source
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;

import org.fife.ui.rtextarea.*;
import org.fife.ui.rsyntaxtextarea.*;

/**
 * A simple example showing how to modify the fonts and colors used in an
 * RSyntaxTextArea. There are two methods to do this - via the Java API, and via
 * an XML file. The latter method is preferred since it's more modular, and
 * provides a way for your users to customize RSTA in your application.<p>
 * 
 * This example uses RSyntaxTextArea 2.0.1.<p>
 * 
 * Project Home: http://fifesoft.com/rsyntaxtextarea<br>
 * Downloads: https://sourceforge.net/projects/rsyntaxtextarea
 */
public class SyntaxSchemeDemo extends JFrame implements ActionListener {

   private static final long serialVersionUID = 1L;

   private RSyntaxTextArea textArea;

   private static final String text = "public class ExampleSource {\n\n"
         + "   // Check out the crazy modified styles!\n"
         + "   public static void main(String[] args) {\n"
         + "      System.out.println(\"Hello, world!\");\n" + "   }\n\n"
         + "}\n";

   public SyntaxSchemeDemo() {

      JPanel cp = new JPanel(new BorderLayout());

      textArea = new RSyntaxTextArea(20, 60);
      textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
      textArea.setCodeFoldingEnabled(true);
      textArea.setAntiAliasingEnabled(true);
      RTextScrollPane sp = new RTextScrollPane(textArea);
      cp.add(sp);

      textArea.setText(text);

      JMenuBar mb = new JMenuBar();
      JMenu menu = new JMenu("File");
      mb.add(menu);
      JMenuItem changeStyleProgrammaticallyItem = new JMenuItem(
            "Change Style Programmatically");
      changeStyleProgrammaticallyItem
            .setActionCommand("ChangeProgrammatically");
      changeStyleProgrammaticallyItem.addActionListener(this);
      menu.add(changeStyleProgrammaticallyItem);
      JMenuItem changeStyleViaThemesItem = new JMenuItem(
            "Change Style via Theme XML");
      changeStyleViaThemesItem.setActionCommand("ChangeViaThemes");
      changeStyleViaThemesItem.addActionListener(this);
      menu.add(changeStyleViaThemesItem);
      setJMenuBar(mb);

      setContentPane(cp);
      setTitle("Syntax Scheme Demo");
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);

   }

   /**
    * Listens for the selection of a menu item and performs an action
    * accordingly.
    */
   public void actionPerformed(ActionEvent e) {
      String command = e.getActionCommand();
      if ("ChangeProgrammatically".equals(command)) {
         changeStyleProgrammatically();
      } else if ("ChangeViaThemes".equals(command)) {
         changeStyleViaThemeXml();
      }
   }

   /**
    * Changes the styles used in the editor programmatically.
    */
   private void changeStyleProgrammatically() {

      // Set the font for all token types.
      setFont(textArea, new Font("Comic Sans MS", Font.PLAIN, 16));

      // Change a few things here and there.
      SyntaxScheme scheme = textArea.getSyntaxScheme();
      scheme.getStyle(Token.RESERVED_WORD).background = Color.pink;
      scheme.getStyle(Token.DATA_TYPE).foreground = Color.blue;
      scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).underline = true;
      scheme.getStyle(Token.COMMENT_EOL).font = new Font("Georgia",
            Font.ITALIC, 12);

      textArea.revalidate();

   }

   /**
    * Changes the styles used by the editor via an XML file specification. This
    * method is preferred because of its ease and modularity.
    */
   private void changeStyleViaThemeXml() {
      try {
         Theme theme = Theme.load(getClass().getResourceAsStream(
               "/eclipse_theme.xml"));
         theme.apply(textArea);
      } catch (IOException ioe) { // Never happens
         ioe.printStackTrace();
      }
   }

   /**
    * Set the font for all token types.
    * 
    * @param textArea The text area to modify.
    * @param font The font to use.
    */
   public static void setFont(RSyntaxTextArea textArea, Font font) {
      if (font != null) {
         SyntaxScheme ss = textArea.getSyntaxScheme();
         ss = (SyntaxScheme) ss.clone();
         for (int i = 0; i < ss.getStyleCount(); i++) {
            if (ss.getStyle(i) != null) {
               ss.getStyle(i).font = font;
            }
         }
         textArea.setSyntaxScheme(ss);
         textArea.setFont(font);
      }
   }

   public static void main(String[] args) {
      // Start all Swing applications on the EDT.
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new SyntaxSchemeDemo().setVisible(true);
         }
      });
   }

}

Save this file as SyntaxSchemeDemo.java.
Compiling the Example
For simplicity, we will just use javac on the command line to compile. Bring up a command prompt or shell, make sure javac is on your PATH, and run the following command:
Windows:  javac -cp <path-to-jar>\rsyntaxtextarea.jar SyntaxStyleDemo.java
Unix:     javac -cp <path-to-jar>/rsyntaxtextarea.jar SyntaxStyleDemo.java
where <path-to-jar> is the path to the rsyntaxtextarea.jar file. This should yield no errors or warnings, and on completion there should see a file named SyntaxStyleDemo.class in your current directory.
Running the Example
Running the example is just as simple as compiling it:
Windows:  java -cp <path-to-jar>\rsyntaxtextarea.jar;. SyntaxStyleDemo
Unix:     java -cp <path-to-jar>/rsyntaxtextarea.jar:. SyntaxStyleDemo

A window should pop up, containing a text editor. As you type, the text should be syntax highlighted as Java code. The default RSTA color scheme has been modified to reflect the changes in the source.