7.4 Displaying Cell Elements


Swing gives the programmer the option to specify how each element in the list (called a cell ) should be displayed on the screen. The list itself maintains a reference to a cell renderer. Cell renderers are common in Swing components, including lists and combo boxes. Essentially, a cell renderer is a component whose paint( ) method is called each time the component needs to draw or redraw an element. To create a cell renderer, you need only to register a class that implements the ListCellRenderer interface. This registration can be done with the setCellRenderer( ) method of JList or JComboBox:

JList list = new JList( ); list.setCellRenderer(new myCellRenderer( ));

7.4.1 The ListCellRenderer Interface

The ListCellRenderer interface must be implemented by cell renderers for lists and combo boxes. It has only one method.

public abstract Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)

This method must return a Component that can be used to draw the cell given the five variables passed in. The JList argument is a reference to the list itself. value is the object within the list data that will be drawn in this cell. The index of the cell in the list is given by the argument index. isSelected tells the renderer if the cell is currently selected, and cellHasFocus tells the renderer if the cell currently has the input focus.

Occasionally, Swing calls this method with an index of -1, which is, of course, not a valid list index, and implementations must be able to return a valid renderer anyway. Situations in which you'd encounter this include combo boxes that are drawing user-entered custom values (since they're not present in the associated list, they have no index) and during UI layout, when the size of a typical list element is needed even if the list doesn't contain any values.

It may be necessary to set the preferred size of the component returned by the cell renderer before returning it so that the requesting list knows how large to paint the component. This can be done by calling the setPreferredSize( ) method on the component.

7.4.2 Implementing a Cell Renderer

Here are some classes we'll use with the Java Books example later in this chapter, including a BookEntry class that contains composite information stored in a book list and a custom renderer that draws each cell in a list of O'Reilly books by placing its title side-by-side with a small icon of its cover:

// BookEntry.java import javax.swing.ImageIcon; public class BookEntry {     private final String title;     private final String imagePath;     private ImageIcon image;     public BookEntry(String title, String imagePath) {         this.title = title;         this.imagePath = imagePath;     }     public String getTitle( ) { return title; }          public ImageIcon getImage( ) {         if (image == null) {             image = new ImageIcon(imagePath);         }         return image;     }     // Override standard toString method to give a useful result.     public String toString( ) { return title; } } // BookCellRenderer.java import javax.swing.*; import java.awt.*; public class BookCellRenderer extends JLabel implements ListCellRenderer {     private static final Color HIGHLIGHT_COLOR = new Color(0, 0, 128);     public BookCellRenderer( ) {         setOpaque(true);         setIconTextGap(12);     }     public Component getListCellRendererComponent(         JList list,         Object value,         int index,         boolean isSelected,         boolean cellHasFocus)     {         BookEntry entry = (BookEntry)value;         setText(entry.getTitle( ));         setIcon(entry.getImage( ));         if(isSelected) {             setBackground(HIGHLIGHT_COLOR);             setForeground(Color.white);         } else {             setBackground(Color.white);             setForeground(Color.black);         }         return this;     } }

Notice that each call to getListCellRendererComponent( ) returns the same instance. This is very important for performance. Creating a new instance each time the method is called would place needless strain on the system. Even if you need to return slightly different renderers under different circumstances, maintain a static pool of these distinct instances and reuse them.

Our custom cell renderer displays images similar to those in Figure 7-7. Before we put the O'Reilly books example together, however, we need to discuss the central list class in Swing: JList. We'll do that after a brief detour for DefaultListCellRenderer.

Figure 7-7. The ListCellRenderer results
figs/swng2.0707.gif

7.4.3 The DefaultListCellRenderer Class

Swing contains a default list cell renderer class used by JList whenever the programmer does not explicitly set a cell renderer. This class, DefaultListCellRenderer, implements the ListCellRenderer interface.

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)

This method returns a Component used to draw a default list cell. If isSelected is true, then the cell is drawn with the selectedBackground and selectedForeground properties defined in the list variable. If the cell is not selected, it uses the standard background and foreground colors of the list component. If the cell has focus, a UI-specific border (typically a 1-pixel LineBorder) is placed around the component. The cell renderer can handle both text and icons. If the value is text, the default font of the list is used.



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net