The
JTable
is used to display and edit regular two-dimensional tables of cells. See
How to Use Tables in
The Java Tutorial for task-oriented documentation and examples of using
JTable
.
The JTable
has many facilities that make it possible to customize its rendering and editing but provides defaults for these features so that simple tables can be set up easily. For example, to set up a table with 10 rows and 10 columns of numbers:
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return Integer.valueOf(row*col); }
};
JTable table = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(table);
JTable
s are typically placed inside of a JScrollPane
. By default, a JTable
will adjust its width such that a horizontal scrollbar is unnecessary. To allow for a horizontal scrollbar, invoke setAutoResizeMode(int)
with AUTO_RESIZE_OFF
. Note that if you wish to use a JTable
in a standalone view (outside of a JScrollPane
) and want the header displayed, you can get it using getTableHeader()
and display it separately.
To enable sorting and filtering of rows, use a RowSorter
. You can set up a row sorter in either of two ways:
- Directly set the
RowSorter
. For example: table.setRowSorter(new TableRowSorter(model))
.
- Set the
autoCreateRowSorter
property to true
, so that the JTable
creates a RowSorter
for you. For example: setAutoCreateRowSorter(true)
.
When designing applications that use the JTable
it is worth paying close attention to the data structures that will represent the table's data. The DefaultTableModel
is a model implementation that uses a Vector
of Vector
s of Object
s to store the cell values. As well as copying the data from an application into the DefaultTableModel
, it is also possible to wrap the data in the methods of the TableModel
interface so that the data can be passed to the JTable
directly, as in the example above. This often results in more efficient applications because the model is free to choose the internal representation that best suits the data. A good rule of thumb for deciding whether to use the AbstractTableModel
or the DefaultTableModel
is to use the AbstractTableModel
as the base class for creating subclasses and the DefaultTableModel
when subclassing is not required.
The "TableExample" directory in the demo area of the source distribution gives a number of complete examples of JTable
usage, covering how the JTable
can be used to provide an editable view of data taken from a database and how to modify the columns in the display to use specialized renderers and editors.
The JTable
uses integers exclusively to refer to both the rows and the columns of the model that it displays. The JTable
simply takes a tabular range of cells and uses getValueAt(int, int)
to retrieve the values from the model during painting. It is important to remember that the column and row indexes returned by various JTable
methods are in terms of the JTable
(the view) and are not necessarily the same indexes used by the model.
By default, columns may be rearranged in the JTable
so that the view's columns appear in a different order to the columns in the model. This does not affect the implementation of the model at all: when the columns are reordered, the JTable
maintains the new order of the columns internally and converts its column indices before querying the model.
So, when writing a TableModel
, it is not necessary to listen for column reordering events as the model will be queried in its own coordinate system regardless of what is happening in the view. In the examples area there is a demonstration of a sorting algorithm making use of exactly this technique to interpose yet another coordinate system where the order of the rows is changed, rather than the order of the columns.
Similarly when using the sorting and filtering functionality provided by RowSorter
the underlying TableModel
does not need to know how to do sorting, rather RowSorter
will handle it. Coordinate conversions will be necessary when using the row based methods of JTable
with the underlying TableModel
. All of JTable
s row based methods are in terms of the RowSorter
, which is not necessarily the same as that of the underlying TableModel
. For example, the selection is always in terms of JTable
so that when using RowSorter
you will need to convert using convertRowIndexToView
or convertRowIndexToModel
. The following shows how to convert coordinates from JTable
to that of the underlying model:
int[] selection = table.getSelectedRows();
for (int i = 0; i < selection.length; i++) {
selection[i] = table.convertRowIndexToModel(selection[i]);
}
// selection is now in terms of the underlying TableModel
By default if sorting is enabled JTable
will persist the selection and variable row heights in terms of the model on sorting. For example if row 0, in terms of the underlying model, is currently selected, after the sort row 0, in terms of the underlying model will be selected. Visually the selection may change, but in terms of the underlying model it will remain the same. The one exception to that is if the model index is no longer visible or was removed. For example, if row 0 in terms of model was filtered out the selection will be empty after the sort.
J2SE 5 adds methods to JTable
to provide convenient access to some common printing needs. Simple new print()
methods allow for quick and easy addition of printing support to your application. In addition, a new getPrintable(javax.swing.JTable.PrintMode, java.text.MessageFormat, java.text.MessageFormat)
method is available for more advanced printing needs.
As for all JComponent
classes, you can use InputMap
and ActionMap
to associate an Action
object with a KeyStroke
and execute the action under specified conditions.
Warning: Swing is not thread safe. For more information see Swing's Threading Policy .
Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeans has been added to the java.beans
package. Please see XMLEncoder
.
new JScrollPane(aTable)
.