news 2026/6/14 5:24:12

JavaFX 实时时钟:Timeline 与动画系统入门

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaFX 实时时钟:Timeline 与动画系统入门

一、最终效果预览

运行程序后,窗口右下角显示实时更新的时间,每秒刷新一次:

时间格式为yyyy.MM.dd hh:mm:ss,每秒自动更新,精确到秒。


二、核心知识点

2.1 Timeline:JavaFX 的时间轴动画

Timeline是 JavaFX 动画系统的核心类,用于按时间线执行一系列动作:

属性/方法说明
new KeyFrame(Duration, EventHandler)定义关键帧:到达指定时间后执行事件
setCycleCount(int)设置循环次数,INDEFINITE表示无限循环
play()启动动画
pause()暂停动画
stop()停止动画

2.2 SimpleDateFormat 时间格式化

DateFormatcurrentTime=newSimpleDateFormat("yyyy.MM.dd hh:mm:ss");

常用格式符号:

符号含义示例
yyyy四位年份2026
MM两位月份06
dd两位日期13
HH24小时制21
hh12小时制09
mm分钟49
ss30

注意:HH是24小时制,hh是12小时制。建议使用HH避免上午下午混淆。


三、完整代码实现

importjavafx.application.Application;importjavafx.event.ActionEvent;importjavafx.event.EventHandler;importjavafx.geometry.Insets;importjavafx.geometry.Pos;importjavafx.scene.Scene;importjavafx.scene.control.Label;importjavafx.scene.layout.BorderPane;importjavafx.scene.text.Font;importjavafx.stage.Stage;importjavafx.animation.KeyFrame;importjavafx.animation.Timeline;importjavafx.util.Duration;importjava.text.DateFormat;importjava.text.SimpleDateFormat;importjava.util.Date;publicclassRealTimeClockextendsApplication{@Overridepublicvoidstart(StageprimaryStage){// 1. 创建时间标签LabeltimeLabel=newLabel();timeLabel.setFont(newFont(20));// 设置字体大小为20// 2. 设置时间格式DateFormatdateFormat=newSimpleDateFormat("yyyy.MM.dd HH:mm:ss");// 3. 创建事件处理器:每秒更新时间EventHandler<ActionEvent>eventHandler=e->{StringcurrentTime=dateFormat.format(newDate());timeLabel.setText(currentTime);System.out.println(currentTime);// 控制台同步输出};// 4. 创建 Timeline 动画Timelineanimation=newTimeline(newKeyFrame(Duration.millis(1000),eventHandler));animation.setCycleCount(Timeline.INDEFINITE);// 无限循环animation.play();// 启动动画// 5. 布局设置:将时间标签放在右下角BorderPaneroot=newBorderPane();root.setPadding(newInsets(20));BorderPane.setAlignment(timeLabel,Pos.BOTTOM_RIGHT);root.setBottom(timeLabel);// 6. 创建场景Scenescene=newScene(root,400,300);primaryStage.setTitle("JavaFX 实时时钟");primaryStage.setScene(scene);primaryStage.show();}publicstaticvoidmain(String[]args){launch(args);}}

四、运行效果展示

4.1 界面效果

窗口右下角显示当前时间,每秒自动刷新。同时控制台也会每秒打印一次时间日志。

4.2 控制台输出

2026.06.13 21:49:00 2026.06.13 21:49:01 2026.06.13 21:49:02 2026.06.13 21:49:03 ...

五、关键代码解析

5.1 Timeline 的工作原理

Timelineanimation=newTimeline(newKeyFrame(Duration.millis(1000),eventHandler));
  • Duration.millis(1000):每隔 1000 毫秒(1秒)触发一次
  • eventHandler:每次触发时执行的事件
  • setCycleCount(Timeline.INDEFINITE):无限重复,不会自动停止

Timeline 执行流程

启动 (play) ├── 等待 1000ms ├── 执行 eventHandler(更新时间) ├── 等待 1000ms ├── 执行 eventHandler(更新时间) └── ...无限循环

5.2 为什么用 Timeline 而不是 Thread?

方式优点缺点
TimelineJavaFX 原生支持,自动在 UI 线程更新,线程安全精度受限于 JavaFX 帧率
Thread + sleep简单直观需要手动调用Platform.runLater()更新 UI,容易出错
AnimationTimer适合高帧率动画(如游戏)每秒60次回调,不适合低频更新

对于每秒更新一次的需求,Timeline是最简洁、最安全的选择。


六、进阶:多功能时钟面板

将实时时间与其他功能结合,打造一个更实用的状态栏:

importjavafx.application.Application;importjavafx.geometry.Insets;importjavafx.geometry.Pos;importjavafx.scene.Scene;importjavafx.scene.control.Label;importjavafx.scene.layout.HBox;importjavafx.scene.text.Font;importjavafx.scene.text.FontWeight;importjavafx.stage.Stage;importjavafx.animation.KeyFrame;importjavafx.animation.Timeline;importjavafx.util.Duration;importjava.text.SimpleDateFormat;importjava.util.Date;publicclassStatusBarClockextendsApplication{privateLabeltimeLabel;privateLabelstatusLabel;privateintseconds=0;@Overridepublicvoidstart(StageprimaryStage){// 状态标签statusLabel=newLabel("系统运行中");statusLabel.setFont(Font.font(14));// 时间标签timeLabel=newLabel();timeLabel.setFont(Font.font("Consolas",FontWeight.BOLD,16));// 布局HBoxstatusBar=newHBox(20);statusBar.setAlignment(Pos.CENTER_RIGHT);statusBar.setPadding(newInsets(10,20,10,20));statusBar.getChildren().addAll(statusLabel,timeLabel);// Timeline:每秒更新Timelinetimeline=newTimeline(newKeyFrame(Duration.seconds(1),e->update()));timeline.setCycleCount(Timeline.INDEFINITE);timeline.play();Scenescene=newScene(statusBar,500,50);primaryStage.setTitle("状态栏时钟");primaryStage.setScene(scene);primaryStage.show();}privatevoidupdate(){// 更新时间SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");timeLabel.setText(sdf.format(newDate()));// 更新运行时长seconds++;if(seconds%5==0){statusLabel.setText("已运行 "+seconds+" 秒");}}publicstaticvoidmain(String[]args){launch(args);}}

七、总结

知识点要点
Timeline使用KeyFrame定义定时任务,INDEFINITE无限循环
SimpleDateFormat"yyyy.MM.dd HH:mm:ss"格式化当前时间
线程安全Timeline 自动在 JavaFX UI 线程执行,无需手动切换
字体设置new Font(20)Font.font("Consolas", FontWeight.BOLD, 16)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 5:20:57

TwinCAT授权丢了别慌!硬件更换、系统重装后的授权备份与迁移指南

TwinCAT授权资产管理&#xff1a;硬件更换与系统迁移中的授权保护策略 当价值数万元的TwinCAT授权因硬盘损坏或系统重装而突然失效时&#xff0c;工程师们往往面临两难抉择——是重新购买授权还是冒险尝试数据恢复&#xff1f;这种场景在工业自动化领域并不罕见。去年某汽车生产…

作者头像 李华
网站建设 2026/6/14 5:19:04

机器学习模型生产就绪:从Notebook到高可用服务的七层防护

1. 项目概述&#xff1a;当模型走出Jupyter&#xff0c;真正开始呼吸真实世界的空气“From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题本身就像一句暗号&#xff0c;专为那些在Jupyter里调通了模型、画出了漂亮ROC曲线、却在部署时被现实狠…

作者头像 李华
网站建设 2026/6/14 5:16:55

数据库复制没那么玄乎,但踩过的坑能写满一黑板

数据库复制没那么玄乎&#xff0c;但踩过的坑能写满一黑板 如果你正在折腾MySQL、PostgreSQL或者MongoDB的复制方案&#xff0c;或者被老板一句“把数据从生产库实时同步到报表库”搞得焦头烂额&#xff0c;那这篇文章就是写给你的。我不是来讲教科书理论的&#xff0c;而是想…

作者头像 李华