簡體   English   中英

SwingWorker不會更新JTable

[英]SwingWorker doesn't update JTable

我有一個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());
    }

}

然后在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;
    }

}

然后在我的Main方法中執行:

SwingUtilities.invokeLater(new Runnable() {

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

問題在於, showMessageDialog()不會追加, JTable也不會刷新。 我想每10秒從數據庫更新一次JTable 我從這里拿的例子

您的JTable不會更新,因為在發布時,您將創建一個新的JFrame(稱為Monitor)並將新的TableModel設置為其。 您永遠不會顯示新的JFrame ,也不會更新已經存在的JFrame 因此,您當然不會看到任何更新。

至於如何正確執行此操作:

  • 您需要為您的SwingWorker提供回調或對已經存在的Monitor的引用(通過變量顯示,或者通過將其移入內部類進行隱式)。 只有這樣,您才能更新正確的JFrame
  • 即使這樣,每次模型更改時您JTable創建一個新的JTable ,而不替換組件。 即,您的框架仍將顯示舊表,並具有新表的數據(但不會顯示它)。 您需要替換updateTable方法中的表,或者( 更好的解決方案 )更新模型。

編輯

這是一個示例(假設您的列名確實像行一樣發送給它們,則假設它們不變):

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