数据改变后重新加载 JTable 的 Object[][]

Posted

技术标签:

【中文标题】数据改变后重新加载 JTable 的 Object[][]【英文标题】:Reload JTable's Object[][] after data has changed 【发布时间】:2015-01-19 16:28:12 【问题描述】:

我想知道当最初填充表格的Object[][] 发生变化时,是否可以刷新表格的 GUI。

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() 在 x 对象已更改以重新填充 calculationsTableData 时调用

repaint()revalidate() 方法在这种情况下似乎无效,fireTableDataChanged() 也无效,因为这不是表模型。

【问题讨论】:

【参考方案1】:

默认情况下,JTable 创建一个新的 DefaultTableModel 实例 AbstractTableModel [1] 实现如果没有明确的表模型放。如果需要更新表格,您必须使用其模型。

你可以...

设置一个新的DefaultTableModel:

void populateCalculationsTableData() 
    ...
    calculationsTableData = temp;
    TableModel model = new DefaultTableModel(calculationsTableData, calculationsColumnNames);
    calculationsTable.setModel(model);

或者你可以...

使用DefaultTableModel 创建表:

TableModel model = new DefaultTableModel(calculationsTableData, calculationsColumnNames);
calculationsTable = new JTable(model);

将表模型转换为DefaultTableModel,并将其数据和列设置如下:

void populateCalculationsTableData() 
    ...
    calculationsTableData = temp;
    DefaultTableModel model = (DefaultTableModel)calculationsTable.getModel();
    model.setDataVector(calculationsTableData, calculationsColumnNames);

建议阅读

JTable(Object[][] rowData, Object[] columnNames) DefaultTableModel#setDataVector(Object[][] dataVector, Object[] columnIdentifiers) How to Use Tables

[1]:检查JTable(Object[][] rowData, Object[] columnNames) 源代码后,我意识到没有创建DefaultTableModel,而是从AbstractTableModel 扩展了一个新的匿名内部类而是。

【讨论】:

【参考方案2】:

我会创建您自己的表模型来包装对象数组,并公开 fireTableDataChanged() 方法:

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);
    

...当数据发生变化时,您应该能够对此调用 fireTableDataChanged(),它会通知需要重绘自身的表。

【讨论】:

以上是关于数据改变后重新加载 JTable 的 Object[][]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JTable/JXTable 中设置列​​宽?

JTable 不会在将数据插入 mysql 时重新绘制/刷新

背景排序JTable后,特定值的颜色不会改变

JAVA中的JTable如何在显示的时候默认选择到第一行

即使在过滤时重新加载商店后网格也不会改变

在 jTable 中选择一行会产生错误