I have a JTable in my GUI, which I wish to update dynamically. Associated to the Jtable is of course a TableModel, where I've extended the AbstractTableModel and overridden appropiate methods.
I have four methods for my JTable:
- AddRow
- CopySelectedRow
- DeleteSelectedRow
- DeleteAll
When I run either AddRow or CopySelectedRow the table is 'one update behind':
If I press newRow once, nothing happens visually.
If I press newRow twice, the first one is shown while the second isn't.
However, using deleteSelected or deleteAll updates the table when I click (i.e. not behind).
Extract of my TableModel class:
public class TableModel extends AbstractTableModel {
private List<String[]> data;
public TableModel() {
data = new ArrayList<String[]>();
}
...
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
data.get(rowIndex)[columnIndex] = aValue.toString();
fireTableCellUpdated(rowIndex, columnIndex);
}
public void addRow(String[] aValue) {
data.add(aValue);
fireTableRowsInserted(data.size()-1, data.size()-1);
}
public void copyRow(int rowIndex) {
addRow(data.get(rowIndex));
}
public void removeRow(int rowIndex) {
data.remove(rowIndex);
fireTableRowsDeleted(rowIndex, rowIndex);
}
And how I call them:
JButton newRow = new JButton("New row");
newRow.addActionListener(new ActionListener() {
// Handling newRow event
public void actionPerformed(ActionEvent e) {
tableModel.addRow(new String[]{"", "", "", "", "", "", "", "", "", "", ""});
}
});
JButton copyRow = new JButton("Copy selected row");
copyRow.addActionListener(new ActionListener() {
// Handling copyRow event
public void actionPerformed(ActionEvent e) {
if (table.getSelectedRow() != -1) {
tableModel.copyRow(table.getSelectedRow());
}
}
});
JButton deleteRow = new JButton("Delete selected row");
deleteRow.addActionListener(new ActionListener() {
// Handling deleteRow event
public void actionPerformed(ActionEvent e) {
if (table.getSelectedRow() != -1) {
tableModel.removeRow(table.getSelectedRow());
}
}
});
JButton deleteAllRows = new JButton("Delete all rows");
deleteAllRows.addActionListener(new ActionListener() {
// Handling deleteAllRows event
public void actionPerformed(ActionEvent e) {
for (int i = tableModel.getRowCount() - 1; i >= 0; i--) {
tableModel.removeRow(i);
}
}
});
EDIT:
I chose to use an AbstractTableModel because I had the same problem with the DefaultTableModel (whenever I added a row, it wasn't added until the next was 'added'), and with an AbstractTableModel I would be able to fire change events myself. However, it didn't fix a thing. Can anyone please shed some light on my issue here? I'd be happy to elaborate more on the case, should anyone need some more information.