如何在javafx中重新启动计时器?

iecba09b  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(391)

我目前正在开发一个程序,在这个程序中,用户可以为不同的练习创建自己的准时间隔。按下“开始”按钮后,第一个练习开始倒计时。一旦完成,就会播放一个声音,第二个开始倒计时,依此类推,直到所有练习都完成并移除。我用一个计时器,每过1秒,把练习的时间减去1。问题是,我似乎找不到在java中重新启动计时器的方法。当所有的练习完成后,我可以停止计时器,但我似乎找不到一种方法来重新启动它,当我想创建新的练习,并再次通过这个过程。我也找不到方法在特定的进程中暂停并再次播放计时器。我是javafx新手,所以如果您能指导我如何更改代码以实现所需,我将非常感激。

Timer timer = new Timer();
startButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        //Timer task=new TimerTask();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                running=true;
                if (running==true)
                {
                    if (workoutsList.size() == 0) {
                        return;
                    }
                    if (workoutsList.size() == 1 && workoutsList.get(0).time == 1) {
                        text.setText("over!");
                        mediaPlayer1.play();
                        workoutsList.clear();
                        workouts.getItems().clear();
                        timer.cancel();
                        return;
                    }
                    workoutsList.get(0).time -= 1;
                    if (workoutsList.get(0).time == 0) {
                        workoutsList.remove(0);
                        mediaPlayer.play();
                        return;
                    }
                    workouts.getItems().clear();
                    workouts.refresh();
                    for (int i = 0; i < workoutsList.size(); i++) {
                        workouts.getItems().add(workoutsList.get(i));
                    }
                }
            }
        }, 0, 1000);
    }
});
stopButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        timer.cancel();
        running=false;
    }
});
yhuiod9q

yhuiod9q1#

自从 Timer 除了赛道时间什么都不做最好用 javafx.animation 应用程序编程接口。这给了您一些好处:
一切都发生在javafx应用程序线程上,这意味着没有并发问题。
你可以利用 currentTime 以及 cycleDuration 的属性 Animation 追踪倒计时的剩余时间。
你可以利用 play() , pause() ,和 stop() 方法 Animation 控制计时器。
你可以用 onFinished 财产 Animation 当计时器完成时播放声音。
下面是一个使用 PauseTransition ,尽管您也可以使用例如。 Timeline .

import javafx.animation.Animation;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
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.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    // javafx.util.Duration
    PauseTransition timer = new PauseTransition(Duration.minutes(5));
    // timer.setOnFinished(e -> /* play sound */);

    Button startBtn = new Button("Start");
    startBtn.setOnAction(e -> timer.play());

    Button pauseBtn = new Button("Pause");
    pauseBtn.setOnAction(e -> timer.pause());

    Button resetBtn = new Button("Reset");
    resetBtn.setOnAction(e -> timer.stop());

    Label label = new Label();
    label.setFont(Font.font("Monospaced", 20));
    label.textProperty().bind(timeLeftAsString(timer));

    HBox hbox = new HBox(10, startBtn, pauseBtn, resetBtn);
    hbox.setAlignment(Pos.CENTER);

    VBox root = new VBox(25, label, hbox);
    root.setPadding(new Insets(25));
    root.setAlignment(Pos.CENTER);

    primaryStage.setScene(new Scene(root));
    primaryStage.show();
  }

  private StringBinding timeLeftAsString(Animation animation) {
    return Bindings.createStringBinding(
        () -> {
          double currentTime = animation.getCurrentTime().toMillis();
          double totalTime = animation.getCycleDuration().toMillis();
          long remainingTime = Math.round(totalTime - currentTime);
          // java.time.Duration
          java.time.Duration dur = java.time.Duration.ofMillis(remainingTime);
          return String.format(
              "%02d:%02d:%03d", dur.toMinutes(), dur.toSecondsPart(), dur.toMillisPart());
        },
        animation.currentTimeProperty(),
        animation.cycleDurationProperty());
  }
}

旁注:您提到计时器完成时会播放声音,我可以看到对的调用 mediaPlayer.play() . 考虑到节目的性质,我认为播放的声音相对较短。如果是这样的话,你应该考虑使用 AudioClip 而不是 MediaPlayer .

相关问题