public abstract class LookAndFeel extends Object
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. Each JComponent 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 the UIDefaults returned from getDefaults. Refer to UIDefaults 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.
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 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 the
ComponentUI only change the property on the
JComponent if the current value is
null or implements
UIResource. 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 the
JButton'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.
LookAndFeel need to access the defaults if the value of the property being changed is
null 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 of
UIDefault'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.
| Constructor and Description |
|---|
LookAndFeel()
|
| Modifier and Type | Method and Description |
|---|---|
UIDefaults |
getDefaults()
Returns the look and feel defaults.
|
abstract String |
getDescription()
Return a one line description of this look and feel implementation, e.g.
|
static Object |
getDesktopPropertyValue(String
Returns the value of the specified system desktop property by invoking
Toolkit.getDefaultToolkit().getDesktopProperty().
|
Icon |
getDisabledIcon(JComponent
Returns an
Icon with a disabled appearance.
|
Icon |
getDisabledSelectedIcon(JComponent
Returns an
Icon for use by disabled components that are also selected.
|
abstract String |
getID()
Return a string that identifies this look and feel.
|
LayoutStyle |
getLayoutStyle()
Returns the
LayoutStyle for this look and feel.
|
abstract String |
getName()
Return a short string that identifies this look and feel, e.g.
|
boolean |
getSupportsWindowDecorations()
Returns
true if the
LookAndFeel returned
RootPaneUI instances support providing
Window decorations in a
JRootPane.
|
void |
initialize()
Initializes the look and feel.
|
static void |
installBorder(JComponent
Convenience method for setting a component's border property with a value from the defaults.
|
static void |
installColors(JComponent
Convenience method for setting a component's foreground and background color properties with values from the defaults.
|
static void |
installColorsAndFont(JComponent
Convenience method for setting a component's foreground, background and font properties with values from the defaults.
|
static void |
installProperty(JComponent
Convenience method for installing a property with the specified name and value on a component if that property has not already been set by the developer.
|
abstract boolean |
isNativeLookAndFeel()
If the underlying platform has a "native" look and feel, and this is an implementation of it, return
true.
|
abstract boolean |
isSupportedLookAndFeel()
Return
true if the underlying platform supports and or permits this look and feel.
|
static void |
loadKeyBindings(InputMap
Populates an
InputMap with the specified bindings.
|
static ComponentInputMap |
makeComponentInputMap(JComponent
Creates a
ComponentInputMapUIResource from
keys.
|
static Object |
makeIcon(Class
Creates and returns a
UIDefault.LazyValue that loads an image.
|
static InputMap |
makeInputMap(Object
Creates a
InputMapUIResource from
keys.
|
static JTextComponent |
makeKeyBindings(Object
Convenience method for building an array of
KeyBindings.
|
void |
provideErrorFeedback(Component
Invoked when the user attempts an invalid operation, such as pasting into an uneditable
JTextField that has focus.
|
String |
toString()
Returns a string that displays and identifies this object's properties.
|
void |
uninitialize()
Uninitializes the look and feel.
|
static void |
uninstallBorder(JComponent
Convenience method for uninstalling a border.
|
public static void installColors(JComponentc, String defaultBgName, String defaultFgName)
null or a
UIResource.
c - component to set the colors on
defaultBgName - key for the background
defaultFgName - key for the foreground
NullPointerException - as described in
exceptions
installColorsAndFont(javax.swing.JComponent, java.lang.String, java.lang.String, java.lang.String),
UIManager.getColor(java.lang.Object)
public static void installColorsAndFont(JComponentc, String defaultBgName, String defaultFgName, String defaultFontName)
null or a
UIResource.
c - component set to the colors and font on
defaultBgName - key for the background
defaultFgName - key for the foreground
defaultFontName - key for the font
NullPointerException - as described in
exceptions
installColors(javax.swing.JComponent, java.lang.String, java.lang.String),
UIManager.getColor(java.lang.Object) ,
UIManager.getFont(java.lang.Object)
public static void installBorder(JComponentc, String defaultBorderName)
null or an instance of
UIResource.
c - component to set the border on
defaultBorderName - key specifying the border
NullPointerException - as described in
exceptions
public static void uninstallBorder(JComponentc)
UIResource, it is set to
null.
c - component to uninstall the border on
NullPointerException - if
c is
null
public static void installProperty(JComponentc, String propertyName, Object propertyValue)
UIResource marker, this method uses private state to determine whether the property has been set by the client.
c - target component to set the property on
propertyName - name of the property to set
propertyValue - value of the property
IllegalArgumentException - if the specified property is not one which can be set using this method
ClassCastException - if the property value has not been set by the developer and the type does not match the property's type
NullPointerException - if
c is
null, or the named property has not been set by the developer and
propertyValue is
null
public static JTextComponent.KeyBinding [] makeKeyBindings(Object [] keyBindingList)
KeyBindings. While this method is not deprecated, developers should instead use
ActionMap and
InputMap for supplying key bindings.
This method returns an array of KeyBindings, one for each alternating key-action pair in keyBindingList. A key can either be a String in the format specified by the KeyStroke.getKeyStroke method, or a KeyStroke. The action part of the pair is a String that corresponds to the name of the Action.
The following example illustrates creating a KeyBinding array from six alternating key-action pairs:
JTextComponent.KeyBinding[] multilineBindings = makeKeyBindings( new Object[] {
"UP", DefaultEditorKit.upAction,
"DOWN", DefaultEditorKit.downAction,
"PAGE_UP", DefaultEditorKit.pageUpAction,
"PAGE_DOWN", DefaultEditorKit.pageDownAction,
"ENTER", DefaultEditorKit.insertBreakAction,
"TAB", DefaultEditorKit.insertTabAction
});
If
keyBindingList's length is odd, the last element is ignored.
Supplying a null value for either the key or action part of the key-action pair results in creating a KeyBinding with the corresponding value null. As other parts of Swing's expect non-null values in a KeyBinding, you should avoid supplying null as either the key or action part of the key-action pair.
keyBindingList - an array of
key-action pairs
KeyBindings
NullPointerException - if
keyBindingList is
null
ClassCastException - if the
key part of the pair is not a
KeyStroke or
String, or the
action part of the pair is not a
String
ActionMap,
InputMap,
KeyStroke.getKeyStroke(char)
public static InputMapmakeInputMap(Object [] keys)
InputMapUIResource from
keys. This is a convenience method for creating a new
InputMapUIResource, invoking
loadKeyBindings(map, keys), and returning the
InputMapUIResource.
keys - alternating pairs of
keystroke-action key pairs as described in
loadKeyBindings(javax.swing.InputMap, java.lang.Object[])
InputMapUIResource
loadKeyBindings(javax.swing.InputMap, java.lang.Object[])
public static ComponentInputMapmakeComponentInputMap(JComponent c, Object [] keys)
ComponentInputMapUIResource from
keys. This is a convenience method for creating a new
ComponentInputMapUIResource, invoking
loadKeyBindings(map, keys), and returning the
ComponentInputMapUIResource.
c - component to create the
ComponentInputMapUIResource with
keys - alternating pairs of
keystroke-action key pairs as described in
loadKeyBindings(javax.swing.InputMap, java.lang.Object[])
InputMapUIResource
IllegalArgumentException - if
c is
null
loadKeyBindings(javax.swing.InputMap, java.lang.Object[]),
ComponentInputMapUIResource
public static void loadKeyBindings(InputMapretMap, Object [] keys)
InputMap with the specified bindings. The bindings are supplied as a list of alternating
keystroke-action key pairs. The
keystroke is either an instance of
KeyStroke, or a
String that identifies the
KeyStroke for the binding. Refer to
KeyStroke.getKeyStroke(String) for the specific format. The
action key part of the pair is the key registered in the
InputMap for the
KeyStroke.
The following illustrates loading an InputMap with two key-action pairs:
LookAndFeel.loadKeyBindings(inputMap, new Object[] {
"control X", "cut",
"control V", "paste"
});
Supplying a null list of bindings (keys) does not change retMap in any way.
Specifying a null action key results in removing the keystroke's entry from the InputMap. A null keystroke is ignored.
retMap -
InputMap to add the
key-action pairs to
keys - bindings to add to
retMap
NullPointerException - if
keys is
non-null, not empty, and
retMap is
null
KeyStroke.getKeyStroke(String) ,
InputMap
public static ObjectmakeIcon(Class <?> baseClass, String gifFile)
UIDefault.LazyValue that loads an image. The returned value is an implementation of
UIDefaults.LazyValue. When
createValue is invoked on the returned object, the image is loaded. If the image is
non-null, it is then wrapped in an
Icon that implements
UIResource. The image is loaded using
Class.getResourceAsStream(gifFile).
This method does not check the arguments in any way. It is strongly recommended that non-null values are supplied else exceptions may occur when createValue is invoked on the returned object.
baseClass -
Class used to load the resource
gifFile - path to the image to load
UIDefaults.LazyValue; when resolved the
LazyValue loads the specified image
UIDefaults.LazyValue,
Icon,
Class.getResourceAsStream(String)
public LayoutStylegetLayoutStyle()
LayoutStyle for this look and feel. This never returns
null.
You generally don't use the LayoutStyle from the look and feel, instead use the LayoutStyle method getInstance.
LayoutStyle for this look and feel
LayoutStyle.getInstance()
public void provideErrorFeedback(Componentcomponent)
JTextField that has focus. The default implementation beeps. Subclasses that wish different behavior should override this and provide the additional feedback.
component - the
Component the error occurred in, may be
null indicating the error condition is not directly associated with a
Component
public static ObjectgetDesktopPropertyValue(String systemPropertyName, Object fallbackValue)
Toolkit.getDefaultToolkit().getDesktopProperty(). If the value of the specified property is
null,
fallbackValue is returned.
systemPropertyName - the name of the system desktop property being queried
fallbackValue - the object to be returned as the value if the system value is null
Toolkit.getDesktopProperty(java.lang.String)
public IcongetDisabledIcon(JComponent component, Icon icon)
Icon with a disabled appearance. This method is used to generate a disabled
Icon when one has not been specified. For example, if you create a
JButton and only specify an
Icon via
setIcon this method will be called to generate the disabled
Icon. If
null is passed as
icon this method returns
null.
Some look and feels might not render the disabled Icon, in which case they will ignore this.
component -
JComponent that will display the
Icon, may be
null
icon -
Icon to generate the disabled icon from
Icon, or
null if a suitable
Icon can not be generated
public IcongetDisabledSelectedIcon(JComponent component, Icon icon)
Icon for use by disabled components that are also selected. This method is used to generate an
Icon for components that are in both the disabled and selected states but do not have a specific
Icon for this state. For example, if you create a
JButton and only specify an
Icon via
setIcon this method will be called to generate the disabled and selected
Icon. If
null is passed as
icon this methods returns
null.
Some look and feels might not render the disabled and selected Icon, in which case they will ignore this.
component -
JComponent that will display the
Icon, may be
null
icon -
Icon to generate disabled and selected icon from
null if a suitable
Icon can not be generated.
public abstract StringgetName()
public abstract StringgetID()
public abstract StringgetDescription()
public boolean getSupportsWindowDecorations()
true if the
LookAndFeel returned
RootPaneUI instances support providing
Window decorations in a
JRootPane.
The default implementation returns false, subclasses that support Window decorations should override this and return true.
true if the
RootPaneUI instances created by this look and feel support client side decorations
JDialog.setDefaultLookAndFeelDecorated(boolean) ,
JFrame.setDefaultLookAndFeelDecorated(boolean) ,
JRootPane.setWindowDecorationStyle(int)
public abstract boolean isNativeLookAndFeel()
true. For example, when the underlying platform is Solaris running CDE a CDE/Motif look and feel implementation would return
true.
true if this look and feel represents the underlying platform look and feel
public abstract boolean isSupportedLookAndFeel()
true if the underlying platform supports and or permits this look and feel. This method returns
false if the look and feel depends on special resources or legal agreements that aren't defined for the current platform.
true if this is a supported look and feel
UIManager.setLookAndFeel(javax.swing.LookAndFeel)
public void initialize()
UIManager when a look and feel is installed as the current look and feel. This method is invoked before the
UIManager invokes
getDefaults. This method is intended to perform any initialization for the look and feel. Subclasses should do any one-time setup they need here, rather than in a static initializer, because look and feel class objects may be loaded just to discover that
isSupportedLookAndFeel() returns
false.
public void uninitialize()
UIManager when the look and feel is uninstalled. For example,
UIManager.setLookAndFeel invokes this when the look and feel is changed.
Subclasses may choose to free up some resources here.
public UIDefaultsgetDefaults()
UIManager when the look and feel is set as the current look and feel and after
initialize has been invoked.
initialize(),
uninitialize(),
UIManager.setLookAndFeel(javax.swing.LookAndFeel)