Substance look and feel - themes overview

At runtime, a control (such as button, scroll bar or slider thumb) can be in three different visual states:

The following screenshot illustrates three buttons in three different visual states:

A Substance theme is a set of information that allows consistent painting of controls in different visual states. The org.jvnet.substance.theme.SubstanceTheme is the base class for all Substance themes.

A theme uses the underlying color scheme to capture the relevant color information. All color schemes implement the org.jvnet.substance.color.ColorScheme interface.

Substance themes can be roughly grouped into three categories:

Substance allows changing theme at runtime, providing a function that retrieves information on all available themes. In addition, Substance uses plugin mechanism to automatically discover additional themes at runtime.

Color schemes

A color scheme must implement org.jvnet.substance.color.ColorScheme interface. This interface defines the following seven functions:

These functions (except the first) are used at runtime to paint the background of UI components (depending on their visual state). Note that the colors are used in gradients and interpolations, so there is no one-to-one mapping chart that defines all the uses of a certain color.

It is recommended to order the colors by brightness, making the getUltraDarkColor() return the least bright color and getUltraLightColor() return the brightest color.

Themes

A theme must extend org.jvnet.substance.theme.SubstanceTheme base class (which is a MetalTheme). The single constructor of SubstanceTheme gets the following parameters: There are three options for using themes in Substance look and feel. The available core themes are located in org.jvnet.substance.theme package (see color scheme chart). The AQUA theme is the default. If you do not use the below options, the AQUA theme will be used. In order to change the current theme, you can
  1. Call SubstanceLookAndFeel.setCurrentTheme() with one of the above themes, for example SubstanceLookAndFeel.setCurrentTheme(new SubstanceBrownTheme())
  2. Call SubstanceLookAndFeel.setCurrentTheme() with the fully qualified name of one of the above themes, for example SubstanceLookAndFeel.setCurrentTheme("org.jvnet.substance.theme.SubstanceBrownTheme")
  3. Set substancelaf.theme parameter of the VM, for example -Dsubstancelaf.theme=org.jvnet.substance.theme.SubstanceBrownTheme
If you use one of the first two options after your application has started, don't forget to call:
UIManager.setLookAndFeel(new SubstanceLookAndFeel());
SwingUtilities.updateComponentTreeUI(...);
The first call is mandatory in versions 2.2, 2.3 and 3.0. The second call should be performed on all open frames (you can use Frame.getFrames() function).

Providing custom themes

Substance provides two ways for specifying custom themes.

The first option is by using the SubstanceTheme constructor as described above. The newly created SubstanceTheme object can then be used as a parameter to SubstanceLookAndFeel.setCurrentTheme function.

The second option is to use Substance plugin mechanism that discovers the additional themes at runtime. This approach is taken by both Substance itself and by the Substance theme pack subproject. As with all Substance plugins, you must pack an additional XML configuration file in one of your runtime jarfiles. The name of this file must be substance-plugin.xml and it must comply with the following syntax:
<laf-plugin>
   additional optional tags
   <theme-plugin-class>...</theme-plugin-class>
   additional optional tags
</laf-plugin>
The contents of theme-plugin-class tag must be the fully-qualified class name of a class that implements the SubstanceThemePlugin interface. This interface specifies a single function:
  public Set<ThemeInfo> getThemes();
The ThemeInfo class contains information on a single (base or custom) theme. Its single constructor gets the following three parameters: In addition, this class provides the setDefault function that can mark a theme as default.

In case you provide a class that implements the SubstanceThemePlugin interface (the second option), you can use the setDefault function of a ThemeInfo class to specify your own default theme. In case you specify none, AQUA will be taken.

Note that using the second option you may override the color themes supplied with Substance base package (by specifying the same display name). This behaviour, however, is not guaranteed to be consistent across various VMs and class loaders, since the theme plugins are processed in random order.

Retrieving information on themes

All the functions are in SubstanceLookAndFeel