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 new Integer(row*col); }
};
JTable table = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(table);
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 JTable.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 JTable.print()
methods allow for quick
and easy addition of printing support to your application. In addition, a new
JTable.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 JavaBeansTM
has been added to the java.beans
package.
Please see XMLEncoder
.