C H A P T E R  10

Theming

The Lightweight UI Toolkit library supports pluggable themes similar to CSS and somewhat simpler than Swing's pluggable Look And Feel.


10.1 Basic Theming

Every LWUIT component has a style associated with it (see Chapter 8). 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:

Button.bgColor=ff0000

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



Note - 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:

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.: Button, Label, CheckBox, RadioButton, Form, etcetera.

The supported attributes and their value syntax are illustrated in TABLE 10-1:


TABLE 10-1   Attributes 
Attribute Value
bgAlign Allows determining the alignment of a background image, only effective for non-scaled background images. Valid values include: BACKGROUND_IMAGE_ALIGN_TOP, BACKGROUND_IMAGE_ALIGN_BOTTOM, BACKGROUND_IMAGE_ALIGN_LEFT, BACKGROUND_IMAGE_ALIGN_RIGHT, BACKGROUND_IMAGE_ALIGN_CENTER
bgGradient 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.
bgColor Hexadecimal number representing the background color for the component in an unselected widget. For example, blue would be: ff
bgImage 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.
bgType Allows determining the type of the background whether it is an image, color, or gradient. Valid values are: BACKGROUND_IMAGE_SCALED, BACKGROUND_IMAGE_TILE_BOTH, BACKGROUND_IMAGE_TILE_VERTICAL, BACKGROUND_IMAGE_TILE_HORIZONTAL, BACKGROUND_IMAGE_ALIGNED, BACKGROUND_GRADIENT_LINEAR_HORIZONTAL, BACKGROUND_GRADIENT_LINEAR_VERTICAL, BACKGROUUND_GRADIENT_RADIAL
fgColor Hexadecimal number representing the foreground color for the component usually used to draw the font in an unselected widget. For example, red would be: ff0000
font The name of the bitmap or system font from the build XML file.
margin The amount of margin for the component defined as 4 comma‐separated integer values representing top, bottom, left, and right. For example, 1, 2, 3, 4 results in 1 pixel margin top, 2 pixels margin bottom, 3 pixels margin left and 4 pixels margin right.
padding 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.
transparency 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 11), 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.


10.2 Look and Feel

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. Both LookAndFeel and 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.