在SwingWorker中更新JTable

时间:2014-05-23 04:24:10

标签: java swing jtable swingworker

我有一个JTable来填充来自DB的数据。我想每10分钟在JTable刷新数据(测试10秒就足够了)。我尝试使用Thread,但我发现这不是一个好主意,我需要使用SwingWorker

public class Monitor extends JFrame{

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

    public void setJTable(Vector data, Vector columnNames) {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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

    public void updateJTable(Vector data, Vector columnNames) {
        jtable = new JTable(data, columnNames);
    }

    public Monitor() {

        setTitle("Monitor System");

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

}

我的Demo课程:

public class Demo {

    public static void main(String[] args) throws ClassNotFoundException, SQLException  {

        Statement stmt = null;
        Connection conn = null;
        ResultSet rs = null;
        Vector<String> columnNames = new Vector<String>();
        Vector<Vector> rowData = new Vector<Vector>();
        DBMonitor dbmonitor = new DBMonitor();
        Monitor monitor = new Monitor();

        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

        rowData = dbmonitor.getJobsData();
        columnNames = dbmonitor.getColumnNames();
        monitor.setJTable(rowData, columnNames);
        monitor.setSize((int) dim.getWidth(), (int) dim.getHeight());
        monitor.setVisible(true);

        boolean interrupt = true;

        while (interrupt) {
            try {

                rowData = dbmonitor.getJobsData();
                columnNames = dbmonitor.getColumnNames();
                monitor.updateJTable(rowData, columnNames);
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException ie) {
                    return;
                } 
                JOptionPane.showMessageDialog(null, "SLEEP!");

            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, e.getMessage());
                System.err.println(e.getMessage());
            }
        }

    }
}

我如何使用SwingWorker执行此操作?我没有这样的概念。

2 个答案:

答案 0 :(得分:2)

在SwingWorker的doInBackground()方法中,您可以循环使用:

  1. 从数据库中检索数据
  2. 创建您的TableModel
  3. 使用SwingWorker的publish()方法将TableModel传递给SwingWorker的&#39; process()`方法
  4. 睡10秒
  5. 然后在SwingWorker的process()方法中:

    1. 使用传递给process()方法的TableModel来更新JTable。
    2. 阅读Concurrency上Swing教程中的部分,了解更多信息和工作示例,或在论坛中搜索更多SwingWorker示例。

答案 1 :(得分:1)

首先,我会从某种Timer开始,我将使用Swing Timer,因为它很简单,但您可以使用java.util.Timer代替......

private Timer updateTimer;

//...

updateTimer = new Time(10000, new ActionListener() {
    public void actionListener(ActionEvent e) {
    }
});
updateTimer.setRepeats(false);
updateTimer.start();

这允许您在大约10秒的时间内收到通知...

然后你需要一个可以做实际工作的SwingWorker ......

public class UpdateWorker extends SwingWorker<TableModel, Void> {

    private Monitor monitor;
    private Timer updateTimer;

    public UpdateWorker(Monitor monitor, Timer updateTimer) {
        this.monitor = monitor;
        this.updateTimer = updateTimer;
    }

    @Override
    protected TableModel doInBackground() throws Exception {
        Vector<Vector> rowData = dbmonitor.getJobsData();
        Vector columnNames = dbmonitor.getColumnNames();

        DefaultTableModel model = new DefaultTableModel(rowData, columnNames);
        return model;
    }

    @Override
    protected void done() {
        try {
            TableModel model = get();
            monitor.updateTable(model);
        } catch (InterruptedException | ExecutionException ex) {
            ex.printStackTrace();
        }
        updateTimer.restart();
    }
}

现在在分配给计时器的actionPerformed的{​​{1}}方法中,你会做类似的事情。

ActionListener

执行工作人员。拥有非重复计时器的原因是确保从更新完成后的public void actionListener(ActionEvent e) { UpdateWorker worker = new UpdateWorker(monitor, this); worker.execute(); } 秒设置下一次更新,因此您不会获得重叠更新

哦,这需要更新你的n以接受Monitor而不是TableModel来创建一个,这样就更简单...... < / p>