如何在数据和大小更改后刷新 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(...)"`
我的项目是 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(...)"`