March 31st, 2008

Colorizing Swing components under core look-and-feels

Last week i talked about using Substance decoration painters to visually offset Flamingo ribbon component. Jonathan Giles asked a question in the comment sections on how hard would it be to apply these improvements to an application running under other (core or third-party look-and-feels). I did not wish to rush into implementing it, and let it simmer for a while. A few possible solutions presented themselves, some involving colorization on the UI delegate level, and some involving off-screen images and overriding one of the paint methods in the main component.

As expected, the simplest solution is also the most powerful, since it can be applied to any Swing component / container, involves a few lines of code and doesn’t require any changes in the component library. It uses the JXLayer wrapper developed by Alexander Potochkin and one of the filters from JHLabs project.

The JXLayer is a very powerful component that deserves much more attention that it has been getting over the past couple of years. It allows intercepting events, masking out some parts of the UI area, providing validation feedback, adding custom painting and much more. In our case, all we need to do is:

  • Wrap the ribbon in a JXLayer
  • Add a painter to that layer
  • Create an image effect and add a rescale operation on it that shifts the colors towards light blue
  • Add the effect to the painter

At this point, all the visuals from the ribbon will be shifted towards light blue color:

All this amounts to extra 8 lines of code, as shown in the new sample application shipping with the latest 3.1dev drop of Flamingo. While this requires extra two jars in your classpath, the solution is not only elegant, but also applicable to any Swing component / container.