Java 与可能长时间运行的后台任务一起使用Swing计时器
我需要重复执行一项任务,该任务会影响GUI相关和非GUI相关的对象。一个警告是,如果在触发下一个计时器事件时上一个任务尚未完成,则不应执行任何操作。 我最初的想法是将SwingTimer与javax.swing.SwingWorker对象结合使用。一般设置如下所示Java 与可能长时间运行的后台任务一起使用Swing计时器,java,swing,Java,Swing,我需要重复执行一项任务,该任务会影响GUI相关和非GUI相关的对象。一个警告是,如果在触发下一个计时器事件时上一个任务尚未完成,则不应执行任何操作。 我最初的想法是将SwingTimer与javax.swing.SwingWorker对象结合使用。一般设置如下所示 class { timer = new Timer(speed, this); timer.start(); public void actionPerformed(ActionEvent e)
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之前工作进程尚未完成,则多个SwingWorker将处于活动状态
2) SwingWorker设计为只执行一次,因此保留对worker的引用并重用(不是?)是可行的选择
有没有更好的方法来实现这一点?您有没有考虑过使用简单的Java计时器,以及在计时器再次触发时确定任务是否正在运行?在这种情况下,您可以简单地退出该特定迭代并等待下一次迭代。您是否考虑过使用简单的Java计时器和一个确定计时器再次触发时任务是否正在运行的方法?在这种情况下,您只需退出特定的迭代并等待下一次。为什么要使用计时器?让“worker”一直运行会更简单,只要任务完成时间太少,就通过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();
Thread background=新线程(new Runnable()){
公开募捐{
而(!stopRequested){
长启动=System.currentTimeMillis();
//做任务
长时间运行=启动-System.currentTimeMillis();
SwingUtilities.invokeLater(新的Runnable(){
public void run(){
//更新用户界面
}
});
如果(经过的时间<滴答声时间){
睡眠(滴答声时间-已过);
}
}
}
}.start();
为什么要使用计时器?更简单的方法是让“worker”一直运行,在任务完成时间太少时通过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();
Thread background=新线程(new Runnable()){
公开募捐{
而(!stopRequested){
长启动=System.currentTimeMillis();
//做任务
长时间运行=启动-System.currentTimeMillis();
SwingUtilities.invokeLater(新的Runnable(){
public void run(){
//更新用户界面
}
});
如果(经过的时间<滴答声时间){
睡眠(滴答声时间-已过);
}
}
}
}.start();
对于(1),ScheduledThreadPoolExecutor
上的scheduleAtFixedRate()
方法可能有用。来自javadocs:
如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行
对于(2),您可以定义一个子类SwingWorker
,并为每次迭代构造该子类的新实例,而不是实例化一个匿名子类。对于(1),ScheduledThreadPoolExecutor
上的scheduleAtFixedRate()
方法可能很有用。来自javadocs:
如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行
对于(2),您可以定义SwingWorker
的子类,并为每次迭代构造该子类的新实例,而不是实例化一个匿名子类