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

时间:2016-05-14 18:29:16

标签: java eclipse swing abstracttablemodel

我的项目是简单的应用程序,如MC,NC或Total Commander。我使用2个JTable和自定义模型扩展AbstractTableModel,我的问题是用新数据和大小更新这些表。

每当我尝试使用我的方法更新它时,我会遇到ArrayIndexOutOfBoundsException,尽管我确保根据给定的参数重新创建具有新大小的数据数组。此外,如果我等待足够长的时间,我的桌子确实会正常刷新,但它的口吃很多,它的视图很疯狂,虽然它以一些奇怪的,扭曲的方式工作但它总体上无法使用。

这是我的方法,应该刷新我的表模型:

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类的一部分,即从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()”,但它并没有真正帮助或改变一件事。

1 个答案:

答案 0 :(得分:3)

model1.fireTableDataChanged();

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

  

使用扩展AbstractTableModel的自定义模型

然后你错误地实现了一个方法。

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

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

setRowCount(0);

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

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

您可以扩展DefaultTableModel以添加此方法,或者将其作为您班级中的方法。

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