您必须每秒在单独的线程中更新文本。
理想情况下,您应该只在 EDT(事件调度程序线程)中更新 swing 组件,但是,在我的机器上尝试之后,使用 Timer.scheduleAtFixRate 给了我更好的结果:
java.util.Timer http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png
javax.swing.Timer 版本总是落后大约半秒:
javax.swing.Timer http://img241.imageshack.us/img241/2599/capturadepantalla201006.png
我真的不知道为什么。
这是完整的来源:
package clock;
import javax.swing.*;
import java.util.*;
import java.text.SimpleDateFormat;
class Clock {
private final JLabel time = new JLabel();
private final SimpleDateFormat sdf = new SimpleDateFormat("hh:mm");
private int currentSecond;
private Calendar calendar;
public static void main( String [] args ) {
JFrame frame = new JFrame();
Clock clock = new Clock();
frame.add( clock.time );
frame.pack();
frame.setVisible( true );
clock.start();
}
private void reset(){
calendar = Calendar.getInstance();
currentSecond = calendar.get(Calendar.SECOND);
}
public void start(){
reset();
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask(){
public void run(){
if( currentSecond == 60 ) {
reset();
}
time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
currentSecond++;
}
}, 0, 1000 );
}
}
这是使用 javax.swing.Timer 修改后的源代码
public void start(){
reset();
Timer timer = new Timer(1000, new ActionListener(){
public void actionPerformed( ActionEvent e ) {
if( currentSecond == 60 ) {
reset();
}
time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
currentSecond++;
}
});
timer.start();
}
也许我应该改变计算日期字符串的方式,但我认为这不是问题
我已经读到,从 Java 5 开始,推荐的是:ScheduledExecutorService 我留给你实现它的任务。