2013-11-28 181 views
2

我有一個fairly simple JavaFX GUI application,它有一個標籤,顯示在某個動作開始之前還剩多少時間。要做到這一點,我創建了一個DownloadTimer類,如下圖所示:TimerTask無法更新JavaFX標籤文本

public class DownloadTimer(){ 
    private int minutes;   
    private int seconds; 
    private Timer innerTimer = new Timer(); 
    private TimerTask innerTask; 
    private boolean isActive; 

    public DownloadTimer(int minutes, int seconds) { 
     if (seconds > 60) { 
      int minToAdd = seconds/60; 
      this.minutes = minutes; 
      this.minutes += minToAdd; 
      this.seconds = seconds % 60; 
     } else { 
      this.minutes = minutes; 
      this.seconds = seconds; 
     } 
    } 

    public void start() { 
     innerTask = new TimerTask() { 
      @Override 
      public void run() { 
       isActive = true; 
       System.out.println(getTime()); 
       if (seconds == 0 && minutes > 0){ 
        minutes -= 1; 
        seconds = 59; 
       } else if (seconds == 0 && minutes == 0){ 
        isActive = false; 
        innerTimer.cancel(); 
        innerTimer.purge(); 
        System.out.println("DownloadTimer DONE"); 
       } else { 
        seconds -= 1; 
       }  
      } 
     }; 
     innerTimer.scheduleAtFixedRate(innerTask, 0, 1000); 
    } 
} 

然後,我創建了DownloadTimer對象,並從我的Main(JavaFX的)類開始倒計時:

/* 
    code omitted for better readability 
*/ 

downloadTimer = new DownloadTimer(0, 5); 

// label gets the .getTime() value, which returns a formatted String like "00:05", "00:04", etc. 
lblTimer.setText(downloadTimer.getTime()); 

// start the countdown 
downloadTimer.start(); 

// create a new timer which checks if the downloadTimer is still counting 
final Timer timer = new Timer(); 
TimerTask timerTask = new TimerTask(){ 
    @Override 
    public void run(){ 
     if (downloadTimer.getIsActive() == false){ 
      timer.cancel(); 
      timer.purge(); 
      System.out.println("GUI timer DONE"); 
     } else { 
      // if it's still running, then continuously update the label's text 
      lblTimer.setText(downloadTimer.getTime()); 
      // this is where I get the error described below 
     } 
    } 
}; 
// repeat after 1000ms 
timer.scheduleAtFixedRate(timerTask, 0, 1000); 

我遇到的問題是,我無法使用Main類中的lblTimer.setText(downloadTimer.getTime());來設置標籤文本,並且我得到的錯誤是TimerThread.run() line: not available [local variables unavailable],因爲它的值爲seen here

我已閱讀約ScheduledThreadPoolExecutorJava Timer vs ExecutorService,但我很好奇這是否可以使用兩個單獨的計時器和TimerTasks完成。任何幫助和/或提示將不勝感激。

回答

6

我很驚訝你沒有看到一個例外。要從一個單獨的線程更新標籤,需要安排在FX線程中運行更新:

Platform.runLater(new Runnable() { 
    public void run() { 
     lblTimer.setText(downloadTimer.getTime()); 
    } 
}); 
+0

工作完美無瑕!到目前爲止,我一直在試圖找出這個問題三天。謝謝! –

+0

@ E.Normous不客氣!我的頭髮利潤率爲2小時 - 在此之後,我開始尋找建議...... :-) –