Introduction to Java Programming-Comprehensive Version (6th Edition)
31.5. Table Renderers and Editors
Table cells are painted by cell renderers. By default, a cell object's string representation ( toString() ) is displayed and the string can be edited as it was in a text field. JTable maintains a set of predefined renderers and editors, listed in Table 31.1, which can be specified to replace default string renderers and editors.
Table 31.1. Predefined Renderers and Editors for Tables
Class | Renderer | Editor |
---|---|---|
Object | JLabel (left aligned) | JTextField |
Date | JLabel (right aligned) | JTextField |
Number | JLabel (right aligned) | JTextField |
ImageIcon | JLabel (center aligned) | |
Boolean | JCheckBox (center aligned) | JCheckBox (center aligned) |
The predefined renderers and editors are automatically located and loaded to match the class returned from the getColumnClass() method in the table model. To use a predefined renderer or editor for a class other than String , you need to create your own table model by extending a subclass of TableModel . In your table model class, you need to override the getColumnClass() method to return the class of the column, as follows :
public Class getColumnClass( int column) { return getValueAt( , column).getClass(); }
By default, all cells are editable. To prohibit a cell from being edited, override the isCellEditable(int rowIndex, int columnIndx) method in TableModel to return false . By default, this method returns true in AbstractTableModel .
To demonstrate predefined table renderers and editors, let us write a program that displays a table for books. The table consists of three rows with the column names Title, Copies Needed, Publisher, Date Published, In-Stock, and Book Photo, as shown in Figure 31.13. Assume that dates and icons are not editable; prohibit users from editing these two columns .
Figure 31.13. You need to use a custom table model to enable predefined renderers for Boolean and image cells.
(This item is displayed on page 1061 in the print version)
Listing 31.6 gives a custom table model named MyTableModel that overrides the getColumnClass method (lines 15 “17) to enable predefined renderers for Boolean and image cells. MyTableModel also overrides the isCellEditable() method (lines 20 “24). By default, isCellEditable() returns true . The example does not allow the user to edit image icons and dates, so this method is overridden to return false to disable editing of date and image columns. For a cell to be editable, both isCellEditable() in the table model and isEditing in JTable class must be true .
Listing 31.6. MyTableModel.java
1 import javax.swing.*; 2 import javax.swing.table.*; 3 import java.util.*; 4 5 public class MyTableModel extends DefaultTableModel { 6 public MyTableModel() { 7 } 8 9 /** Construct a table model with specified data and columnNames */ 10 public MyTableModel(Object[][] data, Object[] columnNames) { 11 super (data, columnNames); 12 } 13 14 /** Override this method to return a class for the column */ 15 public Class getColumnClass( int column) { 16 return getValueAt( , column).getClass(); 17 } 18 19 /** Override this method to return true if cell is editable */ 20 public boolean isCellEditable( int row, int column) { 21 Class columnClass = getColumnClass(column); 22 return columnClass != ImageIcon. class && 23 columnClass != Date. class ; 24 } 25 }
|
If you create a JTable using a table model created from MyTableModel , the default renderers and editors for numbers , Boolean values, dates, and icons are used to display and edit these columns. Listing 31.7 gives a test program. The program creates a table model using MyTableModel (line 36). JTable assigns a predefined cell renderer and a predefined editor to the cell, whose class is specified in the getColumnClass() method in MyTableModel .
Listing 31.7. TableCellRendererEditorDemo.java
(This item is displayed on pages 1061 - 1062 in the print version)
1 import java.awt.*; 2 import javax.swing.*; 3 import java.util.*; 4 5 public class TableCellRendererEditorDemo extends JApplet { 6 // Create table column names 7 private String[] columnNames = 8 { "Title" , "Copies Needed" , "Publisher" , "Date Published" , 9 "In-stock" , "Book Photo" }; 10 11 // Create image icons 12 private ImageIcon intro1eImageIcon = new ImageIcon( 13 getClass().getResource( "image/intro1e.gif" )); 14 private ImageIcon intro2eImageIcon = new ImageIcon( 15 getClass().getResource( "image/intro2e.gif" )); 16 private ImageIcon intro3eImageIcon = new ImageIcon( 17 getClass().getResource( "image/intro3e.jpg" )); 18 19 // Create table data 20 private Object[][] rowData = { 21 { "Introduction to Java Programming" , 120 , 22 "Que Education & Training" , 23 new GregorianCalendar( 1998 , 1-1 , 6 ).getTime(), 24 false , intro1eImageIcon}, 25 { "Introduction to Java Programming, 2E" , 220 , 26 "Que Education & Training" , 27 new GregorianCalendar( 1999 , 1-1 , 6 ).getTime(), 28 false , intro2eImageIcon}, 29 { "Introduction to Java Programming, 3E" , 220 , 30 "Prentice Hall" , 31 new GregorianCalendar( 2000 , 12-1 , ).getTime(), 32 true , intro3eImageIcon}, 33 }; 34 35 // Create a table model 36 private MyTableModel tableModel = new MyTableModel( 37 rowData, columnNames); 38 39 // Create a table 40 private JTable jTable1 = new JTable(tableModel); 41 42 public TableCellRendererEditorDemo() { 43 jTable1.setRowHeight( 60 ); 44 add( new JScrollPane(jTable1) , 45 BorderLayout.CENTER); 46 } 47 }
|
The example creates two classes: MyTableModel and TableCellRendererEditorDemo . MyTableModel is an extension of DefaultTableModel . The purpose of MyTableModel is to override the default implementation of the getColumnClass() method to return the class of the column, so that an appropriate predefined JTable can be used for the column. By default, getColumnClass() returns Object.class .