javaFX实现倒计时
核心概念
-
Timeline
:-
Timeline
是JavaFX动画API的核心类,用于创建动画。它可以按照指定的时间间隔(Duration
)触发事件(KeyFrame
)。 -
可以将其视为一个定时器,每隔一段时间执行一些操作。
-
-
KeyFrame
:-
KeyFrame
定义了在特定的时间点要执行的操作。它包含一个Duration
和一个EventHandler<ActionEvent>
。 -
Duration
指定了从Timeline
开始到KeyFrame
执行的时间。 -
EventHandler<ActionEvent>
定义了在该时间点要执行的代码。
-
-
Duration
:Duration
类用于指定时间间隔。可以指定为秒(seconds)、毫秒(millis)、纳秒(nanos)等。
-
Label
:Label
用于显示倒计时的时间。可以通过setText()
方法更新Label
的文本内容。
-
JavaFX Application Thread:
- 在JavaFX应用程序中,所有的UI更新都必须在JavaFX Application Thread中进行。可以使用
Platform.runLater()
方法将代码提交到JavaFX Application Thread中执行。
- 在JavaFX应用程序中,所有的UI更新都必须在JavaFX Application Thread中进行。可以使用
代码实现
java
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class CountdownApp extends Application {
private static final int DEFAULT_SECONDS = 60; // 默认倒计时时长,单位秒
private Label countdownLabel;
private Timeline timeline;
private int remainingSeconds = DEFAULT_SECONDS;
private Button startButton;
private Button stopButton;
@Override
public void start(Stage primaryStage) {
countdownLabel = new Label(formatTime(remainingSeconds));
countdownLabel.setStyle("-fx-font-size: 48px;");
startButton = new Button("Start");
stopButton = new Button("Stop");
stopButton.setDisable(true); // 初始状态禁用停止按钮
startButton.setOnAction(event -> startCountdown());
stopButton.setOnAction(event -> stopCountdown());
VBox root = new VBox(10, countdownLabel, startButton, stopButton);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
Scene scene = new Scene(root, 400, 300);
primaryStage.setTitle("Countdown Timer");
primaryStage.setScene(scene);
primaryStage.show();
}
private void startCountdown() {
startButton.setDisable(true); // 禁用启动按钮
stopButton.setDisable(false); // 启用停止按钮
timeline = new Timeline(
new KeyFrame(Duration.seconds(1), event -> {
if (remainingSeconds > 0) {
remainingSeconds--;
Platform.runLater(() -> countdownLabel.setText(formatTime(remainingSeconds))); // 必须在fx线程更新UI
} else {
stopCountdown();
Platform.runLater(() -> countdownLabel.setText("Time's up!")); // 时间到,显示 Time's up!
}
})
);
timeline.setCycleCount(remainingSeconds); // 倒计时指定次数
timeline.setOnFinished(event -> { //倒计时完成
stopButton.setDisable(true);
startButton.setDisable(false);
});
timeline.play();
}
private void stopCountdown() {
if (timeline != null) {
timeline.stop();
}
stopButton.setDisable(true);
startButton.setDisable(false);
remainingSeconds = DEFAULT_SECONDS;
Platform.runLater(() -> countdownLabel.setText(formatTime(remainingSeconds)));
}
private String formatTime(int seconds) {
LocalTime time = LocalTime.ofSecondOfDay(seconds);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); // 格式化为 时:分:秒
return time.format(formatter);
}
public static void main(String[] args) {
launch(args);
}
}
代码解释
-
DEFAULT_SECONDS
:定义默认的倒计时秒数。 -
countdownLabel
:用于显示倒计时的标签。 -
timeline
:Timeline
对象,用于定时触发事件。 -
remainingSeconds
:存储剩余秒数的整数变量。 -
startButton
&stopButton
: 启动/停止 倒计时按钮 -
startCountdown
方法-
startButton.setDisable(true)
&stopButton.setDisable(false)
:启动时启动按钮禁用,停止按钮启用 -
KeyFrame中的实现:判断
remainingSeconds > 0
,否则停止倒计时,更新UI -
timeline.setCycleCount(remainingSeconds)
:设置Timeline
循环指定次数,次数等于remainingSeconds
。 -
timeline.setOnFinished(event -> {...})
: 设置倒计时结束后的处理,例如启用/禁用 按钮 -
Platform.runLater(() -> countdownLabel.setText(...))
使用Platform.runLater 更新UI。
-
-
stopCountdown
方法- 停止 timeline, 重置UI,重置
remainingSeconds
- 停止 timeline, 重置UI,重置