Are there any good books or website that go over creating a JTable
? I want to make one column editable. I would like to actually put a inherited JCheckBox
This tutorial from the java lobby is easy to follow. The online Swing trail for JTable that you reference indicates that it has been updated. Did you scan through the whole thing for possible better (isn't newer always better) information?
To make a column editable you have to override the isCellEditable
method in the TableModel
. Creating a TableModel
is fairly easy if you inherit AbstractTableModel
and I'd recommend it for all but the most simple JTable
s.
However, adapting the TableModel
is only part of what you need to do. To actually get a custom component in the JTable
, you need to set a custom cell renderer. To use an interactive custom component, you need to set a custom cell editor. In some cases, it's enough to use slightly modificated versions of the default classes for this.
Editors
If you already have got a custom component is easily done using delegation: Create a new class implementing TableCellEditor
, and return a new instance of the component in the getCellEditorComponent
method. The paramaters to this method include the current value as well as the cell coordinates, a link back to the table and wether or not the cell is selected.
The TableCellEditor
also has a method that is called when the user commits a change to the cell contents (where you can validate user input and adjust the model) or cancels an edit. Be sure to call the stopEditing()
method on your editor if you ever programmatically abort editing, otherwise the editor component will remain on screen -- this once took me like 2 hours to debug.
Note that within a JTable
editors and only editors receive events! Displaying a button can be done using a renderer. But to get a functioning button, you need to implement an editor with the correct EventListeners
registered. Registering a listener on a renderer does nothing.
Renderers
Implementing a renderer is not strictly necessary for what you describe in your question, but you typically end up doing it anyway, if only for minor modifications. Renderers, unlike editors, are speed critical. The getTableCellRendererComponent
of a renderer is called once for every cell in the table! The component returned by a renderer is only used to paint the cell, not for interaction, and thus can be "reused" for the next cell. In other words, you should adjust the component (e.g. using setText(...)
or setFont(...)
if it is a TextComponent
) in the renderer, you should not instantiate a new one -- that's an easy way to cripple the performance.
Caveats
Note that for renderers and editors to work, you need to tell the JTable
when to use a certain renderer/editor. There are basically two ways to do this. You can set the default cell renderer/editor for a certain type using the respective JTable
methods. For this way to work, your TableModel
needs to return exactly this type in the getColumnClass(...)
method! The default table model will not do this for you, it always returns Object.class
. I'm sure that one has stumped a lot of people.
The other way to set the editor/renderer is by explicitly setting it on the column itself, that is, by getting the TableColumn
via the getTableColumn(...)
method of the JTable
. This is a lot more elaborate, however, it's also the only way to have two different renderers/editors for a single class. E.g. your model might have two columns of class String which are rendered in entirely different ways, maybe once using a JLabel/DefaultRenderer
and the other using a JButton
to access a more elaborate editor.
JTable
with its custom renderers and editors is extremely versatile, but it is also a lot to take in, and there are a lot of things to do wrong. Good luck!
How to Use Tables in The Swing Tutorial is mandatory reading for anyone customising JTables. In particular, read and reread Concepts: Editors and Renderers because it typically takes a while for it to "click". The examples on custom renderers and editors are also very worthwhile.
Some useful classes are:
Package javax.swing.table
:
TableModel
- Interface for a tablemodel
AbstractTableModel
- Nice class to extend for creating your own table with custom data structures
DefaultTableModel
- Default table model which can deal with arrays[]
and Vectors
To disable editing on any cell you need to override the isCellEditable(int row, int col)
method
in your table Model, you should override "isCellEditable" and "setValueAt" functions, like below.
Column 4 is the column for editable cells.
Then when you double click the cell and type something,
setValueAt() will be called and save the value to the tableModel's DO,field col4.
public ArrayList<XXXDO> tbmData = new ArrayList<XXXDO>(); //arraylist for data in table
@Override
public boolean isCellEditable(int row, int col) {
if (col == 4) {
return true;
} else {
return false;
}
}
@Override
public void setValueAt(Object value, int row, int col) {
if ((row >= 0) && (row < this.tbmData.size()) && (col >= 0) && (col < this.colNm.length)) {
if (col == 4) {
tbmData.get(row).col4= (String) value;
}
fireTableCellUpdated(row, col);
} else {
}
}
The class you want to look into extending to create your own behavior is DefaultTableModel. That will allow you to define your own behavior. A decent tutorial can be found on sun's site.
If you are trying to use a simple JTable
with 1 column editable and you know the column location you could always use default table model and overload the isCellEditable
call.
something like this :
myTable.setModel(new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
if (column == x) {
return true;
} else
return false;
}
});
And for the check box create a renderer class
MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer