Chapter 10 JList, JComboBox, and Bound Controls
- In This Chapter
- Rubber Stamp Drawing
- Using the JList Class
- Combo Boxes
- Bounded Components
- The JSlider Control
The JList and JComboBox classes create components that allow the user to select from a list of choices. The data models for these two classes are very similar. In fact, the ComboBoxModel interface extends the ListModel interface, adding methods to set and query a selected item.
The JList and JComboBox classes introduce you to the rendering portion of the Swing component architecture. When the items in a list or combo box are painted, the component itself doesnt do the painting. Instead, the painting is delegated to a renderer object. A single renderer can paint the entire component.
The JFC contains the BoundedRangeModel interface, which constrains an integer value between a minimum and maximum value. This data model is used by a number of classes in the JFC, most of which are presented in this chapter.
This chapter will introduce a number of new JFC classes and data models. You will learn:
- Rendered drawing
- How to use the JList class
- How to use the JComboBox class
- How to use the BoundedRangeModel interface
- How to use the JScrollBar class
- How to use the JSlider class
- How to use the JProgressBar class
Rubber Stamp Drawing
Complex controls such as lists can contain thousands of items to display. Creating a JLabel, or another component, to display each item in the list would be too resource-intensive to be practical. However, it would be nice to be able to independently configure each item in the list for display.
The JFC solution to this dilemma is to use a rendering component to visualize an item in the list. When the list needs to paint an item, the renderer is moved to the location where the item in the list needs to be displayed, sized correctly, and configured for the current item. Finally, the renderer paints the item. A stock JList instance uses an instance of the DefaultListRenderer class (which itself is an extension of the JLabel class) to visualize its items. However, a custom renderer can be added to the list to achieve any visual effect required. As you progress through this section, you will see that many JFC components employ a rendering component for visualization (the JTree and JTable classes discussed in the next two chapters, to name a few).
The ListCellRenderer Interface
The methods that define a rendering entity for instances of the JList class are defined in the ListCellRenderer interface, shown in Listing 10.1. As such, any class can implement this interface and act as a renderer for a list. In practice, however, the majority of renderers used are extensions of the JLabel class and implement the ListCellRenderer interface.
The ListCellRenderer interface contains a single method: getListCellRendererComponent. When this method is called, the renderer must configure the component that will render the value object passed to the method. The list where the item is being drawn is passed to this method. This way, if a renderer needs to know which list it is rendering, it does not need to keep a reference to the list, allowing a single renderer to be shared between any number of lists. The current state of the item in the list is also passed to the getListCellRendererComponent method. This allows the renderer to give visually distinct characteristics to selected items and items with the input focus. After the renderer has configured the component, it returns it to the caller.
The renderer should not create a new component instance each time the getListCellRendererComponent method is called. Instead, one component should be created and reconfigured with the current list item on each call. As previously mentioned, many times the renderer is itself a component. In that case, the renderer configures itself in the getListCellRendererComponent method and returns this from the method.
Listing 10.1 The ListCellRenderer Interface
public interface ListCellRenderer
{
/**
* Return a component that has been configured to display the
* specified value. That components <code>paint</code> method is
* then called to render the cell. If it is necessary to compute
* the dimensions of a list because the list cells do not have a
* fixed size, this method is called to generate a component on which
* <code>getPreferredSize</code> can be invoked.
*
* @param list The JList were painting.
* @param value The value returned by
* list.getModel().getElementAt(index).
* @param index The cells index.
* @param isSelected True if the specified cell was selected.
* @param cellHasFocus True if the specified cell has the focus.
* @return A component whose paint() method will render the
* specified value.
*
* @see JList
* @see ListSelectionModel
* @see ListModel
*/
Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus);
}
|