Swing's delegation-based architecture was recently extended by the Painter framework, developed as part of the java.net swingx project. In a recent series of blog posts, swingx committer Josh Marinacci explains how to create custom effects for Swing components with just a few good Painters.
Swing's architecture is based on delegation: A component delegates its visual appearance to a UI delegate, its layout to a layout manager, and its event handling to event listeners. The swingx project on java.net has an early implementation of components that take such delegation even further by delegating how they are painted on the screen to Painters.
An example of such a component is JXPanel, a JPanel extension that allows you to set a Painter with its setBackgroundPainter() method.
Josh Marinacci, a member of Sun's Swing team explains in a recent blog post, Introducing Painters, that, in its simplest form, a Painter is any class that implements the single paint() method of the org.desktop.swingx.painter.Painter interface. Painting a component with a custom Painter will then use that paint() implementation to draw the component on the screen.
What makes this techniques powerful is that the swingx project provides several Painter implementations. The immediate parent of most of these is AbstractPainter. Marinacci explains the many features this class provides:
AbstractPainter has several methods for controlling rendering options like antialiasing and interpolation as well as caching support. When you turn on caching, the drawing operations will be stored in an intermediate buffer, which will in turn be used for all screen painting....
One addition feature of AbstractPainter is support for Effects. An Effect is an object which transforms an image in some way. Currently there is only one concrete implementation of the Effect interface: ImageEffect. ImageEffect will apply a BufferedImageOp to your image. Some common examples of BufferedImageOps are things like Gaussian Blurs, brightness and constrast adjustments, and drop shadow.
Marinacci shows that Painters can be combined to achieve a composite effect. The following code snippet, for instance, combines three Painters to achieve the following visual appearance for a panel (this image is presented in Marinacci's blog):
Painter matte = new MattePainter(new Color(128,128,255));
PinstripePainter pinstripe =
new PinstripePainter(new Color(155,155,255), 45.0);
RectanglePainter roundRect = new RectanglePainter(
20,20,20,20, 30,30, true,
Color.GRAY, 3, Color.DARK_GRAY);
CompoundPainter compound =
new CompoundPainter(matte,pinstripe, roundRect);
JXPanel panel3 = new JXPanel();
Filters provide a plug-in mechanism to alter some aspect of painting images or text. There are dozens of common image filters available (see, for instance, DHLab's available Java image filters that encapsulate common image transformation algorithms), and the swingx project provides many additional ones, such as ShadowFilter to add a drop-shadow to a piece of text. A snippet from Marinacci's blog entry illustrates that:
TextPainter textPainter =
new TextPainter("Painters Rock!",
new Font("SansSerif",Font.BOLD, 36),Color.RED);
MattePainter matte = new MattePainter(Color.WHITE);
JXPanel panel4 = new JXPanel();
new CompoundPainter(matte, textPainter));
Marinacci envisions an ecosystem of all sorts of Painters and image transformation filters and effects to emerge for Swing, not unlike the ecosystems that developed around PhotoShop and The Gimp:
In the future I'd love to see us create a web-based gallery of painters where developers can share code and screenshots of their favorite painters.
To make working with third-party Painters easy, a Painter subclass, URLPainter can even load a painter from any URL location.
JXLabel label5 = new JXLabel("Painters Rule");
URLPainter painter =
The Painters API in swingx is an example of how a previously complex task was made easy with a few classes and methods provided by a small framework. It is also an example of another trend: Often the most interesting additions to core Java APIs are developed outside the core JDK libraries, in external projects. That allows new features to be implemented quickly, but developers not following those projects may not know of the new capabilities.
To what extent do you think Painters will make your life developing better-looking Java applications easier?
Since I did that with Morphic in Squeak about 3 years ago. I called it Bricks. It was a proof of concept, I ran out of time to work on it but I found that painters were cool in that they could get you to a certain point, but that certain kinds of painting interacted in undesireable ways. For instance, getting a nice bevel based on the background color was tricky - adding a rounded corner painter produced even more interaction issues.