我编写了一个TimerTask来显示JLabel中的当前日期和时间。以下是TimerTask代码,在正常情况下运行良好。当我更改GUI运行时的系统日期和时间时,计时器停止运行。当我改变系统日期和时间并且Timer停止运行时没有例外。 谁能告诉我发生了什么?
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());
}
}
}
答案 0 :(得分:4)
不要将TimerTask与Swing一起使用,因为你很容易遇到并发问题,因为TimerTask将从EDT调用代码。而是使用Swing Timer;这是它的特别之处 - 在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);
}
}
答案 1 :(得分:3)
您遇到了Concurency in Swing的问题,其中java.util.Timer
的输出未调用EventDispatchThread并代表Swing GUI的Backgroung任务,
因为最好使用Swing Timer,因为保证输出将在EDT上,但与Swing Timer
相比,java.util.Timer
对于长时间运行的抽签不准确,
用于从任何类型的后台任务更新Swing GUI,您必须将输出包装到Swing GUI中invokeLater
例如
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JLabel#setText();
}
});