SwingWorker不会更新JTable

时间:2014-05-23 08:49:49

标签: java swing jtable swingworker

我有一个SwingWorker的课程,我希望从{b> DB 更新JTable中的数据:

public class MySwingWorker extends SwingWorker<Void, Monitor> {


    public DBMonitor dbmonitor;  
    Vector<Vector> rowData;
    Vector<String> columnNames;
    DefaultTableModel model;
    Monitor obj;

    @Override
    protected Void doInBackground() throws Exception {

        dbmonitor = new DBMonitor();
        rowData = dbmonitor.getJobsData();
        columnNames = dbmonitor.getColumnNames();
        obj.setJTable(rowData, columnNames);

        while (!isCancelled()) {
            Thread.sleep(10000);
            JOptionPane.showMessageDialog(null, "SLEEP!");
            rowData = dbmonitor.getJobsData();
            columnNames = dbmonitor.getColumnNames();
            model = new DefaultTableModel(rowData, columnNames);
            publish(new Monitor(model));
        }
        return null;
    }

    @Override
    protected void process(List<Monitor> monitors) {
        Monitor monitor = monitors.get(monitors.size() - 1);
        monitor.updateJTable(monitor.getModel());
    }

}

我在MonitorTabsJTable执行的SwingWorker课程:

public class Monitor extends JFrame{

    TableModel model;
    JTable jtable = null;
    JTabbedPane jtp = null;
    JPanel jp1 = null;
    JPanel jp2 = null;
    JLabel label1 = null;
    JLabel label2 = null;

    MySwingWorker worker;

    public void setJTable(Vector data, Vector columnNames) {

        jtable = new JTable(data, columnNames);
        JScrollPane scrollPane = new JScrollPane(jtable);
        jp1.add(scrollPane);
    }

    public void updateJTable(TableModel model) {
        jtable = new JTable(model);
    }

    public Monitor() throws ClassNotFoundException, SQLException {

        setTitle("Monitor System");
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        //Panel with tabs for navigation
        jtp = new JTabbedPane();
        getContentPane().add(jtp);

        //tab1, info from dba_jobs
        jp1 = new JPanel();

        //tab2 info from QueueInfo
        jp2 = new JPanel();
        label1 = new JLabel();
        label1.setText("tab1");

        label2 = new JLabel();
        label2.setText("tab2");

        jp1.add(label1);
        jp2.add(label2);

        jtp.add("Tab1", jp1);
        jtp.add("Tab2", jp2);

        DBMonitor dbmonitor = new DBMonitor();
        Vector<Vector> rowData = dbmonitor.getJobsData();
        Vector<String> columnNames = dbmonitor.getColumnNames();

        setJTable(rowData, columnNames);
        setSize(600, 600);
        setVisible(true);

        (worker = new MySwingWorker()).execute();
    }

    public Monitor(TableModel model) {
        this.model = model;
    }

    public TableModel getModel() {
        return model;
    }

}

在我执行的Main方法中:

SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        new Monitor(); 
    }
});

问题是,showMessageDialog()没有附加,JTable没有刷新。 我希望每10秒从 DB 更新JTableThe Example I take from here

1 个答案:

答案 0 :(得分:2)

您的JTable未更新,因为在发布时您创建了一个新的JFrame(称为Monitor)并将新的TableModel设置为它。您永远不会显示新的JFrame,也不会更新现有的SwingWorker。因此,当然,您不会看到任何更新。

至于如何正确地做到这一点:

  • 您需要为Monitor提供回调或对已存在的JFrame的引用(通过变量显式,或通过将其移入内部类而隐式)。只有这样才能更新正确的JTable
  • 即使这样,每次模型更改而不更换组件时,您都会创建一个新的updateTable。 I.E.你的框架仍然会显示旧表并拥有新表的数据(但不会显示它)。您需要替换public class Monitor extends JFrame{ TableModel model; Vector<String> columnNames; <other components> public Monitor() throws SQLException { columnNames = dbmonitor.getColumnNames(); model = new DefaultTableModel(columnNames, 0); <Add all components, including table with the created table model> (worker = new MySwingWorker()).execute(); } private class MySwingWorker extends SwingWorker<Void, Vector<Vector>> { @Override protected Void doInBackground() throws Exception { dbmonitor = new DBMonitor(); rowData = dbmonitor.getJobsData(); while (!isCancelled()) { Thread.sleep(10000); publish(dbmonitor.getJobsData()); } return null; } @Override protected void process(List<Vector<Vector>> data) { Vector<Vector> lastPublish = data.get(data.size() - 1); tableModel.setDataVector(lastPublish, columnNames); } } } 方法中的表格,或者(更好的解决方案)更新模型。

编辑

这是一个如何看起来的例子(假设你的列名不改变,如果他们确实发送它们就像行一样):

{{1}}