[英]Swing Timer in Conjunction with Possible Long-running Background Task
我需要重復執行一個既影響GUI相關對象又影響非GUI相關對象的任務。 一個警告是,如果在觸發下一個計時器事件時上一個任務尚未完成,則不應執行任何操作。 我最初的想法是將SwingTimer與javax.swing.SwingWorker對象結合使用。 常規設置如下所示。
class
{
timer = new Timer(speed, this);
timer.start();
public void actionPerformed(ActionEvent e)
{
SwingWorker worker = new SwingWorker() {
@Override
public ImageIcon[] doInBackground() {
// potential long running task
}
@Override
public void done() {
// update GUI on event dispatch thread when complete
}
}
}
我看到這種方法的一些潛在問題是:
1)如果一個工作程序在計時器觸發下一個ActionEvent之前尚未完成,則多個SwingWorkers將處於活動狀態。
2)SwingWorker只能執行一次,因此保留對worker的引用並重用(不是?)可行的選擇。
有沒有更好的方法來實現這一目標?
您是否看過使用簡單的Java計時器和ReadWriteLock來確定計時器再次觸發時任務是否正在運行? 在這種情況下,您可以退出該特定迭代,然后等待下一個迭代。
為什么要使用計時器? 使“工作人員”始終保持運行會更簡單,只要任務花費的時間很少,就可以通過sleep()暫停。 您仍然可以使用類似以下的內容在事件分發線程中更新內容:
Thread background = new Thread(new Runnable() {
public void run() {
while ( ! stopRequested ) {
long start = System.currentTimeMillis();
// do task
long elapsed = start - System.currentTimeMillis();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// update UI
}
});
if (elapsed < tickTime) {
Thread.sleep(tickTime - elapsed);
}
}
}
}.start();
對於(1), ScheduledThreadPoolExecutor
上的scheduleAtFixedRate()
方法可能很有用。 從javadocs:
如果此任務的任何執行花費的時間超過其周期,則后續執行可能會開始得較晚,但不會同時執行。
對於(2),看起來您可以定義SwingWorker
的子類並為每次迭代構造該子類的新實例,而不是實例化匿名子類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.