Substance look and feel - themes
Overview
Substance uses two different concepts for coloring controls, color scheme and
theme. The basic runtime archive comes with seventeen color themes (grouped in three
categories, bright, cold and dark). In addition, there are additional metal-gray
themes for disabled and inactive controls. Most controls (buttons, check boxes, scroll bars etc.)
use different themes based on the current state.
For example, a button uses three different themes: color, metallic and gray. When a button is
disabled, it uses gray theme. When a button is active (pressed, rolled-over or default) it uses
color theme. Otherwise it uses metallic theme. There are two pairs of metal-gray themes, one for
dark themes and one for bright and cold themes.
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:
- Color getForegroundColor() - retrieves color for foreground
elements (such as text of a button).
- Color getUltraLightColor() - retrieves ultra-light color.
- Color getExtraLightColor() - retrieves extra-light color.
- Color getLightColor() - retrieves light color.
- Color getMidColor() - retrieves medium color.
- Color getDarkColor() - retrieves dark color.
- Color getUltraDarkColor() - retrieves ultra-dark color.
These functions (except the first) are used at runtime to paint the corresponding
components. 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.
Substance provides the following eighteen color schemes:
- Bright themes : Aqua, Barby Pink,
Bottle Green,
Brown, Light Aqua,
Lime Green, Orange,
Purple, Raspberry,
Sun Glare and Sunset
- Cold themes : Olive, Sepia,
Steel Blue and Terracotta
- Dark themes : Ebony, Dark Violet
and Charcoal
In addition, there are additional "system" color schemes that are used for painting
inactive and disabled controls.
Mixed color schemes
Mixed color scheme uses two simple color schemes, main and secondary. Here are examples of
mixed themes:
- Aqua & Light Aqua
- Barby Pink & Raspberry
- Bottle Green & Lime Green
- Brown & Sun Glare
- Sunset & Orange
In order to globally enable mixed themes in your application you can use the following API
in SubstanceLookAndFeel class:
/**
* Globally registers a new <code>mixed</code> theme.
*
* @param mixedTheme
* A <code>mixed</code> theme to register.
*/
public static void addMixedTheme(SubstanceMixBiTheme mixedTheme)
/**
* Globally registers a new <code>mixed</code> theme.
*
* @param theme1
* The main theme for the new <code>mixed</code> theme.
* @param theme2
* The secondary theme for the new <code>mixed</code> theme.
*/
public static void addMixedTheme(SubstanceTheme theme1,
SubstanceTheme theme2)
/**
* Globally registers a collection of <code>mixed</code> themes such as:
* <ul>
* <li>The specified theme is the main theme for a new <code>mixed</code>
* theme.
* <li>The secondary theme is of the same kind.
* </ul>
*
* @param mainTheme
* The main theme for the new <code>mixed</code> themes.
*/
public static void addMixedThemeBy(SubstanceTheme mainTheme)
In addition, you can set mixed theme on a single control in the same way
that you set custom theme on a single control (using
SubstanceLookAndFeel.BUTTON_THEME_PROPERTY client
property).
Inverted color schemes
Inverted color scheme is based on inverting a simple color scheme. Here are examples of
inverted themes: Inverted Aqua,
Inverted Barby Pink, Inverted Steel Blue
and Inverted Sunset:
In order to globally enable inverted themes in your application you can use the
SubstanceLookAndFeel.ENABLE_INVERTED_THEMES client property
and put it on UIManager with Boolean.TRUE value. In addition, you can run your application with
-Dsubstancelaf.enableInvertedThemes VM flag. Once inverted themes
are enabled, Substance will create an inverted theme for all available bright and cold themes.
Tinted, toned and shaded color schemes
All Substance color schemes can be tinted (shifted towards white),
toned (shifted towards gray) and shaded (shifted towards black).
- In order to tint a color scheme, use
org.jvnet.substance.color.TintColorScheme.
- In order to tone a color scheme, use
org.jvnet.substance.color.ToneColorScheme.
- In order to shade a color scheme, use
org.jvnet.substance.color.ShadeColorScheme.
The following screenshots illustrate the original (AQUA) color scheme, 40% tinted, 40% toned
and 40% shaded versions of the original (AQUA) color scheme:
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:
- ColorScheme colorScheme - the corresponding color scheme. It will
be used for the painting.
- String displayName - the display name of the theme.
- ThemeKind themeKind - the theme kind (bright, cold, dark, ...). This
indication will be used for computing interpolated colors for various components.
In addition, it is used to compute the correct metallic and gray schemes.
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
- Call SubstanceLookAndFeel.setCurrentTheme() with one of the
above themes, for example SubstanceLookAndFeel.setCurrentTheme(new
SubstanceBrownTheme())
- Call SubstanceLookAndFeel.setCurrentTheme() with the fully
qualified name of one of the above themes, for example
SubstanceLookAndFeel.setCurrentTheme("org.jvnet.substance.theme.SubstanceBrownTheme")
- 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 starting from version 2.2. 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 SubstanceTheme.addUserDefined
function. This function thakes three parameters and returns a new theme. The parameters are:
- ColorScheme object as described above.
- ThemeKind - bright / cold / dark.
- String - theme display name.
The return 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:
- String theme display name
- String theme class name
- ThemeKind - bright / cold / dark
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
- To retrieve the display name of the current theme use
/**
* Returns the current color theme name.
*
* @return Current color theme name.
*/
public static String getCurrentThemeName()
- To retrieve the current theme use
/**
* Returns the current theme.
*
* @return The current theme.
*/
public static SubstanceTheme getTheme()
- To retrieve information on all available themes use
/**
* Returns all available themes.
*
* @return All available color themes. Key - theme name, value - theme
* information.
*/
public static Map<String, ThemeInfo> getAllThemes()