【问题标题】:Why doesn't JTable update its view when adding new rows to DefaultTableModel?为什么在向 DefaultTableModel 添加新行时 JTable 不更新其视图?
【发布时间】:2014-09-04 19:04:42
【问题描述】:

我在使用 JTable 时遇到了奇怪的问题。方法addRows 不会强制jTable 更新其视图:

public class VirusTable extends JTable {

    private String[] columnNames = { "", "Virus", "Path", "Size", "Created", "Last Mofified" };

    DefaultTableModel tableModel;

    public VirusTable() {
        super();

        tableModel = (DefaultTableModel) super.getModel();
        tableModel.setColumnIdentifiers(columnNames);

        // super.setFillsViewportHeight(true);
        // super.setIntercellSpacing(new Dimension(5, 5));
        // super.setRowSelectionAllowed(false);
        // super.setColumnSelectionAllowed(false);
    }

    public void addRows(Collection<UserFile> viruses) {
        System.out.println("AddRows=" + viruses);

        for (UserFile virus : viruses) {
            tableModel.addRow(virus.toRowData());
        }
//      tableModel.fireTableDataChanged();
        // tableModel.fireTableStructureChanged();
        int rowCount = super.getRowCount();
//      super.revalidate();
//      super.repaint();
        System.out.println("rowCount=" + rowCount);
    }
}

addRows 方法是从SwingWorker.process 方法调用的。 有趣的是,rowCount 始终是正确的,但 JTable 上不显示行。

我尝试了一切,但没有任何帮助。 我想创建简短的可运行演示,但我无法实现此错误。

我发布了这个项目on github 并描述了那里的问题。

【问题讨论】:

  • 如果您无法在简短的演示中实现该错误,那么该错误可能发生在其他地方?
  • 您能建议什么可能会阻止 jTable 刷新视图吗?
  • Can you suggest what might prevent jTable from refreshing view? 也许您有两个 JTable 实例。您添加到 GUI 的一个,以及您尝试更新数据的另一个。如果没有正确的SSCCE,这一切都只是一个疯狂的猜测。
  • 如果你想试试我的项目,它在 github here
  • @camickr 你今天赢得了心理问题解决奖 - 令人惊讶的是,你用给出的信息猜到了这个问题的根本原因 - 太棒了!

标签: java swing jtable swingworker


【解决方案1】:

camickr 是正确的,实际上创建了 VirusTable 的两个实例(实际上 MainFrame 也是如此,但只有一个是可见的)。您已经提供了一种访问 MainFrame 对象的方法,基本上将其转换为单例,但没有只能创建一个实例的约束。恕我直言,如果不在 MainFrame 类中创建静态 getInstance 方法,您本可以做得更好。

Anyhoo,在你的 main 方法中,你这样做:

public static void main(String[] args) throws IOException {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            new MainFrame().setVisible(true);
        }
    });
}

但是由于您编写应用程序的方式,您应该这样做(不是我推荐这种方法):

public static void main(String[] args) throws IOException {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            MainFrame.getInstance().setVisible(true);
        }
    });
}

感谢camickr,不是我。

【讨论】:

  • 我什么都看不到!谢谢!
【解决方案2】:

也许您正在从事件调度线程以外的线程更改 Swing 模型(很难从您的代码中分辨出来)?所有 Swing 交互都必须从 EDT 完成,因此要么将表更新包装在 SwingUtilities.invokeLater() 中(如果您希望它在找到每个条目时更新),或者在 done() 方法中将项目添加到表模型中SwingWorker 强制在 EDT 上执行。

【讨论】:

  • 我更新DefaultTableModel方法是从SwingWorker.process方法调用的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2011-01-21
  • 2012-04-09
相关资源
最近更新 更多