java中的动态时钟

java中的动态时钟,java,swing,clock,Java,Swing,Clock,我想在程序中实现一个时钟,以便在程序运行时显示日期和时间。我已经研究了getCurrentTime()方法和Timers,但它们似乎都不是我想要的 问题是我可以得到程序加载的当前时间,但它从不更新。如果您有任何建议,我们将不胜感激 您需要做的是使用Swing的类 只要让它每秒钟运行一次,并用当前时间更新时钟 Timer t = new Timer(1000, updateClockAction); t.start(); 这将导致每秒触发一次UpdateLockAction。它将在EDT上运行

我想在程序中实现一个时钟,以便在程序运行时显示日期和时间。我已经研究了
getCurrentTime()
方法和
Timer
s,但它们似乎都不是我想要的


问题是我可以得到程序加载的当前时间,但它从不更新。如果您有任何建议,我们将不胜感激

您需要做的是使用Swing的类

只要让它每秒钟运行一次,并用当前时间更新时钟

Timer t = new Timer(1000, updateClockAction);
t.start();
这将导致每秒触发一次UpdateLockAction。它将在EDT上运行

您可以使
updateLockAction
类似于以下内容:

ActionListener updateClockAction = new ActionListener() {
  public void actionPerformed(ActionEvent e) {
      // Assumes clock is a custom component
      yourClock.setTime(System.currentTimeMillis()); 
      // OR
      // Assumes clock is a JLabel
      yourClock.setText(new Date().toString()); 
    }
}
因为这会每秒更新一次时钟,所以在更糟糕的情况下,时钟将关闭999ms。要将此值增加到99毫秒的更坏情况误差范围,可以增加更新频率:

Timer t = new Timer(100, updateClockAction);

听起来你可能有概念上的问题。创建新的java.util.Date对象时,它将初始化为当前时间。如果要实现时钟,可以创建一个GUI组件,该组件不断创建新的日期对象,并使用最新值更新显示

你可能会问的一个问题是,如何按照计划重复做一些事情?您可以有一个无限循环,它创建一个新的日期对象,然后调用Thread.sleep(1000),这样它就可以每秒获得最新的时间。更优雅的方法是使用TimerTask。通常,您会执行以下操作:

private class MyTimedTask extends TimerTask {

   @Override
   public void run() {
      Date currentDate = new Date();
      // Do something with currentDate such as write to a label
   }
}
Timer myTimer = new Timer();
myTimer.schedule(new MyTimedTask (), 0, 1000);  // Start immediately, repeat every 1000ms
然后,要调用它,您可以执行以下操作:

private class MyTimedTask extends TimerTask {

   @Override
   public void run() {
      Date currentDate = new Date();
      // Do something with currentDate such as write to a label
   }
}
Timer myTimer = new Timer();
myTimer.schedule(new MyTimedTask (), 0, 1000);  // Start immediately, repeat every 1000ms

你必须每秒在一个单独的线程中更新文本

理想情况下,您应该只在EDT(事件调度程序线程)中更新swing组件,但是,在我在我的机器上尝试之后,使用提供了更好的结果:

javax.swing.Timer版本总是落后半秒左右:

我真的不知道为什么

以下是完整的来源:

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以来,推荐的方法是:我把实现它的任务留给您。

对于那些喜欢模拟显示的人:。

注意这里使用的方法是
scheduleAtFixedRate


我不经常使用Swing,所以我没有给出详细的答案,但谷歌似乎给出了足够的提示:切中要害:你每次都需要在后台线程中自己更新时钟。@BalusC,但你经常使用谷歌;)此代码可能工作正常,但由于您使用的是Java.util.Timer,因此需要确保使用
SwingUtilities.invokeLater()
来更新GUI.Timer。我故意对“做点什么”这一点含糊其辞,我不想同时介绍太多东西。我做了一个测试,更新总是比使用javax.swing.Timer慢半秒,但是,我不知道为什么我不知道,可能是启动时间(进入EDT或其他),但我无法恢复它们。嗨,欢迎来到堆栈溢出。当回答一个已经有很多答案的问题时,请务必补充一些额外的见解,说明为什么您提供的回答是实质性的,而不是简单地重复原始海报已经审查过的内容。这在“只使用代码”的答案中尤其重要,例如您提供的答案。
    Timer timer = new Timer(1000, (ActionEvent e) -> {
        DateTimeFormatter myTime = DateTimeFormatter.ofPattern("HH:mm:ss");
        LocalDateTime now = LocalDateTime.now(); 
        jLabel1.setText(String.valueOf(myTime.format(now)));
    });
    timer.setRepeats(true);
    timer.start();