Module java.desktop
Package javax.swing

# Class LookAndFeel

java.lang.Object
javax.swing.LookAndFeel

Direct Known Subclasses:
  `BasicLookAndFeel`, `MultiLookAndFeel`

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.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 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.

### Exceptions

All of the install methods provided by `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.

Since:
  1.2

## Constructor Summary

Constructors
Modifier
Constructor
Description
`protected`
`LookAndFeel()`
Constructor for subclasses to call.

## Method Summary

Modifier and Type
Method
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 systemPropertyName, Object fallbackValue)`
Returns the value of the specified system desktop property by invoking `Toolkit.getDefaultToolkit().getDesktopProperty()`.
`Icon`
`getDisabledIcon(JComponent component, Icon icon)`
Returns an `Icon` with a disabled appearance.
`Icon`
`getDisabledSelectedIcon(JComponent component, Icon icon)`
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 c, String defaultBorderName)`
Convenience method for setting a component's border property with a value from the defaults.
`static void`
`installColors(JComponent c, String defaultBgName, String defaultFgName)`
Convenience method for setting a component's foreground and background color properties with values from the defaults.
`static void`
`installColorsAndFont(JComponent c, String defaultBgName, String defaultFgName, String defaultFontName)`
Convenience method for setting a component's foreground, background and font properties with values from the defaults.
`static void`
`installProperty(JComponent c, String propertyName, Object propertyValue)`
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 retMap, Object[] keys)`
Populates an `InputMap` with the specified bindings.
`static ComponentInputMap`
`makeComponentInputMap(JComponent c, Object[] keys)`
Creates a `ComponentInputMapUIResource` from `keys`.
`static Object`
`makeIcon(Class<?> baseClass, String gifFile)`
Creates and returns a `UIDefault.LazyValue` that loads an image.
`static InputMap`
`makeInputMap(Object[] keys)`
Creates an `InputMapUIResource` from `keys`.
`static JTextComponent.KeyBinding[]`
`makeKeyBindings(Object[] keyBindingList)`
Convenience method for building an array of `KeyBindings`.
`void`
`provideErrorFeedback(Component 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 c)`
Convenience method for uninstalling a border.

### Methods declared in class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

## Constructor Details

### LookAndFeel

protected LookAndFeel()
Constructor for subclasses to call.

## Method Details

### installColors

public static void installColors(JComponent c, String defaultBgName, String defaultFgName)
Convenience method for setting a component's foreground and background color properties with values from the defaults. The properties are only set if the current value is either `null` or a `UIResource`.

Parameters:
  `c` - component to set the colors on
  `defaultBgName` - key for the background
  `defaultFgName` - key for the foreground
Throws:
  `NullPointerException` - as described in exceptions
See Also:
  - `installColorsAndFont(javax.swing.JComponent, java.lang.String, java.lang.String, java.lang.String)`
  - `UIManager.getColor(java.lang.Object)`

### installColorsAndFont

public static void installColorsAndFont(JComponent c, String defaultBgName, String defaultFgName, String defaultFontName)
Convenience method for setting a component's foreground, background and font properties with values from the defaults. The properties are only set if the current value is either `null` or a `UIResource`.

Parameters:
  `c` - component set to the colors and font on
  `defaultBgName` - key for the background
  `defaultFgName` - key for the foreground
  `defaultFontName` - key for the font
Throws:
  `NullPointerException` - as described in exceptions
See Also:
  - `installColors(javax.swing.JComponent, java.lang.String, java.lang.String)`
  - `UIManager.getColor(java.lang.Object)`
  - `UIManager.getFont(java.lang.Object)`

### installBorder

public static void installBorder(JComponent c, String defaultBorderName)
Convenience method for setting a component's border property with a value from the defaults. The border is only set if the border is `null` or an instance of `UIResource`.

Parameters:
  `c` - component to set the border on
  `defaultBorderName` - key specifying the border
Throws:
  `NullPointerException` - as described in exceptions

### uninstallBorder

public static void uninstallBorder(JComponent c)
Convenience method for uninstalling a border. If the border of the component is a `UIResource`, it is set to `null`.

Parameters:
  `c` - component to uninstall the border on
Throws:
  `NullPointerException` - if `c` is `null`

### installProperty

public static void installProperty(JComponent c, String propertyName, Object propertyValue)
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. This method is intended to be used by ui delegate instances that need to specify a default value for a property of primitive type (boolean, int, ..), but do not wish to override a value set by the client. Since primitive property values cannot be wrapped with the `UIResource` marker, this method uses private state to determine whether the property has been set by the client.

Parameters:
  `c` - target component to set the property on
  `propertyName` - name of the property to set
  `propertyValue` - value of the property
Throws:
  `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`
Since:
  1.5

### makeKeyBindings

public static JTextComponent.KeyBinding[] makeKeyBindings(Object[] keyBindingList)
Convenience method for building an array of `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.

Parameters:
  `keyBindingList` - an array of `key-action` pairs
Returns:
  an array of `KeyBindings`
Throws:
  `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`
See Also:
  - `ActionMap`
  - `InputMap`
  - `KeyStroke.getKeyStroke(char)`

### makeInputMap

public static InputMap makeInputMap(Object[] keys)
Creates an `InputMapUIResource` from `keys`. This is a convenience method for creating a new `InputMapUIResource`, invoking `loadKeyBindings(map, keys)`, and returning the `InputMapUIResource`.

Parameters:
  `keys` - alternating pairs of `keystroke-action key` pairs as described in `loadKeyBindings(javax.swing.InputMap, java.lang.Object[])`
Returns:
  newly created and populated `InputMapUIResource`
Since:
  1.3
See Also:
  - `loadKeyBindings(javax.swing.InputMap, java.lang.Object[])`

### makeComponentInputMap

public static ComponentInputMap makeComponentInputMap(JComponent c, Object[] keys)
Creates a `ComponentInputMapUIResource` from `keys`. This is a convenience method for creating a new `ComponentInputMapUIResource`, invoking `loadKeyBindings(map, keys)`, and returning the `ComponentInputMapUIResource`.

Parameters:
  `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[])`
Returns:
  newly created and populated `InputMapUIResource`
Throws:
  `IllegalArgumentException` - if `c` is `null`
Since:
  1.3
See Also:
  - `loadKeyBindings(javax.swing.InputMap, java.lang.Object[])`
  - `ComponentInputMapUIResource`

### loadKeyBindings

public static void loadKeyBindings(InputMap retMap, Object[] keys)
Populates an `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.

Parameters:
  `retMap` - `InputMap` to add the `key-action` pairs to
  `keys` - bindings to add to `retMap`
Throws:
  `NullPointerException` - if `keys` is `non-null`, not empty, and `retMap` is `null`
Since:
  1.3
See Also:
  - `KeyStroke.getKeyStroke(String)`
  - `InputMap`

### makeIcon

public static Object makeIcon(Class<?> baseClass, String gifFile)
Creates and returns a `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.

Parameters:
  `baseClass` - `Class` used to load the resource
  `gifFile` - path to the image to load
Returns:
  a `UIDefaults.LazyValue`; when resolved the `LazyValue` loads the specified image
See Also:
  - `UIDefaults.LazyValue`
  - `Icon`
  - `Class.getResourceAsStream(String)`

### getLayoutStyle

public LayoutStyle getLayoutStyle()
Returns the `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`.

Returns:
  the `LayoutStyle` for this look and feel
Since:
  1.6
See Also:
  - `LayoutStyle.getInstance()`

### provideErrorFeedback

public void provideErrorFeedback(Component component)
Invoked when the user attempts an invalid operation, such as pasting into an uneditable `JTextField` that has focus. The default implementation beeps. Subclasses that wish different behavior should override this and provide the additional feedback.

Parameters:
  `component` - the `Component` the error occurred in, may be `null` indicating the error condition is not directly associated with a `Component`
Since:
  1.4

### getDesktopPropertyValue

public static Object getDesktopPropertyValue(String systemPropertyName, Object fallbackValue)
Returns the value of the specified system desktop property by invoking `Toolkit.getDefaultToolkit().getDesktopProperty()`. If the value of the specified property is `null`, `fallbackValue` is returned.

Parameters:
  `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
Returns:
  the current value of the desktop property
Since:
  1.4
See Also:
  - `Toolkit.getDesktopProperty(java.lang.String)`

### getDisabledIcon

public Icon getDisabledIcon(JComponent component, Icon icon)
Returns an `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.

Parameters:
  `component` - `JComponent` that will display the `Icon`, may be `null`
  `icon` - `Icon` to generate the disabled icon from
Returns:
  disabled `Icon`, or `null` if a suitable `Icon` can not be generated
Since:
  1.5

### getDisabledSelectedIcon

public Icon getDisabledSelectedIcon(JComponent component, Icon icon)
Returns an `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.

Parameters:
  `component` - `JComponent` that will display the `Icon`, may be `null`
  `icon` - `Icon` to generate disabled and selected icon from
Returns:
  disabled and selected icon, or `null` if a suitable `Icon` can not be generated.
Since:
  1.5

### getName

public abstract String getName()
Return a short string that identifies this look and feel, e.g. "CDE/Motif". This string should be appropriate for a menu item. Distinct look and feels should have different names, e.g. a subclass of MotifLookAndFeel that changes the way a few components are rendered should be called "CDE/Motif My Way"; something that would be useful to a user trying to select a L&F from a list of names.

Returns:
  short identifier for the look and feel

### getID

public abstract String getID()
Return a string that identifies this look and feel. This string will be used by applications/services that want to recognize well known look and feel implementations. Presently the well known names are "Motif", "Windows", "Mac", "Metal". Note that a LookAndFeel derived from a well known superclass that doesn't make any fundamental changes to the look or feel shouldn't override this method.

Returns:
  identifier for the look and feel

### getDescription

public abstract String getDescription()
Return a one line description of this look and feel implementation, e.g. "The CDE/Motif Look and Feel". This string is intended for the user, e.g. in the title of a window or in a ToolTip message.

Returns:
  short description for the look and feel

### getSupportsWindowDecorations

public boolean getSupportsWindowDecorations()
Returns `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`.

Returns:
  `true` if the `RootPaneUI` instances created by this look and feel support client side decorations
Since:
  1.4
See Also:
  - `JDialog.setDefaultLookAndFeelDecorated(boolean)`
  - `JFrame.setDefaultLookAndFeelDecorated(boolean)`
  - `JRootPane.setWindowDecorationStyle(int)`

### isNativeLookAndFeel

public abstract boolean isNativeLookAndFeel()
If the underlying platform has a "native" look and feel, and this is an implementation of it, return `true`. For example, when the underlying platform is Solaris running CDE a CDE/Motif look and feel implementation would return `true`.

Returns:
  `true` if this look and feel represents the underlying platform look and feel

### isSupportedLookAndFeel

public abstract boolean isSupportedLookAndFeel()
Return `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.

Returns:
  `true` if this is a supported look and feel
See Also:
  - `UIManager.setLookAndFeel(javax.swing.LookAndFeel)`

### initialize

public void initialize()
Initializes the look and feel. While this method is public, it should only be invoked by the `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`.

See Also:
  - `uninitialize()`
  - `UIManager.setLookAndFeel(javax.swing.LookAndFeel)`

### uninitialize

public void uninitialize()
Uninitializes the look and feel. While this method is public, it should only be invoked by the `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.

See Also:
  - `initialize()`
  - `UIManager.setLookAndFeel(javax.swing.LookAndFeel)`

### getDefaults

public UIDefaults getDefaults()
Returns the look and feel defaults. While this method is public, it should only be invoked by the `UIManager` when the look and feel is set as the current look and feel and after `initialize` has been invoked.

Returns:
  the look and feel defaults
See Also:
  - `initialize()`
  - `uninitialize()`
  - `UIManager.setLookAndFeel(javax.swing.LookAndFeel)`

### toString

public String toString()
Returns a string that displays and identifies this object's properties.

Overrides:
  `toString` in class `Object`
Returns:
  a String representation of this object