【问题标题】:JTable won't refreshJTable 不会刷新
【发布时间】:2012-03-20 18:52:52
【问题描述】:

为什么表格单元格 0,1 不会从 aaa 更改为 XXXX?

import java.awt.*;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;


class MainFrame {

    public static void main(String[] args) {


        JFrame f = new JFrame("Refreshing JTable");
        JPanel p = new JPanel(new GridBagLayout());
        DefaultTableModel productsModel;
        JTable productsTable;

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }


}

原因: 显然尝试更新存储数据的数组将导致 JTable 不改变。要么需要更新 DefaultTableModel,要么需要重绘整个表格。

编辑(可能的解决方案)一种方法是使用计时器

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

class MainFrame {

    static JFrame f = new JFrame("Refreshing JTable");
    static JPanel p = new JPanel(new GridBagLayout());
    static DefaultTableModel productsModel;
    static JTable productsTable;

    public static void main(String[] args) {
        runGui();
    }

    @SuppressWarnings("serial")
    public static void runGui() {

        f.setSize(800, 600);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        String[] tableTitle = new String[] {"ID", "Name"};
        String[][] tableData = {{"1", "AAA"},{"2", "BBB"}};


        productsModel = new DefaultTableModel(tableData, tableTitle);
        productsTable = new JTable(productsModel) {
            public boolean isCellEditable(int r, int c) {
                return false;
            }
        };

        JScrollPane scrollpane = new JScrollPane(productsTable);


        tableData[0][1] = "XXXX";

        Timer t = new Timer(2000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addColumns();
                remakeData();
                productsTable.setModel(productsModel);

            }
        });
        t.start();

        f.add(p);
        p.add(scrollpane);
        f.validate();
        f.setVisible(true);


    }

    private static void addColumns() {
        productsModel.setColumnCount(0);
        productsModel.addColumn("ID");
        productsModel.addColumn("Name");
    }

    private static void remakeData() {
        productsModel.setRowCount(0);
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"1", "Dummy item 1"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"2", "Dummy itme 2"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"3", "Dummy item 3"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"4", "Dummy item 4"});
        productsModel.insertRow(productsModel.getRowCount(), new Object[] {"5", "Dummy item 5"});
    }
}

编辑(更好的解决方案,它完美地为我工作)使用静态方法。由于我通过另一个 Frame 在数组中添加新数据,因此我在 MainFrame 中创建了一个静态方法,每次在数组中添加/更新/删除对象时都会调用该方法。此方法将在更新后重做整个模型,因此会刷新表。

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 我赞同 Andrew 的建议,因为我认为我们无法根据现有信息猜测出什么问题。还可以考虑在代码中添加大量 System.out.println 调用,以帮助调试错误源并确保您的假设都是正确的。
  • 您打算多久发布一次完全相同的问题,而在理解方面没有任何进展的迹象并且总是没有 sscce?
  • @vedran: 简单地说,由于您使用的是 DefaultTableModel,因此您需要什么都不做。如果模型发生更改,JTable 将自动更改其视图的状态,因为模型知道触发通知方法来告诉视图进行更新。由于这没有发生,这表明某处存在错误,这就是我们无法为您提供帮助的原因。

标签: java swing jtable jframe defaulttablemodel


【解决方案1】:

在您的相关线程上发布的 SSCCE 的一个问题是代码更改了最初形成表模型的数组,而它应该更改表模型本身。

【讨论】:

  • 问题是,该表显示来自我存储在数组中的 sql 查询的数据。此外,当我添加产品时,我将它添加到 DB 中,而不仅仅是 tablemodel。那么如何从 sql 中检索数据并将其直接存储在模型中?
  • “问题是,该表显示了我存储在数组中的 sql 查询的数据。” 那么...什么?您希望数据库在本地数组更改时更新?我很困惑,或者你是,或者我们俩都是。
  • 可能是你 :) 毕竟我是这里的新手。至于这个问题,构建得相当糟糕:您有没有为我建议的解决方案,它可以帮助我每次通过查询添加内容时更新表模型?
  • "..我有两个 JFrames.." 不是直接的问题,但首先解决它。有关详细信息,请参阅Multiple frames: good/bad practice?。顺便说一句,您是否厌恶投票?就我个人而言,我会给任何对我的任何问题提供答案的人投赞成票(尽管我写的问题很好,所以通常会得到很好的答案)。
  • “我终于做到了。” 恭喜!很高兴你把事情解决了。 :)
【解决方案2】:

您的问题(和上一个问题)的解决方案相当简单,但遗憾的是太长了,无法在评论中发布

  1. 您务必阅读一下JTable 的实际工作原理。一个好的起点是Swing tutorial,甚至可能是最重要的类JTableTableModel 的类javadoc。另一个关于 Swing 和 MVC 使用的好书是this document。它比仅JTables 更广泛,但会让您更深入地了解所有 Swing 组件是如何设计的,以及您应该如何使用它们。
  2. 阅读完该教程后,您应该明白,如果要更新表中显示的数据,则需要更新表的模型。模型将触发表格接收到的事件,表格将确保它自己更新。毕竟,表格只是数据的一个视图(=TableModel),所以更新应该在模型端进行。如果不清楚,请返回第 1 步
  3. 现在查看您的代码并删除侦听器。相反,更新表上的模型并查看表如何自我更新。
  4. 如果这不起作用,您可以返回此站点并返回您发布的SSCCE。这样我们就可以看到你尝试了一些东西,你尝试了什么,很可能你的代码有什么问题。此 SSCCE 应包含您使用的 TableModel 的代码以及更新您的 TableModel 的代码,因为这是最有可能出现问题的位置。

【讨论】:

  • 您好,感谢您的回答。感谢安德鲁,我发现了问题。似乎我正在将新数据添加到我用作模型的数据容器的数组中,这不会做任何事情。相反,我正在寻找一种可以让我不断更新表模型的解决方案。现在我找到了一个解决方案,通过一个调用remakeTable()方法的计时器,它完全删除模型数据,然后用新的sql查询替换它。
猜你喜欢
  • 2010-10-04
  • 2015-09-06
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多