java中的动态时钟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2959718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:56:43  来源:igfitidea点击:

Dynamic Clock in java

javaswingclock

提问by jt153

I want to implement a clock within my program to diusplay the date and time while the program is running. I have looked into the getCurrentTime()method and Timers but none of them seem to do what I would like.

我想在我的程序中实现一个时钟来显示程序运行时的日期和时间。我已经研究了getCurrentTime()方法和Timers 但他们似乎都没有做我想做的事。

The problem is I can get the current time when the program loads but it never updates. Any suggestions on something to look into would be greatly appreciated!

问题是我可以获得程序加载时的当前时间,但它永远不会更新。任何有关调查的建议将不胜感激!

回答by jjnguy

What you need to do is use Swing's Timerclass.

您需要做的是使用 Swing 的Timer类。

Just have it run every second and update the clock with the current time.

只需让它每秒运行一次并使用当前时间更新时钟。

Timer t = new Timer(1000, updateClockAction);
t.start();

This will cause the updateClockActionto fire once a second. It will run on the EDT.

这将导致updateClockAction每秒触发一次。它将在 EDT 上运行。

You can make the updateClockActionsimilar to the following:

您可以制作updateClockAction类似于以下内容的内容:

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()); 
    }
}

Because this updates the clock every second, the clock will be off by 999ms in a worse case scenario. To increase this to a worse case error margin of 99ms, you can increase the update frequency:

因为这每秒更新一次时钟,所以在更坏的情况下时钟将关闭 999 毫秒。要将其增加到更坏情况下的 99 毫秒误差范围,您可以增加更新频率:

Timer t = new Timer(100, updateClockAction);

回答by PhilDin

This sounds like you might have a conceptual problem. When you create a new java.util.Date object, it will be initialised to the current time. If you want to implement a clock, you could create a GUI component which constantly creates a new Date object and updates the display with the latest value.

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

One question you might have is how to repeatedly do something on a schedule? You could have an infinite loop that creates a new Date object then calls Thread.sleep(1000) so that it gets the latest time every second. A more elegant way to do this is to use a TimerTask. Typically, you do something like:

您可能会遇到的一个问题是如何按计划重复做某事?您可以有一个无限循环,它创建一个新的 Date 对象,然后调用 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
   }
}

Then, to invoke it, you would do something like:

然后,要调用它,您将执行以下操作:

Timer myTimer = new Timer();
myTimer.schedule(new MyTimedTask (), 0, 1000);  // Start immediately, repeat every 1000ms

回答by OscarRyz

You have to update the text in a separate thread every second.

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

Ideally you should update swing component only in the EDT ( event dispatcher thread ) but, after I tried it on my machine, using Timer.scheduleAtFixRategave me better results:

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

java.util.Timer http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png

java.util.Timer http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png

The javax.swing.Timer version was always about half second behind:

javax.swing.Timer 版本总是落后大约半秒:

javax.swing.Timer http://img241.imageshack.us/img241/2599/capturadepantalla201006.png

javax.swing.Timer http://img241.imageshack.us/img241/2599/capturadepantalla201006.png

I really don't know why.

我真的不知道为什么。

Here's the full source:

这是完整的来源:

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 );
    }
}

Here's the modified source using javax.swing.Timer

这是使用 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();
    }

Probably I should change the way the string with the date is calculated, but I don't think that's the problem here

可能我应该改变带日期的字符串的计算方式,但我认为这不是问题所在

I have read, that, since Java 5 the recommended is: ScheduledExecutorServiceI leave you the task to implement it.

我读过,从 Java 5 开始,推荐的是:ScheduledExecutorService我留给你实现它的任务。

回答by trashgod

For those preferring an analog display: Analog Clock JApplet.

对于那些喜欢模拟显示器的人:模拟时钟 JApplet

回答by vishnubalaji

   public void start(){
        reset();
        ScheduledExecutorService worker = Executors.newScheduledThreadPool(3);
         worker.scheduleAtFixedRate( new Runnable(){
            public void run(){
                if( currentSecond == 60 ) {
                    reset();
                }
                time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond));
                currentSecond++;
            }
        }, 0, 1000 ,TimeUnit.MILLISECONDS );
    } 

回答by shareef

Note the method scheduleAtFixedRateis used here

注意scheduleAtFixedRate这里使用的方法

        // Current time label
        final JLabel currentTimeLabel = new JLabel();
        currentTimeLabel.setFont(new Font("Monospace", Font.PLAIN, 18));
        currentTimeLabel.setHorizontalAlignment(JTextField.LEFT);

        // Schedule a task for repainting the time
        final Timer currentTimeTimer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                currentTimeLabel.setText(TIME_FORMATTER.print(System.currentTimeMillis()));
            }
        };

        currentTimeTimer.scheduleAtFixedRate(task, 0, 1000);

回答by Dermot

    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();