根据我之前的问题What's the best way to have a dynamic JTable whose data updates itself with changes in database table?,我使用以下代码自动更新jList
DefaultListModel x = new DefaultListModel();
jList1.setModel(x);
int initialDelay = 0;
int period = 5000;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
x.clear();
try {
conn = Database.Connect("patient.db");
sql = "SELECT * FROM PATIENT_APPOINTMENTS";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()) {
x.addElement(rs.getString("patientid"));
}
}
catch ( Exception e) {
JOptionPane.showMessageDialog(null,e,"Error",JOptionPane.ERROR_MESSAGE);
}
}
};
timer.scheduleAtFixedRate(task,initialDelay,period);
但是我已经阅读了有关SwingWorker的内容,它似乎是正确的方法。swing工作程序的正常实现有3个受保护的doInBackground方法,发布和完成。我还尝试使用SwingWorker的另一个版本
DefaultListModel x = new DefaultListModel();
jList1.setModel(x);
int initialDelay = 0;
int period = 5000;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
x.clear();
try {
SwingWorker<ArrayList<String>, Void> worker = new SwingWorker<ArrayList<String>, Void>() {
protected ArrayList<String> doInBackground() throws Exception {
ArrayList<String> patientid = new ArrayList<String>();
conn = Database.Connect("patient.db");
sql = "SELECT * FROM PATIENT_APPOINTMENTS";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
patientid.add(rs.getString("patientid"));
}
return patientid;
}
protected void done() {
ArrayList<String> id = new ArrayList<String>();
try {
id = get();
for (int i = 0; i < id.size(); i++) {
x.addElement(id.get(i));
}
} catch (InterruptedException e) {
JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.ERROR_MESSAGE);
} catch (ExecutionException e) {
JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.ERROR_MESSAGE);
}
}
};
worker.execute();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.ERROR_MESSAGE);
}
}
};
timer.scheduleAtFixedRate(task, initialDelay, period);
}
哪种方法比较好? 此外,jList每5秒闪烁5次,我该如何避免?
答案 0 :(得分:5)
Swing Timer
在Event Dispatching Thread的上下文中执行它的通知,使其适合更新UI,但不适合执行长时间运行或阻塞任务(如查询数据库)
Thread
适用于执行长时间运行或阻止任务但不应该用于更新UI,因为Swing不是线程安全的,并且只应在EDT的上下文中修改UI。当然你可以使用EventQueue.invokeLater
,但是如果你需要为这些调用提供参数会很痛苦......
您可以改为使用SwingWorker
,它有能力在后台执行长时间运行或阻止任务(在EDT之外),但提供了通过它{{1}更新UI的方法} / publish
,process
和/或done
支持
看看:
了解更多详情
哪种方法更好
您的第一个示例违反了Swing的单线程规则,因此没有多大用处......
你的第二个例子是过度杀戮,PropertyChange
已经在运行背景,你实际上更善于使用ScheduledExecutorService
并传递TimerTask
的实例。
<强>更新强>
不是我喜欢它的方式,但......
SwingWorker