LookAndFeel (Java Platform SE 8 ) (original) (raw)
LookAndFeel
, as the name implies, encapsulates a look and feel. Beyond installing a look and feel most developers never need to interact directly with LookAndFeel
. In general only developers creating a custom look and feel need to concern themselves with this class.
Swing is built upon the foundation that each JComponent
subclass has an implementation of a specific ComponentUI
subclass. The ComponentUI
is often referred to as "the ui", "component ui", or "look and feel delegate". The ComponentUI
subclass is responsible for providing the look and feel specific functionality of the component. For example, JTree
requires an implementation of the ComponentUI
subclass TreeUI
. The implementation of the specific ComponentUI
subclass is provided by the LookAndFeel
. EachJComponent
subclass identifies the ComponentUI
subclass it requires by way of the JComponent
method getUIClassID
.
Each LookAndFeel
implementation must provide an implementation of the appropriate ComponentUI
subclass by specifying a value for each of Swing's ui class ids in the UIDefaults
object returned from getDefaults
. For example,BasicLookAndFeel
uses BasicTreeUI
as the concrete implementation for TreeUI
. This is accomplished by BasicLookAndFeel
providing the key-value pair "TreeUI"-"javax.swing.plaf.basic.BasicTreeUI"
, in theUIDefaults
returned from getDefaults
. Refer toUIDefaults.getUI(JComponent) for details on how the implementation of the ComponentUI
subclass is obtained.
When a LookAndFeel
is installed the UIManager
does not check that an entry exists for all ui class ids. As such, random exceptions will occur if the current look and feel has not provided a value for a particular ui class id and an instance of the JComponent
subclass is created.
Recommendations for Look and Feels
As noted in UIManager
each LookAndFeel
has the opportunity to provide a set of defaults that are layered in with developer and system defaults. Some of Swing's components require the look and feel to provide a specific set of defaults. These are documented in the classes that require the specific default.
ComponentUIs and defaults
All ComponentUIs
typically need to set various properties on the JComponent
the ComponentUI
is providing the look and feel for. This is typically done when the ComponentUI
is installed on the JComponent
. Setting a property should only be done if the developer has not set the property. For non-primitive values it is recommended that theComponentUI
only change the property on the JComponent
if the current value is null
or implementsUIResource
. If the current value is null
or implements UIResource
it indicates the property has not been set by the developer, and the ui is free to change it. For example, BasicButtonUI.installDefaults
only changes the font on the JButton
if the return value from button.getFont()
is null
or implements UIResource
. On the other hand if button.getFont()
returned a non-null
value that did not implement UIResource
then BasicButtonUI.installDefaults
would not change theJButton
's font.
For primitive values, such as opaque
, the method installProperty
should be invoked. installProperty
only changes the corresponding property if the value has not been changed by the developer.
ComponentUI
implementations should use the various install methods provided by this class as they handle the necessary checking and install the property using the recommended guidelines.
Exceptions
All of the install methods provided by LookAndFeel
need to access the defaults if the value of the property being changed isnull
or a UIResource
. For example, installing the font does the following:
JComponent c; Font font = c.getFont(); if (font == null || (font instanceof UIResource)) { c.setFont(UIManager.getFont("fontKey")); }
If the font is null
or a UIResource
, the defaults table is queried with the key fontKey
. All ofUIDefault's
get methods throw a NullPointerException
if passed in null
. As such, unless otherwise noted each of the various install methods of LookAndFeel
throw a NullPointerException
if the current value is null
or a UIResource
and the supplied defaults key is null
. In addition, unless otherwise specified all of the install
methods throw a NullPointerException
if a null
component is passed in.