简体   繁体   中英

How to use Timeline to perform a void method every x seconds on JavaFX?

The problem:

I'm trying to use Timeline to call a void method action() every 0.5 seconds. I have researched how to do this and looked at similar questions on this site, but none are working out for me.

What I have tried #1:

Duration sec = Duration.ofSeconds((long) 0.5);
this.timeline = new Timeline(new KeyFrame(sec, e -> {
    action();
}));

The error the above caused: "The constructor KeyFrame(Duration, ( e) -> {}) is undefined".

What I have tried #2:

this.timeline = new Timeline(new KeyFrame(Duration.ofSeconds((long) 0.5), new EventHandler<ActionEvent>() 
        {

            @Override
            public void handle(ActionEvent event) {
                action();
            }
            }));

The error the above caused: "The constructor KeyFrame(Duration, new EventHandler(){}) is undefined".

Thanks in advance for any help.

Based on this line:

Duration sec = Duration.ofSeconds((long) 0.5);

Note: Casting 0.5 to a long will simply give you 0 .

You are using the wrong Duration class. The above indicates you're using java.time.Duration when you need to be using javafx.util.Duration . Remove the import statement for the former and replace it with one for the latter. Then change the above line to:

Duration sec = Duration.seconds(0.5);

Notice the static method for the JavaFX Duration class is named seconds , not ofSeconds . Also, if you want the Timeline to repeatedly call your method every 0.5 seconds then you need to set its cycle count to Animation#INDEFINITE .

Here's an example:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class App extends Application {

  private Label label;
  private int count;

  @Override
  public void start(Stage primaryStage) {
    label = new Label();

    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0.5), e -> incrementLabel()));
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.playFromStart();

    primaryStage.setScene(new Scene(new StackPane(label), 500, 300));
    primaryStage.show();
  }

  private void incrementLabel() {
    label.setText(String.format("%,d", count++));
  }
}

Note: "Incrementing" the text of the Label could be done directly in the EventHandler , but I moved it to a void method to better fit your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM