创建计时器但无法重新启动它

时间:2014-04-03 16:48:04

标签: java timer

我已经创建了GUI计时器,它运行的方式与我想要的完全相同。我有一个停止和暂停按钮,当我停止或暂停计时器并重新启动一个新的时,我在线程“AWT-EventQueue-0”中得到异常java.lang.IllegalStateException:任务已经安排或取消

我不确定我想要做什么我读过你不能重复使用任务,但我无法解决这个问题。有人可以帮助我,我会为此疯狂,我似乎总是解决一个问题,但另一个问题出现了。

这是我执行倒计时的部分代码

private  TimerTask task = new TimerTask(){
@Override
public void run(){
    if (countdown()) {
        if(minutes < 9 && seconds < 9)
        timerOutput.setText("0"+minutes + ": 0" + seconds);
        else if(minutes < 9)
        timerOutput.setText("0"+minutes + ":" + seconds);
        else if(seconds < 9)
        timerOutput.setText(minutes + ": 0" + seconds);

    }
    else
    {
        System.out.println("Finish!");
        timerOutput.setText("Time is up!");
        timer.cancel();
        startBut.setEnabled(true);
    }
}

};

private boolean countdown(){
    seconds --;
    if (seconds < 0){
        minutes--;
        seconds = 59;

        if (minutes == -1){
            return false;
        }
    }
    return true;
}

2 个答案:

答案 0 :(得分:0)

TimerTask并未设计为可重复使用。每当您重新安排时,您可以做的最好的事情就是创建一个新的TimerTask

答案 1 :(得分:0)

虽然您不能简单地重新启动Timer,但您可以创建一个Timer包装类,它的行为与Timer完全相同,但允许使用简单的重启方法来实例化新的Timer在后台。例如;

public class RestartableTimer{

    private Timer timer;
    private long delay, period;

    public RestartableTimer(){
        timer = new Timer();
    }  

    public void scheduleAtFixedRate(TimerTask task, long delay, long period){
        this.delay = delay;
        this.period = period;
        timer.scheduleAtFixedRate(task, delay, period);
    }

    public void restart(TimerTask task){
        timer.cancel();
        timer = new Timer();
        timer.scheduleAtFixedRate(task, delay, period);
    } 
}

公平警告,这不允许多态性。例如,您无法在RestartableTimer引用中存储Timer。重新启动时,您还需要实例化新的TimerTask。如果你想(并且你知道你只会重用相同的TimerTask),你可以在上面声明一个自定义和私有嵌入类,让包装类处理新TimerTask的创建。或者,您可以让类方法采用TimerTaskFactory来实现一个接口,该接口需要一个返回TimerTask的方法。

下面是使用上述类的一个例子;

public static void main(String[] args) throws InterruptedException{
    TimerTask task = new TimerTask(){
        @Override
        public void run() {
            System.out.println("Running");
        }};
    RestartableTimer rt = new RestartableTimer();
    System.out.println("Timer starting with one task");
    rt.scheduleAtFixedRate(task, 1000, 1000);
    Thread.sleep(5000);
    System.out.println("Timer restarting with another task");
    rt.restart(new TimerTask(){
        int count = 0;
        @Override
        public void run() {
            if(count>4) {
                System.out.println("Done");
                this.cancel();
            } else {
                System.out.println("Running 2");
                count++;
            }
        }});
}