This section discusses possible issues with the heavyweight/lightweight (HW/LW) mixing feature. In particular, it addresses the following issues:
Validate the component hierarchy:
Changing any layout-related properties of a component, such as its size, location, or font, invalidates the component as well as its ancestors. In order for the HW/LW Mixing feature to function correctly, the component hierarchy must be validated after making such changes. By default, invalidation stops on the top-most container of the hierarchy (for example, a Frame
object). Therefore, to restore the validity of the hierarchy, the application should call the Frame.validate()
method. For example:
component.setFont(myFont); frame.validate();
where frame
refers to a frame which contains component
. Note: Swing applications and the Swing library often use the following pattern:
component.setFont(myFont); component.revalidate();
The revalidate()
call is not sufficient because it validates the hierarchy starting from the nearest validate root of the component only, thus leaving the upper containers invalid. In that case, the HW/LW feature may not calculate correct shapes for HW components, and visual artifacts may be seen on the screen.
To verify the validity of the whole component hierarchy a user can use the key combination Control+Shift+F1 as described in Debug Tips for AWT. A component marked 'invalid' may indicate a missing validate()
call somewhere.
Validate roots:
The concept of validate roots mentioned in Validate the component hierarchy has been introduced in Swing in order to speed up the process of validating component hierarchies because it may take a significant amount of time. While such optimization leaves upper parts of hierarchies invalid, this did not bring any issues because the layout of components inside a validate root does not affect the layout of outside component hierarchy (that is, the siblings of the validate root). However, when HW and LW components are mixed together in a hierarchy, this statement is no longer true. That is why the feature requires the whole component hierarchy to be valid.
Calling frame.validate()
may be inefficient as well, and as such AWT supports an alternative, optimized way of handling invalidation/validation of component hierarchies. This feature is enabled with a system property:
-Djava.awt.smartInvalidate=true
Once this property is specified, the invalidate()
method will stop invalidation of the hierarchy when it reaches the nearest validate root of a component on which the invalidate()
method has been invoked. Afterwards, to restore the validity of the component hierarchy, the application should simply call:
component.revalidate();
Note: In this case, calling frame.validate()
would be effectively a no-op (a statement that does nothing) because frame
is still valid. Since some applications rely on calling validate()
directly on a component upper than the validate root of the hierarchy (for example, a frame), this new optimized behavior may cause incompatibility issues, and hence it is available only when specifying the system property.
If an application experiences any difficulties running in this new optimized mode, a user can use the key combination Control+Shift+F1 as described in Debug Tips for AWT to investigate what parts of the component hierarchy are left invalid, and thus possibly cause the problems.
Swing painting optimization:
By default, the Swing library assumes that there are no HW components in the component hierarchy, and therefore uses optimized drawing techniques to boost performance of the Swing GUI. If a component hierarchy contains HW components, the optimizations must be turned off. This is relevant for Swing JScrollPanes
in the first place. You can change the scrolling mode by using the JViewPort.setScrollMode(int)
method.
Non-opaque LW components:
Non-opaque LW components are not supported by the HW/LW mixing feature implementation by default. In order to enable mixing non-rectangular LW components with HW components, the application must use the com.sun.awt.AWTUtilities.setComponentMixingCutoutShape()
non-public API.
Note: The non-rectangular LW components should still paint themselves using either opaque (alpha = 1.0) or transparent (alpha = 0.0) colors. Using translucent colors (with 0.0 < alpha < 1.0) is not supported.
Disable the default HW/LW mix feature:
In the past, some developers have implemented their own support for cases when HW and LW components must be mixed together. The built-in implementation of the feature available since JDK 6 and JDK 7 may cause problems with custom workarounds. In order to disable the built-in feature the application must be started with the following system property:
-Dsun.awt.disableMixing=true