2013-11-28 1 views
2

fairly simple JavaFX GUI application에는 특정 작업이 시작될 때까지 남은 시간을 나타내는 레이블이 있습니다. 이를 위해 아래 그림과 같이, 나는 DownloadTimer 클래스를 만들었습니다TimerTask가 JavaFX Label 텍스트를 업데이트 할 수 없습니다.

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 객체를 생성하고 내 홈페이지 (자바 FX) 클래스에서 카운트 다운을 시작 했어 :

/* 
    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); 

이 문제는 내가 메인 클래스에서 lblTimer.setText(downloadTimer.getTime());으로 레이블 텍스트를 설정할 수없고, 내가 얻는 오류가 TimerThread.run() line: not available [local variables unavailable]seen here임을 알 수 있습니다.

ScheduledThreadPoolExecutorJava Timer vs ExecutorService에 대해 읽었습니다. 그러나 두 개의 별도 타이머 및 타이머 태스크를 사용하여이 작업을 수행 할 수 있는지 궁금합니다. 도움이나 팁을 주시면 감사하겠습니다.

답변

6

예외가 표시되지 않습니다. 별도의 스레드에서 레이블을 업데이트하려면 FX 스레드에서 업데이트를 실행하도록 예약해야합니다.

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

완벽하게 작동했습니다. 나는 지금까지 3 일 동안이 것을 알아 내려고 애썼다. 감사! –

+0

@ E.Normous 환영합니다! hairpulling을위한 나의 최고 한계는 2 시간이다 - 이것 후에 나는 충고를 찾기 시작한다 :-) –

관련 문제