倒数计时器Java JavaFX

问题描述 投票:0回答:1

有人可以帮我在 JavaFX 中制作一个倒计时器吗?我需要从标签中获取时间(时间由滑块设置),并且我想查看每秒剩余的分钟和秒数。当按下按钮时应该开始倒计时。我搜索了 Stack Overflow,并尝试使用 ChatGPT 来完成此操作,但仍然遇到问题。这是 ChatGPT 给我的代码,但它不起作用。它说时间线未初始化。

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class CountdownTimer extends Application {
    private int hours;
    private int minutes;
    private int seconds;

   private Label timerLabel = new Label();

   public static void main(String[] args) {
       launch(args);
   }

    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox(10);
        root.setAlignment(Pos.CENTER);
        
        TextField hoursField = new TextField();
        hoursField.setPromptText("Hours");
        TextField minutesField = new TextField();
        minutesField.setPromptText("Minutes");
        TextField secondsField = new TextField();
        secondsField.setPromptText("Seconds");
        
        Button startButton = new Button("Start Timer");
        startButton.setOnAction(event -> {
            // Parse user input for hours, minutes, and seconds
            hours = Integer.parseInt(hoursField.getText());
            minutes = Integer.parseInt(minutesField.getText());
            seconds = Integer.parseInt(secondsField.getText());
            
            // Start the countdown timer
            startCountdown();
        });
        
        root.getChildren().addAll(hoursField, minutesField, secondsField,   startButton, timerLabel);
        
        Scene scene = new Scene(root, 300, 200);
        primaryStage.setTitle("Countdown Timer");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    private void startCountdown() {
        Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), event -> {
            // Decrease one second
            if (seconds > 0) {
                seconds--;
            } else {
                // If seconds reach zero, decrement minutes and set seconds to 59
                if (minutes > 0) {
                    minutes--;
                    seconds = 59;
                } else {
                    // If minutes reach zero, decrement hours and set minutes and seconds to 59
                    if (hours > 0) {
                        hours--;
                        minutes = 59;
                        seconds = 59;
                    } else {
                        // If hours, minutes, and seconds reach zero, stop the timer
                        hours = 0;
                        minutes = 0;
                        seconds = 0;
                        timeline.stop();
                    }
                }
            }
            // Update the label with the new values
            timerLabel.setText(String.format("Time Left: %02d:%02d:%02d", hours, minutes, seconds));
        }));
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }
}
java javafx timer countdown countdowntimer
1个回答
0
投票

消息“时间线可能未初始化”意味着您正在尝试在构建之前使用

timeline
。您在传递给时间轴构造函数的事件处理程序中调用
timeline.stop()
;由于构造函数尚未完成,编译器无法保证在事件处理程序运行时实际已为
timeline
分配了值。换句话说,
timeline
可能会被初始化。

解决此问题的一种方法是单独添加关键帧。这样,Timeline 构造函数就完全完成了:

Timeline timeline = new Timeline();
// Construction complete;  now timeline can be used in an event handler.

timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1), event -> {
    // Decrease one second
    if (seconds > 0) {
        seconds--;
    } else {
        // If seconds reach zero, decrement minutes and set seconds to 59
        if (minutes > 0) {
            minutes--;
            seconds = 59;
        } else {
            // If minutes reach zero, decrement hours and set minutes and seconds to 59
            if (hours > 0) {
                hours--;
                minutes = 59;
                seconds = 59;
            } else {
                // If hours, minutes, and seconds reach zero, stop the timer
                hours = 0;
                minutes = 0;
                seconds = 0;
                timeline.stop();
            }
        }
    }
    // Update the label with the new values
    timerLabel.setText(String.format("Time Left: %02d:%02d:%02d", hours, minutes, seconds));
}));

另一种方法是将

timeline
声明为私有字段,而不是局部变量。这是有效的,因为一旦封闭类完成了它自己的构造函数,每个字段都保证被初始化。 (如果您的代码从未为某个字段分配过值,则该字段将自动初始化为 null。)

© www.soinside.com 2019 - 2024. All rights reserved.