【问题标题】:JavaFX Displaying Time and Refresh in Every SecondJavaFX 显示时间和每秒刷新
【发布时间】:2016-11-28 17:31:02
【问题描述】:

您好,我想就这个问题寻求任何建议。

我想在标签或任何适合它的组件中以 HH:MM:SS 格式(每秒刷新一次)显示当前时间。

有什么建议吗?

编辑:有人要代码..所以我把它放在这里是为了更好地描述问题。 “那段时间我没有代码我想要实现的是简单的 GUI 日记,在其中一个标签中我想显示距离最近事件的剩余时间,而在另一个标签中我想显示像时钟一样刷新每个第二.我需要它来让剩余的时间工作.我能想到的就是创建新线程来完成它并刷新时钟,但我在JavaFX中使用多线程并不是那么先进.所以我想知道是否有人可以建议我使用比多线程更简单的东西(我不知道如何将该线程实现到 JavaFX 组件中)"

【问题讨论】:

  • 你能告诉我你的代码吗?所以我可以看到任何更正。

标签: java time javafx timer


【解决方案1】:

带时间线的版本:

long endTime = ...;
Label timeLabel = new Label();
DateFormat timeFormat = new SimpleDateFormat( "HH:mm:ss" );
final Timeline timeline = new Timeline(
    new KeyFrame(
        Duration.millis( 500 ),
        event -> {
            final long diff = endTime - System.currentTimeMillis();
            if ( diff < 0 ) {
            //  timeLabel.setText( "00:00:00" );
                timeLabel.setText( timeFormat.format( 0 ) );
            } else {
                timeLabel.setText( timeFormat.format( diff ) );
            }
        }
    )
);
timeline.setCycleCount( Animation.INDEFINITE );
timeline.play();

【讨论】:

  • 帮助了我。但是我会使用 'LocalDateTime.now()' 来恢复当前日期和时间
【解决方案2】:
   Label main_clock_lb = new Label();
    Thread timerThread = new Thread(() -> {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        while (true) {
            try {
                Thread.sleep(1000); //1 second
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            final String time = simpleDateFormat.format(new Date());
            Platform.runLater(() -> {
                main_clock_lb.setText(time);
            });
        }
    });   timerThread.start();//start the thread and its ok

【讨论】:

  • 你能解释一下你到底做了什么吗?这样你的答案会更有用!
  • #1 添加了一个标签来显示时间,所以你知道#2 我声明了一个线程,即使在 gui 视图之后也会继续运行,#3 然后它将定义一个日期格式,#3 它当 i 为真时将持续运行(这可能会被修改)然后在无限运行时(取决于你将保持应用程序运行多少)并且线程将始终更新时间,但为了确保时间会在每一秒发生变化,我们将该线程置于sleep for (1000 毫秒 -> 1 秒) 之后它将初始化日期字符串并一次又一次地更新到时钟标签 ( main_clock_lb.setText(time); )
  • Platform.runLater(() -> { main_clock_lb.setText(time); }); //在未来某个未指定的时间在 JavaFX 应用程序线程上运行指定的 Runnable。所以在我想要编辑时间的那一刻
  • 请编辑您的答案并添加解释(相对于在 cmets 中这样做) - 另请注意,没有理由去如此低级别(如创建/休眠一个后台线程,然后包装在javafx中实际更新到runlater),它内置了合理的并发支持(参见使用Timeline的答案,fi)
【解决方案3】:

如何为 javaFx 打印日期和时间可能会有所帮助。

final Label clock = new Label();
final DateFormat format = DateFormat.getInstance();
final Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), 
new EventHandler() 
{
@Override  
    public void handle(ActionEvent event) 
    {
      final Calendar cal = Calendar.getInstance();
      clock.setText(format.format(cal.getTime());
    }
});

timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();

【讨论】:

【解决方案4】:

要使用 Timer 解决您的任务,您需要使用您的代码实现 TimerTask 并使用 Timer#scheduleAtFixedRate 方法重复运行该代码:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        System.out.print("I would be called every 2 seconds");
    }
}, 0, 2000);

另请注意,调用任何 UI 操作都必须在 Swing UI 线程(或 FX UI 线程,如果您使用 JavaFX)上完成:

   private int i = 0;
   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    jTextField1.setText(Integer.toString(i++));
                }
            });
        }
    }, 0, 2000);
}

如果是 JavaFX,您需要在“FX UI 线程”而不是 Swing 上更新 FX 控件。要实现这一点,请使用 javafx.application.Platform#runLater 方法而不是 SwingUtilities

【讨论】:

  • 谢谢,但那是多线程,我真的不知道如何在 JavaFX GUI 中实现它..
  • 你也可以查看这个问题stackoverflow.com/questions/34801227/…
  • 您正在从 AWT 事件调度线程更改 JavaFX 标签的文本。这违反了 JavaFX 线程规则,并且可能会抛出 IllegalStateException
  • 即使它看起来有效,它也受制于race condition,应该通过围绕Platform.runLater() 中更改文本的调用来缓解这种情况。
【解决方案5】:
    final Label clock = new Label();
    final DateFormat format = DateFormat.getInstance();
    final Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1),
            new EventHandler<ActionEvent>()
            {
                @Override
                public void handle(ActionEvent event)
                {
                    final Calendar cal = Calendar.getInstance();
                    clock.setText(format.format(cal.getTime()));
                }
            }));

    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();

【讨论】:

  • 请注意,“仅代码答案”真的不鼓励。只是转储代码对未来的读者没有多大帮助。专注于解释你在做什么!
  • 你为什么要复制另一个答案?唯一的原因可能是修改它(使用新的日期/时间类)你没有..
猜你喜欢
  • 2020-08-28
  • 1970-01-01
  • 2013-05-02
  • 2012-03-03
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
相关资源
最近更新 更多