Reputation: 13
I am wondering if it is possible to refresh a Table's GUI when the Object[][]
used to initially populate it has changed.
Object[][] calculationsTableData;
public Interface() {
...
analysisPanel.add(calculationsTable());
...
}
JScrollPane calculationsTable() {
populateCalculationsTableData();
...
calculationsTable = new JTable(calculationsTableData, calculationsColumnNames);
...
}
void populateCalculationsTableData(){
Object[][] temp = new Object[x.numsSize][7];
for (int i = 0; i < x.numsSize; i++) {
temp[i][0] = df.format(x.nums[i]);
...
}
calculationsTableData = temp;
}
populateCalculationsTableData()
is called when the x object has changed to repopulate calculationsTableData
repaint()
and revalidate()
methods do not appear to be effective in this scenario and neither does fireTableDataChanged()
as this is not a table model.
Upvotes: 1
Views: 1879
Reputation: 17971
By default JTable creates a new instance of AbstractTableModel [1] implementation if no table model is explicitely set. If the table needs to be updated you have to work with its model.DefaultTableModel
Set a new DefaultTableModel:
void populateCalculationsTableData() {
...
calculationsTableData = temp;
TableModel model = new DefaultTableModel(calculationsTableData, calculationsColumnNames);
calculationsTable.setModel(model);
}
Create the table using a DefaultTableModel
:
TableModel model = new DefaultTableModel(calculationsTableData, calculationsColumnNames);
calculationsTable = new JTable(model);
Cast the table model as DefaultTableModel
and set its data and columns like this:
void populateCalculationsTableData() {
...
calculationsTableData = temp;
DefaultTableModel model = (DefaultTableModel)calculationsTable.getModel();
model.setDataVector(calculationsTableData, calculationsColumnNames);
}
[1]: After checking JTable(Object[][] rowData, Object[] columnNames)
source code I've realized that no DefaultTableModel
is created but a new anonymous inner class extending from AbstractTableModel
instead.
Upvotes: 2
Reputation: 3809
I would create your own table model to wrap the object arrays, and which exposed the fireTableDataChanged() method:
private static class ObjectArrayModel extends AbstractTableModel {
private final Object[][] rowData;
private final Object[] columnNames;
private ObjectArrayModel(Object[][] rowData, Object[] columnNames) {
this.rowData = rowData;
this.columnNames = columnNames;
}
@Override
public void fireTableDataChanged() {
super.fireTableDataChanged();
}
public String getColumnName(int column) {
this.fireTableDataChanged();
return columnNames[column].toString();
}
public int getRowCount() {
return rowData.length;
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int row, int col) { return rowData[row][col]; }
public boolean isCellEditable(int row, int column) { return true; }
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = value;
fireTableCellUpdated(row, col);
}
}
... when the data changes you should be able to call fireTableDataChanged() on this and it will notify the table it needs to redraw itself.
Upvotes: 2