|Lightweight UI Toolkit Developer's Guide
Every LWUIT component has a style associated with it (see Chapter 7). This style can be manipulated manually and can be customized using a set of definitions for a specific component type. For example, in order to make the backgrounds for all the buttons red you can use the following theme:
This theme sets the background in the style object within the button object to red. A theme can be packaged into a resource file (see Chapter 9) and it can be loaded or switched in runtime. In order to update a theme after switching you must refresh the root component (the Form/Dialog containing our component tree) using the
refreshTheme method to update all styles.
Manually modified style elements are not updated when switching a theme.
For example, if you have a button whose background is customized to blue, and you load or refresh a theme with a different background color for buttons, the new theme affects all button instances except for the one you have modified manually.
This allows you to determine styles for specific components yet still be able to use themes for the general look of the application without worrying about how they affect your changes.
A theme file is very similar in spirit to CSS, yet it is much simpler and it is structured like a Java properties file. A theme file is comprised of key value pairs. The key acts in a similar way to a CSS selector that indicates the component or attribute affected by the theme value. For example:
Button.font – font for all buttons
font – default application font applied to all components where no default is defined
The key element is comprised of an optional unique identifier ID for the component (the UIID) and a required attribute type. Unlike CSS, themes do not support elements such as hierarchy or more complex selectors.
Component UIIDs correspond to the component class name by convention. For example.:
The supported attributes and their value syntax are illustrated in Table 8-1:
Table 8-1 Attributes
Determines the values for the gradient of the image. Accepts source/destination color as well as X/Y of the center of a radial gradient.
Hexadecimal number representing the background color for the component in an unselected widget. For example, blue would be:
Name of an image from within the resource that should be used as the background for this component. The image referenced must exist within the resource using the same name mentioned here. See the resources chapter for further details about resources and theme files.
Allows determining the type of the background whether it is an image, color, or gradient. Valid values are:
Hexadecimal number representing the foreground color for the component usually used to draw the font in an unselected widget. For example, red would be:
The name of the bitmap or system font from the build XML file.
The amount of margin for the component defined as 4 comma-separated integer values representing top, bottom, left, and right. For example,
Padding is identical to margin in terms of format but it updates the padding property of the component. To understand padding versus margin further please refer to the box model explanation in Margin and Padding.
A number between 0 and 255 representing the opacity of a component's background. 0 means the background of the component doesn't draw at all (fully transparent) while 255 represents a completely opaque background. Notice that this value currently has no effect on background images (although this behavior might change in a future release).
To install a theme you must load it from the Resources class (see Chapter 9), from which you receive the already parsed hashtable containing the selectors (keys) and their appropriate values. You then submit this class to the UI manager's
setThemeProps method in order to update the current theme. It is a good practice to call
refreshTheme on all components in memory (even those that are not visible) otherwise behavior is unpredictable.
While a theme is remarkably powerful and relatively simple, it doesn't allow the deep type of customization some applications require. Developers would often like the ability to control the drawing of all widgets from a single location, relieving them of the need to subclass widgets and manipulate their paint behavior.
LWUIT delegates all drawing to a single abstract base class called
LookAndFeel, an instance of which may be obtained from the
UIManager. This class has a concrete subclass which provides the default LWUIT look called
DefaultLookAndFeel may be subclassed in order to extend/replace their functionality.
The look and feel class has methods for determining the boundaries (preferred size) of component types and for painting all components. In addition it has some special methods that allow you to bind special logic to components and manually draw widgets such as scroll bars. It is the responsibility of the Look and Feel developer to properly use the Style objects delivered by the theme. If you replace the look and feel class, you must make sure to extract values appropriately from component styles of the theming functionality or LWUIT can break.
For further details about the look and feel classes, please consult the API documentation.