The latest weekly drop of JDK 7 (b57) has finally exposed the functionality of translucent and shaped windows as publicly supported APIs on the java.awt.Window class. Bug 6802853 has tracked the progress of exposing these APIs previously available in 6u10+ in the internal com.sun.awt.AWTUtilities class, and it’s time to update the examples to use the new public APIs.
To recap, here are the previous entries that used the AWTUtilities class:
All the source files referenced in these examples have been updated to use the new Window APIs, and here is a brief overview of the relevant API signatures:
- AWTUtilities.isTranslucencySupported(Translucency) is now GraphicsDevice.isWindowTranslucencySupported(WindowTranslucency).
- AWTUtilities.isTranslucencyCapable(GraphicsConfiguration) is now GraphicsConfiguration.isTranslucencyCapable().
- AWTUtilities.setWindowShape(Window, Shape) is now Window.setShape(Shape).
- AWTUtilities.setWindowOpacity(Window, float) is now Window.setOpacity(float).
- AWTUtilities.setWindowOpaque(boolean) is superceded by Window.setBackground(Color). Passing the new Color(0, 0, 0, 0) achieves the old effect of installing per-pixel translucency.
You can see the Javadocs of the new Window methods in the corresponding Mercurial diff, or in the source archive bundled with the b57 installer.
Note that the com.sun.awt.AWTUtilities class is still there, and calling its API methods still produces the correct visuals. A quick look at the implementation reveals that the AWTUtilities methods do not (yet) go directly to the new Window methods, perhaps converging deeper in the AWT internals.
In addition to bug fixes and performance improvements in Substance 5.2 (code-named Quebec), there are a few new skins, such as Dust and Dust Coffee. Twilight skin joins the ranks in the latest 5.2dev drop, and it is inspired by the color schemes of the Bespin web code editor spearheaded by Ben (@bgalbs) and Dion (@dalmaer). If you want to take it for a spin, click on the WebStart button below:

To use it in your application, you have the following three options:
-Dswing.defaultlaf=org.jvnet.substance.skin.SubstanceTwilightLookAndFeel
UIManager.setLookAndFeel(new Substance
Twilight
LookAndFeel())
UIManager.setLookAndFeel("org.jvnet.substance.skin.Substance
Twilight
LookAndFeel");
Here are a few screenshots that show this new skin. A small frame with a tabbed pane and a few different controls:

A frame with menu bar, tool bar and status bar from SwingX project:

A thumbnail of the main Substance test application (click for full-size view):

As with all Substance core skins, this is work in progress and will be polished over time. In the meantime, you’re more than welcome to take the latest 5.2dev drop for a spin and leave your comments. Release candidate for Substance 5.2 is scheduled for May 11 and the final release is scheduled for May 25.
If you’re interested in knowing more about Substance internals, this post is for you. It is a rather advanced topic, and it assumes a certain level of familiarity with how Swing internals work in general. Here is a list of overview articles that provide a glimpse into how Swing operates:
The rest of the post assumes that you’re familiar with the basic building blocks of Swing painting pipeline and common terms of UI delegates.
Contact points
As a UI toolkit, Swing takes care of displaying the application UI controls as pixels on the screen, and handles the user interaction with those pixels. This process has many steps, most of which can be configured by the application via custom painting, layered panes, glass panes and more. Applications that do not use these extension points rely on the current look-and-feel to put the pixels on the screen and control certain aspects of the user interaction.
A look-and-feel is a collection of UI delegates. Each UI delegate handles the specific Swing component type – buttons have button UI delegates, sliders have slider UI delegates, etc. While each component type is different, the UI delegates have very similar contact points that control the various aspects of component lifecycle. Here is the list of major contact points:
- Configuring the visual settings. This includes colors and fonts.
- Configuring the inner layout metrics. This includes insets, margins and gaps.
- Computing the preferred dimension.
- Layout of inner components for composite controls. This is relevant for controls such as combobox which has an inner text field and arrow button.
- Listening to component’s model changes. This includes mouse and keyboard, as well as change and item listeners – depending on the specific control type.
- Painting the different visual areas.
As you can see, painting is only one contact point among many. In an ideal model-view separation promoted by the core Swing library, the UI delegate is responsible for anything that is related to the component’s visual and interaction facets.
Why choose Substance?
Why would you want to use a third-party look-and-feel when core Swing has a number of bundled look-and-feels (including the addition of Nimbus in 6u10+)? Subjective preferences about the visuals aside, Substance provides the following features one would expect from a modern UI toolkit:
- Full high DPI support for the core Swing controls with resolution-independent painting.
- Respecting the desktop font settings of the current environment.
- Built-in animations for the core Swing controls (rollover, selection, …)
- Skinning layer, and especially decoration areas. The eventual goal is to enable even the most demanding designs to be implemented as self-contained Substance skins that can be ported across different applications in the same portfolio.
Substance implementation
As a high-level view, the following Substance classes address the four main points above:
<span style="color: darkblue;">SubstanceSizeUtils</span>
has a bunch of methods to compute the different metrics based on the component font size. It makes sure that all the component visuals (borders, gaps, margins, insets, …) scale and result in consistent physical appearance on various hardware.
<span style="color: darkblue;">SubstanceFontUtilities</span>
has font policy implementations for Windows, Gnome, KDE and Mac desktops.
<span style="color: darkblue;">FadeTracker</span>
(to be refactored to use Trident in the next major Substance version) is the animation engine that powers all built-in animations.
<span style="color: darkblue;">SubstanceSkin</span>
and <span style="color: darkblue;">SubstanceColorSchemeBundle</span>
are the main classes in the skinning layer.
Each Substance UI delegate uses these four classes at different contact points:
<span style="color: darkblue;">SubstanceSizeUtils</span>
is used during the initialization to set up gaps, margins and insets. It is also used during the painting to compute border weights, and in the layout managers to compute the preferred sizes and layout internal sub-components.
<span style="color: darkblue;">SubstanceFontUtilities</span>
is used to populate the <span style="color: darkblue;">*.font</span>
entries in the <span style="color: darkblue;">UIManager</span>
that are later used to set the fonts on the components during the initialization stage.
<span style="color: darkblue;">FadeTracker</span>
is used in various mouse / change listeners to initiate animation sequences (such as mouse rollover over a button, tab losing selection state) and during the painting to show cross-fades between the states.
<span style="color: darkblue;">SubstanceSkin</span>
is used during the painting to compute the colors for painting the different visual areas of the component.
Supporting wide variety of font sizes in modern UI toolkits is a necessity, and previous entry provided a little background on the topic. The keen-eyed readers might have noticed the gaps in the curved corners of the combobox arrow button:

What happened here? The border painter in Substance gets two contours – the outer and the inner. For buttons, these contours are computed by matching the button shaper, ClassicButtonShaper in case of combobox arrow buttons. The problem in the computation was that it used the same curvature radius for both outer and inner contours, which resulted in the visible visual gaps under large font sizes.
The correct solution is to subtract the border stroke weight from the outer radius, and use the resulting value for the inner radius. Unfortunately, the API signature of the SubstanceButtonShaper interface had to be changed in order to accommodate this functionality – so if you have a custom button shaper, you will need to implement a new method added to this interface.
The following screenshot shows a large checkmark icon under Substance 5.2dev (on left) and Substance 5.1 (on right):

The next screenshot shows a combobox under Substance 5.2dev (on top) and Substance 5.1 (on bottom):

As you can see in both screenshots, the inner contour is now aligned with the outer contour in the corners.
This work will continue in the next releases to make sure that all core Swing controls look correctly under different font sizes, including very large values such as shown in this entry. In the meantime, you’re welcome to take the latest 5.2dev drop of core Substance (code-named Quebec) for a spin. Release candidate for Substance 5.2 is scheduled for May 11 and the final release is scheduled for May 25.