如何在数据和大小更改后刷新 table 模型

How to refresh table model after data and size change

我的项目是 MC、NC 或 Total Commander 等应用程序的简单实现。我将 2 JTables 与扩展 AbstractTableModel 的自定义模型一起使用,我的问题是用新数据和大小更新这些 tables。

每当我尝试用我的方法更新它时,我都会 运行 进入 ArrayIndexOutOfBoundsException,尽管我确保根据给定的参数重新创建具有新大小的数据数组。此外,如果我等待的时间足够长,我的 table 确实会正常刷新,但它经常断断续续,它的视图变得疯狂并且总体上无法使用,尽管它以某种奇怪、扭曲的方式工作。

这是我用来刷新 Table 模型的方法:

public class TableModel extends AbstractTableModel { 

private SimpleDateFormat df2 = new SimpleDateFormat("dd/MM/yyyy HH:mm");
private String[] fieldNames = {"Name", "Extension", "Size", "Time"};
private Object[][] data;

public void UpdateTable(String path)
{
    File[] list = (new File(path).listFiles());

    data = new Object[list.length][fieldNames.length];

    for(int i=0; i<list.length;i++)
    {   
        data[i][0] = list[i].getName();
        if (FilenameUtils.getExtension(list[i].getPath()) == "")
        {
            data[i][1] = "<dir>";
        }
        else{
            data[i][1] = FilenameUtils.getExtension(list[i].getPath());
        }
        data[i][2] = list[i].length();
        data[i][3] = df2.format(new Date(list[i].lastModified()));
    }
}
[...]

然后是 MainFrame class 的一部分,即从 actionListener 中调用该方法。

TableModel model1 = new TableModel(listRoots()[0]);
JTable table = new JTable(model1);
table.setShowGrid(false);
table.setIntercellSpacing(new Dimension(0, 0));
table.setFillsViewportHeight(true);
table.getTableHeader().setReorderingAllowed(false);
JScrollPane scrollPane = new JScrollPane(table);
pane.add(scrollPane, c);

//combo box's actionListener. Is supposed to work like it does in totalCommander
combo.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox)e.getSource();
        model1.UpdateTable(cb.getSelectedItem().toString());
        model1.fireTableDataChanged();
        table.repaint();
    }   
});

我已经尝试在我的更新方法或 SetValueAt() 中使用 "fireTableDataChanged()",但它并没有真正帮助或改变任何事情。

model1.fireTableDataChanged();

您的应用程序代码永远不应调用该方法。调用方法是自定义 TableModel 的工作

with custom model that extends AbstractTableModel

那你实现方法不对。

您为什么要创建自定义模型?您的模型没有什么特别之处。您可以只使用 DefaultTableModel 因为它支持对数据进行动态更改。

您的 updateTable(...) 方法可能类似于:

setRowCount(0);

for (...)
{
    Vector row = new Vector();
    row.addElement(...);
    row.addElement(...);
    addRow( row );
}

因此,您首先从模型中清除数据,然后一次一个地添加数据。添加每一行时,将自动调用适当的 fireXXX 方法。

您可以扩展 DefaultTableModel 以添加此方法,或仅将此作为您的 class 中的一个方法。

此外,方法名称不应以大写字符开头。 "UpdateTable(...)" 应该是 "updateTable(...)"`