简体   繁体   English

SwingWorker不会更新JTable

[英]SwingWorker doesn't update JTable

I have a class of my SwingWorker where I want to update data in JTable from DB : 我有一个SwingWorker的类,我想在其中从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());
    }

}

And Monitor class where I render Tabs , JTable and execute SwingWorker : 然后在Monitor类中渲染TabsJTable并执行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;
    }

}

And in my Main method I execute: 然后在我的Main方法中执行:

SwingUtilities.invokeLater(new Runnable() {

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

The problem is that, showMessageDialog() doesn't append, and JTable doesn't refresh. 问题在于, showMessageDialog()不会追加, JTable也不会刷新。 I want update JTable from DB every 10 sec. 我想每10秒从数据库更新一次JTable The Example I take from here 我从这里拿的例子

Your JTable does not update because when publishing you create a new JFrame (called Monitor) and set the new TableModel to it. 您的JTable不会更新,因为在发布时,您将创建一个新的JFrame(称为Monitor)并将新的TableModel设置为其。 You never show the new JFrame , nor do you update the already existing one. 您永远不会显示新的JFrame ,也不会更新已经存在的JFrame Hence, of course, you won't see any updates. 因此,您当然不会看到任何更新。

As for how to do this properly: 至于如何正确执行此操作:

  • You need to give your SwingWorker either a callback or a reference to the already existing Monitor (explicit via a variable, or implicit by moving it into an inner class). 您需要为您的SwingWorker提供回调或对已经存在的Monitor的引用(通过变量显示,或者通过将其移入内部类进行隐式)。 Only then will you update the correct JFrame 只有这样,您才能更新正确的JFrame
  • Even then, you are creating a new JTable every time your model changes and not replacing your component. 即使这样,每次模型更改时您JTable创建一个新的JTable ,而不替换组件。 IE your frame will still show the old table and have the data for a new one (but will not show it). 即,您的框架仍将显示旧表,并具有新表的数据(但不会显示它)。 You need to either replace the table in the updateTable method, or ( much better solution ) update the model. 您需要替换updateTable方法中的表,或者( 更好的解决方案 )更新模型。

EDIT 编辑

An example of how this can look like (Assuming your column names don't change, if they do send them over just like the rows): 这是一个示例(假设您的列名确实像行一样发送给它们,则假设它们不变):

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);
          }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM