2012-04-11 79 views
2

我寫了一個TimerTask來顯示JLabel中的當前日期和時間。以下是TimerTask代碼,在正常情況下運行良好。當GUI運行時更改系統日期和時間時,定時器停止運行。當我更改系統日期和時間並且Timer剛剛停止運行時,沒有出現異常。 任何人都可以告訴我發生了什麼事嗎?當系統日期改變時,TimerTask獲取系統日期和時間停止運行

private void startTimer() 
{ 
    // Start the clock 
    timer = new Timer(); 
    timer.schedule(new TimeTask(), 0, 1000); 
} 

class TimeTask extends TimerTask 
{ 
    public void run() 
    { 
     try { 
      clockLabel.setText(new SimpleDateFormat("EEE , dd MMM , HH:mm:ss").format(Calendar.getInstance().getTime())); 
      System.out.println(clockLabel.getText()); 
     } catch(Exception ex) { 
      ex.printStackTrace(); 
      System.out.println("Exception : " + ex.getMessage()); 
     } 
    } 
} 

回答

4

不要在Timer中使用TimerTask,因爲您可以很容易地遇到併發問題,因爲TimerTask會調用EDT的代碼。而是使用擺動計時器;這就是它特有的 - 在Swing事件線程上定期調用代碼。

private void startTimer() { 
    timer = new Timer(TIMER_DELAY, new TimerListener()); 
    timer.start(); 
} 

private class TimerListener implements ActionListener { 
    private final String PATTERN = "EEE , dd MMM , HH:mm:ss"; 
    private final DateFormat S_DATE_FORMAT = new SimpleDateFormat(PATTERN); 

    @Override 
    public void actionPerformed(ActionEvent e) { 
    Date date = Calendar.getInstance().getTime(); 

    String dateString = S_DATE_FORMAT.format(date); 
    clockLabel.setText(dateString);   
    } 
} 
3
  • 你有問題與Concurency in Swing,來自java.util.Timer輸出不會調用EventDispatchThread,並代表Swing GUI的Backgroung任務,

  • 因爲會更好使用Swing Timer,因爲保證產量將在EDT上,但Swing Timer對於長時間運行時間不準確,與java.util.Timer,

  • 從你要輸出到擺動GUI包裝到invokeLater

例如任何類型的後臺任務更新搖擺GUI

EventQueue.invokeLater(new Runnable() { 

    @Override 
    public void run() { 
     JLabel#setText(); 
    } 
});