我有一个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
执行此操作?我没有这样的概念。
答案 0 :(得分:2)
在SwingWorker的doInBackground()
方法中,您可以循环使用:
publish()
方法将TableModel传递给SwingWorker的&#39; process()`方法然后在SwingWorker的process()
方法中:
process()
方法的TableModel来更新JTable。阅读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>