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:
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.
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
JPanel
), 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:
In this scenario, while the regular controls and containers on the content pane are painted with the regular watermark, the frame header (title pane and tool bar) has less "intrusive" watermark painting. This is achieved by the following sequence:
AlphaComposite.SRC_OVER
with alpha value of 0.5.The second pattern is decorating. The decoration 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 JXLoginDialog
component painted by the
Substance SwingX plugin:
In this scenario, the JXLoginDialog
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
decoration 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
JXStatusBar
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 decoration painter to provide a
distinct appearance of status bar which is consistent with the title pane
and menu bar:
The third pattern is border tracing. Those components that require consistent
painting of borders or contours can use the
border painter with the matching contour. Here is an example
of border tracing in the JRibbon
component from Flamingo
component suite under the
Substance Flamingo plugin:
This UI delegate uses the border painter extensively to create the required visuals. Note the outer contour of the ribbon that also includes the selected tab button, and the inner contours of the ribbon tasks.
Here is another example of this pattern, this time on the
JCommandButton
component from Flamingo
component suite. The custom UI delegate uses the border painter to
paint the button border (a simpler contour in this case):
The last pattern is gradient filling. It is used to paint the
inner fill of custom components (along with the border tracing pattern to
paint the component contour). This pattern uses the
fill painter with the matching contour. Here is
an example of the JRibbon
component from Flamingo
component suite:
In this example, the first toggle tab button (Write) is painted by the
current fill painter, providing a consistent
appearance with the rest of the application controls. Another example is the previous
screenshot (of the JCommandButton
),
where the button fill is painted by the current fill painter as well.