Substance skinning primer
As Substance look-and-feel nears the official release 4.1 (scheduled for November 12th), i’m working on the missing documentation. This entry talks about the using the painter layer to skin custom components.
As mentioned in the painter overview, most of the Substance painting logic is abstracted into a set of painters. This not only allows preventing duplicate painting sequence in the Substance UI delegates. This also provides a painting layer for the applications that wish to paint custom components in a way that is consistent with other Substance visuals.
This applies in two major cases:
- Providing consistent painting for a standalone component suite, such as SwingX.
- Providing consistent painting for custom components and visual areas of a specific application.
Instead of trying to match the colors, gradients and animation sequences from the current Substance skin (which might change between various releases), applications can use the Substance painting APIs. This will result in code which is shorter, more maintainable and also produces consistent results.
Skinning primer
The following Substance APIs are most suited for painting custom components:
Most of the Substance UI delegates use a combination of the above APIs. While the exact combination in the existing UI delegates is subject to change in between releases, you can study the core Substance code to see the main combination patterns.
The first pattern is watermark overlaying. The watermarks are painted on most Swing containers, and on some components as well. In simpler cases (such as <font color="darkblue">JPanel</font>
), the watermark is painted on top of the gradient fill. In more complex scenarios, after the watermark has been painted, the fill sequence is repeated with lower alpha value. Here is an example of such a scenario:
- Using the header painter to paint the background gradient.
- Using the watermark to paint the current watermark.
- Using the header painter once again, this time with the
<font color="darkblue">AlphaComposite.SRC_OVER</font>
with alpha value of 0.5.
The second pattern is decorating. The header painters can be used to provide distinct painting to some containers, this setting them “apart” from the rest of the application. As the pattern name implies, this works best on specialized containers and visual areas that are situated along the window edges. Here is an example of SwingX <font color="darkblue">JXLoginDialog</font>
component painted by the Substance SwingX plugin:
<font color="darkblue">JXLoginDialog</font>
has a “decoration” strip located along the top side of the window. To paint the background of this component, the custom UI delegate is using the current header painter, which results in a consistent appearance of the top portion of this dialog.Here is another example of this pattern, this time on the <font color="darkblue">JXStatusBar</font>
component from SwingX component suite. Assuming that this component will be placed along the bottom side of the frame, the matching UI delegate in the Substance SwingX plugin uses the current header painter to provide a distinct appearance of status bar which is consistent with the title pane and menu bar:
<font color="darkblue">JRibbon</font>
component from Flamingo component suite under the Substance Flamingo plugin: <font color="darkblue">JCommandButton</font>
component from Flamingo component suite. The custom UI delegate uses the border painter to paint the button border (a simpler contour in this case):
<font color="darkblue">JRibbon</font>
component from Flamingo component suite: <font color="darkblue">JCommandButton</font>
), where the button fill is painted by the current gradient painter as well.