JTable is a Swing component that displays data in rows and columns in a two-dimensional grid, as shown in Figure 31.1.
JTable doesn't directly support scrolling. To create a scrollable table, you need to create a JScrollPane and add an instance of JTable to the scroll pane. If a table is not placed in a scroll pane, its column header will not be visible, because the column header is placed in the header of the view port of a scroll pane.
JTable has three supporting models: a table model, a column model, and a list-selection model. The table model is for storing and processing data. The column model represents all the columns in the table. The list-selection model is the same as the one used by JList for selecting rows, columns, and cells in a table. JTable also has two useful supporting classes, TableColumn and JTableHeader . TableColumn contains the information on a particular column. JTableHeader contains the information on the header of a JTable . Each column has a default editor and renderer. You can also create a custom editor by implementing the TableCellEditor interface, and create a custom renderer by implementing the TableCellRenderer interface. The relationship of these interfaces and classes is shown in Figure 31.2.
Note
All the supporting interfaces and classes for JTable are grouped in the javax.swing.table package. |
Figure 31.3 shows the constructors, properties, and methods of JTable .
The JTable class contains seven constructors for creating tables. You can create a table using its no-arg constructor, its models, row data in a two-dimensional array, and column header names in an array, or row data and column header names in vectors. Listing 31.1 creates a table with the row data and column names (line 20) and places it in a scroll pane (line 24). The table is displayed in Figure 31.1.
1 import javax.swing.*; 2 3 public class TestTable extends JApplet { 4 // Create table column names 5 String[] columnNames = 6 { "Country" , "Capital" , "Population in Millions" , "Democracy" }; 7 8 // Create table data 9 Object[][] data = { 10 { "USA" , "Washington DC" , 280 , true }, 11 { "Canada" , "Ottawa" , 32 , true }, 12 { "United Kingdom" , "London" , 60 , true }, 13 { "Germany" , "Berlin" , 83 , true }, 14 { "France" , "Paris" , 60 , true }, 15 { "Norway" , "Oslo" , 4.5 , true }, 16 { "India" , "New Deli" , 1046 , true } 17 }; 18 19 // Create a table 20 JTable jTable1 = new JTable(data, columnNames); 21 22 public TestTable() { 23 add( new JScrollPane(jTable1)); 24 } 25 } |
Note
Primitive type values such as 280 and true in line 10 are autoboxed into new Integer(280) and new Boolean(true) . |
JTable is a powerful control with a variety of properties that provide many ways to customize tables. All the frequently used properties are documented in Figure 31.3. The autoResizeMode property specifies how columns are resized (you can resize table columns but not rows). Possible values are:
JTable.AUTO_RESIZE_OFF JTable.AUTO_RESIZE_LAST_COLUMN JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS JTable.AUTO_RESIZE_NEXT_COLUMN JTable.AUTO_RESIZE_ALL_COLUMNS
The default mode is JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS . Initially, each column in the table occupies the same width (75 pixels). With AUTO_RESIZE_OFF , resizing a column does not affect the widths of the other columns. With AUTO_RESIZE_LAST_COLUMN , resizing a column affects the width of the last column. With AUTO_RESIZE_SUBSEQUENT_COLUMNS , resizing a column affects the widths of all the subsequent columns. With AUTO_RESIZE_NEXT_COLUMN , resizing a column affects the widths of the next columns. With AUTO_RESIZE_ALL_COLUMNS , resizing a column affects the widths of all the columns.
Listing 31.2 gives an example that demonstrates the use of several JTable properties. The example creates a table and allows the user to choose an Auto Resize Mode, specify the row height and margin, and indicate whether the grid is shown. A sample run of the program is shown in Figure 31.4.
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 import javax.swing.event.*; 5 6 public class TablePropertiesDemo extends JApplet { 7 // Create table column names 8 private String[] columnNames = 9 { "Country" , "Capital" , "Population in Millions" , "Democracy" }; 10 11 // Create table data 12 private Object[][] rowData = { 13 { "USA" , "Washington DC" , 280 , true }, 14 { "Canada" , "Ottawa" , 32 , true }, 15 { "United Kingdom" , "London" , 60 , true }, 16 { "Germany" , "Berlin" , 83 , true }, 17 { "France" , "Paris" , 60 , true }, 18 { "Norway" , "Oslo" , 4.5 , true }, 19 { "India" , "New Deli" , 1046 , true } 20 }; 21 22 // Create a table 23 private JTable jTable1 = new JTable(rowData, columnNames); 24 25 // Create two spinners 26 private JSpinner jspiRowHeight = 27 new JSpinner( new SpinnerNumberModel( 16 , 1 , 50 , 1 )); 28 private JSpinner jspiRowMargin = 29 new JSpinner( new SpinnerNumberModel( 1 , 1 , 50 , 1 )); 30 31 // Create a checkbox 32 private JCheckBox jchkShowGrid = new JCheckBox( "showGrid" , true ); 33 34 // Create a combo box 35 private JComboBox jcboAutoResizeMode = new JComboBox( new String[]{ 36 "AUTO_RESIZE_OFF" , "AUTO_RESIZE_LAST_COLUMN" , 37 "AUTO_RESIZE_SUBSEQUENT_COLUMNS" , "AUTO_RESIZE_NEXT_COLUMN" , 38 "AUTO_RESIZE_ALL_COLUMNS" }); 39 40 public TablePropertiesDemo() { 41 JPanel panel1 = new JPanel(); 42 panel1.add( new JLabel( "rowHeight" )); 43 panel1.add(jspiRowHeight); 44 panel1.add( new JLabel( "rowMargin" )); 45 panel1.add(jspiRowMargin); 46 panel1.add(jchkShowGrid); 47 48 JPanel panel2 = new JPanel(); 49 panel2.add( new JLabel( "autoResizeMode" )); 50 panel2.add(jcboAutoResizeMode); 51 52 add(panel1, BorderLayout.SOUTH); 53 add(panel2, BorderLayout.NORTH); 54 add( new JScrollPane(jTable1)); 55 56 // Initialize jTable1 57 jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 58 jTable1.setGridColor(Color.BLUE); 59 jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 60 jTable1.setSelectionBackground(Color.RED); 61 jTable1.setSelectionForeground(Color.WHITE); 62 63 // Register and create a listener for jspiRowHeight 64 jspiRowHeight.addChangeListener( new ChangeListener() { 65 public void stateChanged(ChangeEvent e) { 66 jTable1.setRowHeight ( 67 ((Integer)(jspiRowHeight.getValue())).intValue()); 68 } 69 }); 70 71 // Register and create a listener for jspiRowMargin 72 jspiRowMargin.addChangeListener( new ChangeListener() { 73 public void stateChanged(ChangeEvent e) { 74 jTable1.setRowMargin ( 75 ((Integer)(jspiRowMargin.getValue())).intValue()); 76 } 77 }); 78 79 // Register and create a listener for jchkShowGrid 80 jchkShowGrid.addActionListener( new ActionListener() { 81 public void actionPerformed(ActionEvent e) { 82 jTable1.setShowGrid (jchkShowGrid.isSelected()); 83 } 84 }); 85 86 // Register and create a listener for jcboAutoResizeMode 87 jcboAutoResizeMode.addActionListener( new ActionListener() { 88 public void actionPerformed(ActionEvent e) { 89 String selectedItem = 90 (String)jcboAutoResizeMode.getSelectedItem(); 91 92 if (selectedItem.equals( "AUTO_RESIZE_OFF" )) 93 jTable1.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); 94 else if (selectedItem.equals( "AUTO_RESIZE_LAST_COLUMN" )) 95 jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); 96 else if (selectedItem.equals 97 ( "AUTO_RESIZE_SUBSEQUENT_COLUMNS" )) 98 jTable1.setAutoResizeMode( 99 JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); 100 else if (selectedItem.equals( "AUTO_RESIZE_NEXT_COLUMN" )) 101 jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN); 102 else if (selectedItem.equals( "AUTO_RESIZE_ALL_COLUMNS" )) 103 jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 104 } 105 }); 106 } 107 } |
If you know the row data in advance, creating a table using the constructor JTable(Object[][] rowData, Object[] columnNames) is convenient . As shown in line 23, a JTable is created using this constructor.
Two JSpinner objects ( jspiRowHeight , jspiRowMargin ) for selecting row height and row margin are created in lines 26 “29. The initial value for jspiRowHeight is set to 16 , which is the default property value for rowHeight . The initial value for jspiRowMargin is set to 1 , which is the default property value for rowMargin . A check box ( jchkShowGrid ) is created with label showGrid and initially selected in line 32. A combo box for selecting autoResizeMode is created in lines 35 “38.
The values of the JTable properties ( autoResizeMode , gridColor , selectionMode , selectionBackground , and selectionForeground ) are set in lines 57 “61.
The code for processing spinners, check boxes, and combo boxes is given in lines 64 “105.