Perhaps one of the bigger disadvantages of implementing the validation overlays by extending a specific look and feel is that this technique effectively locks your application into that LAF. While this can be addressed with complicated bytecode injection techniques that might fail under different LAFs, isn’t there another way to add the validation overlay as a simple “add on” on top of any LAF? In this entry we will look at a solution available in the core Swing package – a multiplexing look and feel.
Available from as far back as JDK 1.3, the MultiLookAndFeel class sounds like a perfect solution to our problem. Reading the documentation of this class promises a nice and clean solution:
A multiplexing look and feel [addresses] both these problems simultaneously because it allows multiple look and feels to be combined. The first problem (having to use what amounts to a second copy of the same code) is solved because the developer can create a specialized look and feel that can then be combined with other look and feels. The second problem (having to force the use of a particular look and feel) is solved because a specialized look and feel can be used with whatever default look and feel the application may have locked in place.
With all this promise there are surprisingly few examples of using multiplexing LAF (even given that it has existed for quite some time now). First, you can read this thread on java.net dating back to 2005 (especially the remarks from then-Swing architect Scott Violet). Second, note how this bug is still open after two years. In this entry i’m going to show just a few deficiencies of the multiplex LAF implementation and why you should stay clear of it in most cases.
The classes in this entry are located in the org.pushingpixels.validation.multilaf
package and implement the validation overlays using a multiplex LAF (on top of the Substance LAF). The first implementation takes off by learning all the mistakes from the previous entry – using custom borders and special handling of inner text fields for proper overlays. The ValidationTextFieldUI
and ValidationComboBoxUIFirstTry
do just that. Then, we set Substance as the “main” LAF and add our “validation” LAF (that has these two UI delegates) as an auxiliary LAF (you can have more than one). Here is how our application looks like:

As you can see, the combobox buttons are clearly not coming from the main LAF. What is going on? Our combobox UI delegate extends the BasicComboBoxUI
(so as to allow us to add the validation overlay functionality to any LAF). The arrow button is part of the internal implementation in the UI delegate and is created by the createArrowButton()
, which is called from the installComponents()
. So far so good, since this is how a combobox UI delegate that extends the basic implementation works. The problem with the MultiComboBoxUI
is that it invokes the “lifecycle” methods of the installed UI delegates starting from the main LAF. And so, the MultiComboBoxUI.installUI
first calls SubstanceComboBoxUI.installUI
(which calls SubstanceComboBoxUI.installComponents
which calls SubstanceComboBoxUI.createArrowButton
), and then calls the ValidationComboBoxUIFirstTry.installUI
(which goes through the same sequence of steps, eventually calling the BasicComboBoxUI.createArrowButton
). And so, the arrow button installed by the main LAF is effectively uninstalled by our extension without it explicitly doing so. Note that this would happen under any other LAF; it’s not Substance-specific.
With this very technical detail exposed, our second try in ValidationComboBoxUISecondTry
is to override the createArrowButton()
and return null. Not only this adds an unnecessary implementation complexity to our class (which has absolutely nothing to do with validation overlays, by the way), it also results in a nice NullPointerException
when BasicComboBoxUI.installComponents()
tries to add the null result to the combobox. Obviously, the core Swing implementation of multiplex LAF was never tested under such a simple scenario as adding custom painting to comboboxes.
Our last try is in ValidationComboBoxUI
which has to use very “brittle” techniques to preserve the original button appearance. It overrides the createArrowButton()
, iterates over all UI delegates picking the one that doesn’t come from our auxiliary LAF, finds its createArrowButton()
using reflection (since this method is protected), marks it as accessible and calls it using reflection. Obviously, this is not the best thing to do – the reflection might fail under a stricter security manager and the code is ugly and difficult to refactor.
Here is how our application looks now:

Although the combo buttons look consistent with the application, note how they are four pixels wider than they without our auxiliary validation LAF (18*15 instead of 14*15). What does this mean – yet more exploration of the combobox UI implementation to find which method is responsible for computing the button bounds and, perhaps, yet more unnecessary and unjustified overriding of methods that are not related to our functionality (with possible use of reflection).
So, as you can see, the multiplex LAF is one of the worst techniques that you can choose for the validation overlays and pretty much for any other paint-related functionality. It’s a real pity that after seven years this functionality remains in such unfinished state.
With the last few entries essentially using the same part of the Swing painting pipeline (overriding or extending paint() in one way or another), it’s time to continue along the pipeline. In this entry i’m going to talk about the using the UI delegates to show validation overlays and the various issues with this approach.
In general, almost all parts of core Swing components are painted by the UI delegates. A UI delegate is a class that is responsible for painting a specific class of Swing components. For example, JButton
s are painted by the ButtonUI
delegate, JSlider
s are painted by the SliderUI
delegate and so on. Together, UI delegates form what is called a look and feel. There are a few core LAFs (such as Metal / Ocean, Windows, GTK, Motif, Synth and the upcoming Nimbus) and about 15-20 third-party commercial and open-source ones (a comprehensive list is available at javootoo.com). While in general almost everything is painted by the UI delegates, this does not automatically mean that they are the best answer to all problems, and i’m going to address different LAF-related issues in this entry.
The classes in this entry are located in the org.pushingpixels.validation.specificlaf
package and implement the validation overlays using a custom look-and-feel that extends the Substance LAF. In general, you would have to extend a UI delegate for each one of the component classes that can have validation overlays.
Our first attempt is straightforward -all the UI delegates inherit the update(Graphics g, Component c)
method from the common base ComponentUI
class. This is the method that is called in JComponent.paintComponent()
to paint the actual component. In our ValidationComboBoxUIFirstTry
and ValidationTextFieldUIFirstTry
we override the update method, call the super implementation and then paint the validation icon. Here is the screenshot of our UI:

Obviously, this is not what we want. What is happening here? For starters, look at the second part of the Swing painting pipeline – after paintComponent()
is done, Swing calls paintBorder()
. This effectively means that the component border will be painted after the UI delegate is done painting the component. See what happens with the top (non-editable) combobox and the first text field – the validation error is partially overdrawn by the component border. How can we address this problem?
Unfortunately, the solution is not on the pure look-and-feel level. We have to install a custom border in much the same way as discussed in the section on borders. The advantage of doing this on the LAF level is that the application UI creation logic remains the same – the borders are installed by the UI delegates of the relevant components. As mentioned in the section on borders, the current core implementation of the Swing pipeline allows the paintBorder()
method to paint in the entire bounds of the component (doesn’t install a custom clip that matches the border insets). So, let’s see how our application looks like under the ValidationComboBoxUI
and ValidationTextFieldUISecondTry
:

The first combobox and the first text field look as expected. What about the second (editable) combobox? As already mentioned, an editable combobox is implemented with a text field and a button. These are painted in the paintChildren()
method, which is called after paintComponent()
and paintBorder()
are done. And so, the inner text field of the editable combobox partially hides the validation icon painting of the “container” combobox. How can this be addressed?
The ValidationTextFieldUI
overrides the update()
method in addition to installing a custom border. While the border is painting the validation overlay on regular text fields, the update()
method traverses the component hierarchy, checks whether the current parent needs to show a validation overlay and if so, paints the validation icon offset to the parent coordinates. Here is how the application looks now:

And now that we have seen how the validation overlays can be achieved by extending a look-and-feel, i’ll talk about the good and the bad sides of doing so.
By doing the custom painting on the LAF level you’re decoupling this functionality from your main application. In addition, you would be able to reuse this LAF in another application. On the other hand, there are many shortcomings to this approach:
- By extending a specific look-and-feel, you’re binding your application to it. While this can be addressed with bytecode modification (injecting the required functionality into any core or third-party LAF either offline or in the classloader), doing so is very complicated, might not work on LAFs that don’t follow the usual painting cycle (such as WinLAF or Synth) or not feasible (such as changing core LAFs in the classloader).
- Much as with repaint manager or glass pane, you can only have one active look-and-feel at any given time. If you need to implement additional functionality using this approach, the code becomes much less reusable and maintainable. The multiplex look-and-feel that i will talk about in the next entry brings more problems than it solves.
- The LAF operates further along the way of the Swing painting pipeline than what is needed for this specific functionality. This makes the implementation more complicated by explicitly handling the borders and internal components. In case of borders, this might interfere with existing application logic when property change listeners will be activated on changing the border.
- As with other component-level techniques, we still need to install a custom repaint manager that expands the dirty region from an inner component to the actual component that shows the validation overlay. This can be addressed by firing a repaint event whenever such an inner component is repainted (to repaint the parent component). The implementation needs to make sure that there is no infinite repaint loop. In addition, since the repainting in Swing is asynchronous, you might end up with temporary visual artifacts.
- You need to provide a UI delegate for every component class that can have validation errors. As seen in the examples above, some of these UI delegates will have to provide a complex logic for painting the validation overlays. In addition, some of them will have to take into account rather “extreme” cases such as using unusual components in the combobox editor (that can take any component). So, the code that we have seen in the last version of the text field UI delegate will have to be replicated for a lot of other controls (especially if you’re planning to ship such a LAF as a standalone library that is not specific to one of your applications where you have complete control).
The next entry will talk about the multiplex look and feel that is trying to address some of the problems mentioned above, but brings even more problems with it.
As shown in the previous two entries, glass panes have a few disadvantages that might make you look for an alternative way of implementing your functionality. In our case, using glass pane for validation overlays might not be the best choice because of:
These two can be addressed by using a lesser known technique, which only now is starting to find its way into the Swing tutorials and books – a JLayeredPane
. Going back to the diagrams shown in the previous entry, a root pane consists of a sequence of “layers”. The layered pane has the content pane and the menu bar (the bounds of these two are computed by the root pane UI delegate, which will be important for the next entry). The glass pane is “located” on top of the layered pane:

The layered pane itself is a sequence of layers, as illustrated in the diagram below:

In addition to the existing six “core” layers in the default implementation of a JLayeredPane
, you can install your own layers at pretty much any location (in between any two core layers). For our purpose, we would want to install our validation layer between the default and the palette layers, so that it is not painted on top of other layers (such as modal, popup or drag). Note how the JLayeredPane
elegantly addresses the disadvantages of using a glass pane.
First, you can have up to 99 layers in between the “adjacent” core layers. Of course you can still have different parts of your application (such as third-party libraries) try to install their layers to the same index, but at least you will be able to control the location of your own layers (something that can not be easily addressed with glass panes or repaint managers). In addition, if your layer is placed below the popup layer, it will not show the validation overlays over the lightweight popups.
The classes in this entry are located in the org.pushingpixels.validation.layeredpane
package and implement the validation overlays using a custom layered pane. The implementation of a custom validation layer in ValidationLayer
is pretty much the same as the first implementation of a glass pane (without the need to specially handle the lightweight popups). It recursively visits all the components in the root pane and paints validation markers as necessary. Note that as with glass pane, we are able to paint the validation markers partially outside the component bounds.
The first attempt at installing this validation layer is in the LayeredPaneSampleUiFirstTry
class, and it follows this example from the Filthy Rich Clients book. We get the layered pane of the frame root pane, add our validation layer between the core default and palette layers and install the OverlayLayout
on the layered pane. Here is the result:

As you can see, while the validation icons are displayed correctly, the title pane is gone. This happens because the OverlayLayout
overrides the layout manager that handles the placement of title pane under decorated mode. A possible solution to this problem is implemented in the LayeredPaneSampleUi
which wraps the original layout manager (that handles the title pane among the rest) and positions our validation layer to span over the content pane (but not the title pane). Here is a screenshot of the same application under this implementation:

To validate that the lightweight popups are displayed correctly, here is a screenshot of the application when the first combobox shows its popup:

As you can see, implementing validation overlays using layered panes successfully addresses various issues with other techniques:
- Unlike many “component-level” techniques such as overriding paint() or using
JXLayer
, it can paint outside the component bounds.
- In addition, it doesn’t require installing a custom repaint manager to extend the dirty region from an internal component to the actual container (such as editable comboboxes).
- Unlike other “global” techniques such as repaint manager or glass pane, you can have multiple layers in layered pane (one for each “task”).
- In addition, you have much finer control over where your layers”goes” (unlike the glass pane).
However, this technique as implemented in our sample code still has performance issues. Since we’re painting outside the component bounds, we install a document listener on our text fields that repaints the entire frame on each document change (since any document change may result in the change of validation status). Even if the validation layer checks the clip bounds to paint the validation overlays, it doesn’t matter much since the entire frame is repainted on every document change.
This can be addressed by repainting only the relevant region “around” the text field that will contain the actual validation overlay. While this is a valid solution, it creates an unnecessary coupling between the component and the actual implementation of the validation painting. In the long run, it adds complexity and additional level of inter-module dependencies.
A much more elegant approach is implemented in the IconFeedbackPanel
class of the JGoodies Validation project. Instead of having the validation layer that paints the error icons, this panel has an actual JLabel
(with the error icon) for each component that needs to show a validation error. In this case, the document listener doesn’t need to trigger the repaint of the whole frame (or even compute the extended bounds for the repaint). It just causes removal or addition of a label at the relevant location in the validation layer. The core listeners (that Swing installs on each container) then simply repaint only those controls that have been affected without repainting the entire frame. In addition, this panel overrides the validateTree()
that is called internally when there are changes to the layout. In this method, the locations of all validation labels are repainted. This small amount of additional coding easily addresses the issue of repaint performance.
While up until now i have talked only about the advantages of using layered panes as compared to all the other techniques that have been discussed up until now, it is not without shortcomings. These are not specific to layered panes; rather they are relevant for all “global” techniques (including repaint manager and glass pane). Think what happens to controls that are contained in such containers as JSplitPane
, JScrollPane
, JTabbedPane
, a panel with CardLayout
or a JInternalFrame
. The code needs to handle the following cases:
- The viewport offsets of scroll panes – the validation markers need to be offset as necessary.
- Controls that are located in unselected tab of a tabbed pane – the validation markers shouldn’t be shown at all.
- Controls that are located in non-fronted component of a panel with card layout – the validation markers shouldn’t be shown at all.
- Controls that are located in an internal frame which has its own layered pane and glass pane.
- Controls that are only partially shown in scroll panes – the validation markers need to be clipped as necessary.
All of these simply do not exist for “control-level” techniques such as overriding paint(), using JXLayer
or a custom look-and-feel (which will be shown in the next entry). The “global” techniques must address and test these cases explicitly to ensure that there are no visual artifacts on complex UIs.
Matt Nathan has asked an excellent question in the comments section of the “Validation overlays using glass pane” entry – what happens when you have your validation field under a lightweight menu?Let’s see what happens when we click on the button of the first combobox:

As you can see, the validation overlays painted by the glass pane are actually painted on top of the combobox popup! This is, of course, not the desired behavior, and here is a short explanation of what is going on.
As explained in Swing tutorial on root panes, a root pane consists of a sequence of “layers”. The layered pane (which i will talk about in the next entry) has the content pane and the menu bar (the bounds of these two are computed by the root pane UI delegate, which will be important for the next entry). The glass pane is “located” on top of the layered pane:

The layered pane itself is a sequence of layers, as illustrated in the diagram below:

So, where does the combobox popup “live”? It depends on whether it is a lightweight popup or a heavyweight popup. In general, a popup that is completely contained inside the frame bounds is called lightweight and lives in the popup layer of the layered pane. A popup that extends beyond the frame bounds is called heavyweight (and is implemented as a separate Window
). And here you can see the reason for the incorrect behavior of our glass pane – it is painted on top of the layered pane, and hence on top of the lightweight popup layer.
One possible way to address this issue is suggested by Matt himself (and is very similar to what i did in the repaint manager entry) – go over all visible lightweight popups and adjust the clipping mask during the repaint of the glass pane. This can get especially tedious when the validation overlays are offset (as in the original glass pane implementation) and you can very quickly get lost in the implementation details.
Another and much simpler way would be to disable the lightweight popup menus by calling JPopupMenu.setDefaultLightWeightPopupEnabled(false)
before showing your frame:

As you can see, the validation overlays are correctly painted since the heavyweight popup window (combobox popup) is painted after the frame is painted.
Note that in our particular case, the desired behavior is that the glass pane painting is done before the popups that hide the relevant controls. This is not always the case, and you might want to have glass pane painted after the popups. In such a case, you will have to provide special treatment for heavyweight popups since they live in their own top-level windows.
An additional implementation of a glass pane that respects the lightweight popup menus for our scenario might do the following after painting the validation overlays (sample implementation in org.pushingpixels.validation.glasspane.ValidationGlassPaneForPopups
):
- Starting from the root pane
- Go over all components recursively
- If a component is a
JPopupMenu
, is showing and is visible
- Paint it on the
Graphics
passed to the paintComponent()
of the glass pane
The end result should be identical to the last screenshot above. As already mentioned, this might not be the desired functionality for all glass pane usages. For example, if your glass pane shows a translucent fill with infinite progress indication, you might not want the popups to be painted with full opacity.