Introduction to Java Programming-Comprehensive Version (6th Edition)

 

[Page 1032 ( continued )]

30.9. List Cell Renderer

The preceding example displays items as strings in a list. JList is very flexible and versatile, and it can be used to display images and GUI components in addition to simple text. This section introduces list cell renderers for displaying graphics.

In addition to delegating data storage and processing to list models, JList delegates the rendering of list cells to list cell renderers. All list cell renderers implement the ListCellRenderer interface, which defines a single method, getListCellRendererComponent , as follows :

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

This method is passed with a list, the value associated with the cell, the index of the value, and information regarding whether the value is selected and whether the cell has the focus. The component returned from the method is painted on the cell in the list. By default, JList uses DefaultListCellRenderer to render its cells. The DefaultListCellRenderer class implements ListCellRenderer , extends JLabel , and can display either a string or an icon, but not both in the same cell.

For example, you can use JList 's default cell renderer to display strings, as shown in Figure 30.22(a), using the following code:

JList list = new JList( new String[]{ "Denmark" , " Germany " , "China" , "India" , "Norway" , "UK" , "US" });

Figure 30.22. The cell renderer displays list items in a list.

You can use JList 's default cell renderer to display icons, as shown in Figure 30.22(b), using the following code:

ImageIcon denmarkIcon = new ImageIcon(getClass().getResource( "image/denmarkIcon.gif" )); ... JList list = new JList( new ImageIcon[]{denmarkIcon, germanyIcon, chinaIcon, indiaIcon, norwayIcon, ukIcon, usIcon});

How do you display a string along with an icon in one cell, as shown in Figure 30.22(c)? You need to create a custom renderer by implementing ListCellRenderer , as shown in Figure 30.23.


[Page 1033]
Figure 30.23. ListCellRenderer defines how cells are rendered in a list.

Suppose a list is created as follows:

JList list = new JList( new Object[][]{{denmarkIcon, "Denmark" }, {germanyIcon, "Germany" }, {chinaIcon, "China" }, {indiaIcon, "India" }, {norwayIcon, "Norway" }, {ukIcon, "UK" }, {usIcon, "US" }});

Each item in the list is an array that consists of an icon and a string. You can create a custom cell renderer that retrieves an icon and a string from the list data model and displays them in a label. The custom cell renderer class is given in Listing 30.9.

Listing 30.9. MyListCellRenderer.java

1 import java.awt.*; 2 import javax.swing.*; 3 import javax.swing.border.*; 4 5 public class MyListCellRenderer implements ListCellRenderer { 6 private JLabel jlblCell = new JLabel( " " , JLabel.LEFT); 7 private Border lineBorder = 8 BorderFactory.createLineBorder(Color.black, 1 ); 9 private Border emptyBorder = 10 BorderFactory.createEmptyBorder( 2 , 2 , 2 , 2 ); 11 12 /** Implement this method in ListCellRenderer */ 13 public Component getListCellRendererComponent 14 (JList list, Object value, int index, boolean isSelected, 15 boolean cellHasFocus) { 16 Object[] pair = (Object[])value; // Cast value into an array 17 jlblCell.setOpaque( true ); 18 jlblCell.setIcon((ImageIcon)pair[ ]); 19 jlblCell.setText(pair[ 1 ].toString()); 20 21 if (isSelected) { 22 jlblCell.setForeground(list.getSelectionForeground()); 23 jlblCell.setBackground(list.getSelectionBackground()); 24 } 25 else { 26 jlblCell.setForeground(list.getForeground()); 27 jlblCell.setBackground(list.getBackground()); 28 } 29 30 jlblCell.setBorder(cellHasFocus ? lineBorder : emptyBorder); 31 32 return jlblCell; 33 } 34 }

The MyListCellRenderer class implements the getListCellRendererComponent method in the ListCellRenderer interface. This method is passed with the parameters list , value , index , isSelected , and isFocused (lines 13 “15). The value represents the current item value. In this case, it is an array consisting of two elements. The first element is an image icon (line 18). The second element is a string (line 19). Both image icon and string are displayed on a label. The getListCellRendererComponent method returns the label (line 32), which is painted on the cell in the list.


[Page 1034]

If the cell is selected, the background and foreground of the cell are set to the list's selection background and foreground (lines 22 “23). If the cell is focused, the cell's border is set to the line border (line 30); otherwise , it is set to the empty border (line 39). The empty border serves as a divider between the cells.

Note

The example in Listing 30.9 uses a JLabel as a renderer. You may use any GUI component as a renderer, returned from the getListCellRendererComponent method.

Let us develop an example that creates a list of countries and displays the flag image and name for each country as one item in the list, as shown in Figure 30.24. When a country is selected in the list, its flag is displayed in a label next to the list.

Figure 30.24. The image and the text are displayed in the list cell.

Two types of icons are used in this program. The small icons are created from files flagIcon0.gif , ..., flagIcon6.gif (lines 31 “32). The small icons are rendered inside the list. The large icons are created from files flag0.gif , ..., flag6.gif (lines 35 “36) and are displayed on a label on the right side of the split pane. Listing 30.10 gives the program.

Listing 30.10. ListCellRendererDemo.java

(This item is displayed on pages 1034 - 1035 in the print version)

1 import javax.swing.*; 2 import javax.swing.event.*; 3 import java.awt.*; 4 5 public class ListCellRendererDemo extends JApplet { 6 private final static int NUMBER_OF_NATIONS = 7 ; 7 private String[] nations = new String[] 8 { "Denmark" , "Germany" , "China" , "India" , "Norway" , "UK" , "US" }; 9 private ImageIcon[] icons = new ImageIcon[NUMBER_OF_NATIONS]; 10 private ImageIcon[] bigIcons = new ImageIcon[NUMBER_OF_NATIONS]; 11 12 // Create a list model 13 private DefaultListModel listModel = new DefaultListModel(); 14 15 // Create a list using the list model 16 private JList jlstNations = new JList(listModel); 17 18 // Create a list cell renderer 19 private ListCellRenderer renderer = new MyListCellRenderer(); 20 21 // Create a split pane 22 private JSplitPane jSplitPane1 = new JSplitPane(); 23


[Page 1035]

24 // Create a label for displaying image 25 private JLabel jlblImage = new JLabel( "" , JLabel.CENTER); 26 27 /** Construct ListCellRenderer */ 28 public ListCellRendererDemo() { 29 // Load small and large image icons 30 for ( int i = ; i < NUMBER_OF_NATIONS; i++) { 31 icons[i] = new ImageIcon(getClass().getResource( 32 "image/flagIcon" + i + ".gif" )); 33 listModel.addElement( new Object[]{icons[i], nations[i]}); 34 35 bigIcons[i] = new ImageIcon(getClass().getResource( 36 "image/flag" + i + ".gif" )); 37 } 38 39 // Set list cell renderer 40 jlstNations.setCellRenderer(renderer); 41 jlstNations.setPreferredSize( new Dimension( 200 , 200 )); 42 jSplitPane1.setLeftComponent( new JScrollPane(jlstNations)); 43 jSplitPane1.setRightComponent(jlblImage); 44 jlstNations.setSelectedIndex( ); 45 jlblImage.setIcon(bigIcons[ ]); 46 add(jSplitPane1, BorderLayout.CENTER); 47 48 // Register listener 49 jlstNations.addListSelectionListener( new ListSelectionListener() { 50 public void valueChanged(ListSelectionEvent e) { 51 jlblImage.setIcon(bigIcons[jlstNations.getSelectedIndex()]); 52 } 53 }); 54 } 55 }

Two types of icons are used in this program. The small icons are created from files flagIcon0.gif , ..., flagIcon6.gif (lines 31 “32). These image files are the flags for Denmark, Germany, China, India, Norway, UK, and US. The small icons are rendered inside the list. The large icons for the same countries are created from files flag0.gif , ..., flag6.gif (lines 35 “36) and are displayed on a label on the right side of the split pane.

The ListCellRendererDemo class creates a list model (line 13) and adds the items to the model (line 33). Each item is an array of two elements (image icon and string). The list is created using the list model (line 16). The list cell renderer is created (line 19) and associated with the list (line 40).

The ListCellRendererDemo class creates a split pane (line 22) and places the list on the left (line 42) and a label on the right (line 43).

When you choose a country in the list, the list-selection event handler is invoked (lines 49 “53) to set a new image to the label in the right side of the split pane (line 51).

 

Категории