Validation overlays using JXLayer
To continue addressing the disadvantages of overriding paint()
for showing validation overlays, this time i will talk about the JXLayer
component. Developed and maintained by Alexander Potochkin, it is one of the most versatile Swing utilities that i have seen in the last two years. One of the next entries will talk about using a glass pane for validation overlays; it will also mention the two main disadvantages of glass panes
- You can have only one glass pane for a top-level window (flexibility)
- When glass pane is repainted, the entire frame is repainted with it (performance)
The best way to describe JXLayer
in one sentence would be that it provides the functionality of a glass pane on the component level. While addressing both disadvantages of glass panes, it also has advanced APIs to set custom alpha value, install filters and support non-rectangular components. What does this have to do with validation overlays?
Using JXLayer
allows us to address one limitation of directly overriding paint()
– we don’t need to install a custom repaint manager to extend the dirty region from an inner component to its containing complex component (say, from the inner text field to the containing editable combobox). Note that the second limitation (not using “pure” core components) unfortunately remains.
All classes in this entry are located in the org.pushingpixels.validation.jxlayer
package. The JXLayerComponentFactory
provides a custom painter for JXLayer
that paints the component itself and the validation icon if necessary. In addition, it provides a utility method to “wrap” any JComponent
with our custom JXLayer
. The JXLayerSampleUi
creates the UI itself – note that instead of adding “regular” components (such as JTextField
or JComboBox
), it wraps them with JXLayer
s and adds those (much as you would add a JTable
wrapped in a JScrollPane
, so the notion is not completely foreign to a Swing developer).
The biggest gain from using JXLayer
in our example is that there is no longer need for a custom repaint manager. Since it wraps our component with an additional “glass sheet”, Swing knows that it needs to repaint the entire component when any of its parts is dirty. Since we’re operating on a single component (and not on the entire frame as glass pane does), the performance penalty is more than acceptable (remember that repaint manager is a global resource, so not having to install one is a very good thing). Here is how our UI looks like under JXLayer
: