I l@ve RuBoard |
![]() ![]() |
7.4 Displaying Cell ElementsSwing 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 InterfaceThe ListCellRenderer interface must be implemented by cell renderers for lists and combo boxes. It has only one method.
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 RendererHere 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![]() 7.4.3 The DefaultListCellRenderer ClassSwing 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.
|
I l@ve RuBoard |
![]() ![]() |