2

JLabelに現在の日付と時刻を表示するTimerTaskを作成しました。以下はTimerTaskコードであり、通常のシナリオでうまく機能します。GUIの実行中にシステムの日付と時刻を変更すると、タイマーの実行が停止します。システムの日付と時刻を変更したときに例外はなく、タイマーの実行が停止しました。誰かが何が起こっているのか教えてもらえますか?

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

2 に答える 2

4

TimerTaskはEDTからコードを呼び出すため、同時実行の問題が発生しやすいため、SwingでTimerTaskを使用しないでください。代わりに、スイングタイマーを使用してください。これは特にそれが構築されているものです-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);         
  }
}
于 2012-04-11T18:17:40.380 に答える
3
  • SwingのConcurencyに問題があり、からの出力はEventDispatchThreadjava.util.Timerを呼び出さず、SwingGUIのBackgroungタスクを表します。

  • 出力がEDTであることが保証されているため、Swing Timerを使用する方が適切ですが、と比較して、Swing Timer長時間実行されるタックでは正確ではありません。java.util.Timer

  • あらゆるタイプのバックグラウンドタスクからSwingGUIを更新するには、SwingGUIへの出力を次のようにラップする必要があります。invokeLater

例えば

EventQueue.invokeLater(new Runnable() {

    @Override
    public void run() {
        JLabel#setText();
    }
});
于 2012-04-11T18:27:33.220 に答える