如何使JavaFXTimeline增加一秒并绑定到Progressbar?

如何使JavaFXTimeline增加一秒并绑定到Progressbar?,java,javafx,Java,Javafx,我正在尝试创建一个系统,其中使用时间线记录一分钟的持续时间。在这种情况下,我希望时间线每秒递增,并让Progressbar在调用操作和重置时间线之前记录到1分钟 final Timeline timeline = new Timeline(); timeline.setCycleCount(Animation.INDEFINITE); timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1))); progress.progress

我正在尝试创建一个系统,其中使用时间线记录一分钟的持续时间。在这种情况下,我希望时间线每秒递增,并让Progressbar在调用操作和重置时间线之前记录到1分钟

final Timeline timeline = new Timeline();
timeline.setCycleCount(Animation.INDEFINITE);
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1)));
progress.progressProperty().bind(timeline.getTotalDuration()???);
timeline.play();
我已经将周期计数设置为不确定,这样时间线周期就不会停止。我还尝试将Progressbar属性绑定到timeline,但它需要一个observeValue,而
timeline\getTotalDuration
不提供该值

我尝试在没有绑定的情况下在单独的线程上运行程序:

new Thread(new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                while(true){
                    System.out.printf("s:\t%f\n",timeline.getTotalDuration().toSeconds());
                    Thread.sleep(1000);
                }
            }
}).start();
新线程(新任务(){
@凌驾
受保护的Void调用()引发异常{
while(true){
System.out.printf(“s:\t%f\n”,timeline.getTotalDuration().toSeconds());
睡眠(1000);
}
}
}).start();
然而,运行它不会增加每秒的计时器,而是一次完成所有周期。由于我设置的循环计数是不确定的,因此总持续时间的结果是不确定的


我如何让时间线一秒一秒地工作,如何将持续时间绑定到Progressbar,直到它达到100%,以便调用我的特殊操作?

如果您只想在一分钟内将进度条从零重复增加到满,并在每分钟结束时执行代码,您只需:

    ProgressBar progress = new ProgressBar();
    Timeline timeline = new Timeline(
        new KeyFrame(Duration.ZERO, new KeyValue(progress.progressProperty(), 0)),
        new KeyFrame(Duration.minutes(1), e-> {
            // do anything you need here on completion...
            System.out.println("Minute over");
        }, new KeyValue(progress.progressProperty(), 1))    
    );
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();
这将为进度条创建一个“模拟”效果,即它不会每秒递增,而是在整分钟内平稳地递增

如果确实希望每秒递增,请使用
IntegerProperty
表示秒数,并将进度条的进度属性绑定到它:

    ProgressBar progress = new ProgressBar();
    IntegerProperty seconds = new SimpleIntegerProperty();
    progress.progressProperty().bind(seconds.divide(60.0));
    Timeline timeline = new Timeline(
        new KeyFrame(Duration.ZERO, new KeyValue(seconds, 0)),
        new KeyFrame(Duration.minutes(1), e-> {
            // do anything you need here on completion...
            System.out.println("Minute over");
        }, new KeyValue(seconds, 60))   
    );
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();
这里的要点是,
IntegerProperty
将在0和60之间插值,但只接受整数值(即,它将插值截断为
int

以下是第二个版本的SSCCE:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class OneMinuteTimer extends Application {

    @Override
    public void start(Stage primaryStage) {
        ProgressBar progress = new ProgressBar();
        progress.setMinWidth(200);
        progress.setMaxWidth(Double.MAX_VALUE);
        IntegerProperty seconds = new SimpleIntegerProperty();
        progress.progressProperty().bind(seconds.divide(60.0));
        Timeline timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(seconds, 0)),
            new KeyFrame(Duration.minutes(1), e-> {
                // do anything you need here on completion...
                System.out.println("Minute over");
            }, new KeyValue(seconds, 60))   
        );
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();

        StackPane root = new StackPane(progress);
        root.setPadding(new Insets(20));
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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