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?
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
JXLayerSampleUi creates the UI itself – note that instead of adding “regular” components (such as
JComboBox), it wraps them with
JXLayers 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