C H A P T E R  3

Using Lists

Because screen size is limited, lists are the most common basic UI widget on devices. A List presents the user with a group of items displayed in a single column. The set of elements is rendered using a ListCellRenderer and is extracted using the ListModel. Swing’s Model/View/Controller architecture (MVC) makes it possible for a list to represent many UI concepts ranging from a carousel to a To-Do checklist. A list component is relatively simple. It invokes the model in order to extract the displayed or selected information and invokes the cell renderer to show it to the user. The list class itself is completely decoupled from everything, so you can extract its content from any source (for example, the network, storage etcetera) and display the information in any form (for example, Checkboxes, Strings, Icons, and so forth).

3.1 Initializing a List

You can create a list in one of four ways:

List() Creates a new instance of List with an empty default model.
List(ListModel model) Creates a new instance of List with the given model.
List(Object[] items) Creates a new instance of List with an array of Objects that are placed into the list model.
List(Vector items) Creates a new instance of List where a set of items are placed into the list model.

3.2 Creating a Model

There are two ways to create a list model:

ListModel Implement the list model interface (use a general purpose implementation of the list model interface derived from the DefaultListModel)
DefaultListModel Everything is taken care of for you.

3.2.1 ListModel

Represents the data structure of the list, thus allowing a list to represent any potential data source by referencing different implementations of this interface. For example, a list model can be implemented in such a way that it retrieves data directly from storage (although caching is recommended). It is the responsibility of the list to notify observers (specifically the view List of any changes to its state (items removed, added, or changed, and so forth) thus the data is updated on the view.

3.2.2 DefaultListModel

The following code demonstrates using the DefaultListModel class with a vector of elements.

// Create a set of items
String[] items = { "Red", "Blue", "Green", "Yellow" };

// Initialize a default list model with “item” inside
DefaultListModel myListModel = new DefaultListModel(items);

// Creating a List with “myListModel”

3.3 List Cell Renderer

A list uses an object called a cell renderer to display each of its items. The default cell renderer knows how to display strings and icons and it displays Objects by invoking toString. If you want to change the way the default renderer display icons or strings, or if you want behavior different than what is provided by toString, you can implement a custom cell renderer. You can create a list renderer using ListCellRenderer or DefaultListCellRenderer:

3.3.1 ListCellRenderer

ListCellRenderer is a "rubber stamp" tool that allows you to extract a renderer instance (often the same component instance for all invocations) that is initialized to the value of the current item. The renderer instance is used to paint the list and is discarded when the list is complete.

An instance of a renderer can be developed as follows:

public class MyYesNoRenderer extends Label implements ListCellRenderer {
   public Component getListCellRendererComponent(List list, 
                     Object value, int index, boolean isSelected) {
      if( ((Boolean)value).booleanValue() ) {
      } else {
        return this;

   public Component getListFocusComponent(List list) {
      Label label = new label("");

      return label;

It is best that the component whose values are manipulated does not support features such as repaint(). This is accomplished by overriding repaint in the subclass with an empty implementation. This is advised for performance reasons, otherwise every change made to the component might trigger a repaint that wouldn't do anything but still cost in terms of processing.

3.3.2 DefaultListCellRenderer

The DefaultListCellRender is the default implementation of the renderer based on a Label and the ListCellRenderer interface.

getListCellRendererComponent() Returns a component instance that is already set to renderer "value". While it is not a requirement, many renderers often derive from a component (such as a label) and return "this".
getListFocusComponent() Returns a component instance that paints the list focus item. When the selection moves, this component is drawn above the list items. It’s best to give some level of transparency (see code example in ListCellRenderer). Once the focused item reaches the cell location then this Component is drawn under the selected item.

Note - To emulate this animation, call List.setSmoothScrolling(true). This method is optional an implementation can choose to return null

3.4 Adding Items to and Removing Items From a List

You can add items to a list in one of two ways. The first way is to create a ListModel and add it to the list, either when initiating a List or using the method setModel(ListModel model). To remove an item or all items from a List, use removeItem(int index) or removeAll() methods.

For example:

// Adding to a list either by the above DefaultListModel
// snipped code or
myListModel.addItem(“New Item”);

// Removing is done by
// or

3.5 List Events

Two types of events are supported here, ActionEvent and SelectionsListener in addition to addFocusListener(FocusListener l) that is inherited from Component. ActionEvent binds a listener to the user selection action, and the SelectionListener is bound to the List model selection listener. The listener bindings mean you can track changes in values inside the Model.

3.5.1 Fixed Selection Feature

The fixed selection feature supports a dynamic versus static item movement in a List. In a Java SE environment the list items are typically static and the selection indicator travels up and down the list, highlighting the currently selected item. The Lightweight UI Toolkit introduces a new animation feature that lets the selection be static while the items move dynamically up and down. To indicate the fixed selection type, use setFixedSelection(int fixedSelection) where fixedSelection can be one of the following:

FIXED_NONE Behave as the normal (Java SE) List behaves. List items are static and the selection indicator travels up and down the list, highlighting the currently selected item.
FIXED_TRAIL The last visible item in the list is static and list items move up and down.
FIXED_LEAD The first item in the list is static and list items move up and down.
FIXED_CENTER The middle item in the list is static and list items are move up and down.

3.6 Tickers in List

Because list items are essentially rendered as a rubber stamp they can't be treated as typical LWUIT components. Things such as binding event listeners to the components in the list won't work since the list reuses the same component to draw all the entries.

Features such as tickering an individual cell are often requested and the solution isn't trivial because what we need to do is essentially "ticker the List" not the renderer.

The sample below tickers a renderer by registering itself as an animation in the parent form and calling the list's repaint method to ticker. Notice that it has a separate entry for the selected list item otherwise the entire content of the list would constantly ticker.

EXAMPLE 3-1   Tickering a Renderer
class TickerRenderer extends DefaultListCellRenderer {
   private DefaultListCellRenderer selectedRenderer = new
   private List parentList;
   public TickerRenderer() 
   public boolean animate() {
      if(parentList != null && parentList.getComponentForm() != null) {
         if(selectedRenderer.isTickerRunning()) {
            if(selectedRenderer.animate()) {
      return super.animate()
   public Component getListCellRendererComponent(List list, Object value, int
                      index, boolean isSelected) {
       if(isSelected) {
          selectedRenderer.getListCellRendererComponent(list, value, index,
          // sometimes the list asks for a dummy selected value for size 
          // calculations and this might break the tickering state
          if(index == list.getSelectedIndex()) {
              if(selectedRenderer.shouldTickerStart()) {
                  if(!selectedRenderer.isTickerRunning()) {
                      parentList = list;
                                      getLookAndFeel().getTickerSpeed(), true);
           } else {
               if(selectedRenderer.isTickerRunning()) {
          return selectedRenderer;
      } else {
          return super.getListCellRendererComponent(list,value,index,                                                     isSelected);