2014-04-03 42 views
0

我已經創建了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; 
} 

回答

0

好吧TimerTask s不適合重複使用。您可以做的最好的做法是每次重新計劃時創建一個新的TimerTask

+0

什麼會做 – Wolf

+0

取決於你的類是如何組織的,而僅僅是創建一個新的每次重新計劃時間的最佳方式。如果涉及重複部分代碼,請將'run'方法內的代碼作爲單獨的方法,並在'run'方法內部調用以避免重複。 – Arrem

0

雖然你不能簡單地重新啓動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); 
    } 
} 

公平的警告,這不會允許多態性。例如,您不能在Timer參考中存儲RestartableTimer。當您重新啓動時,您仍然需要實例化新的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++; 
      } 
     }}); 
} 
相關問題