I am making a JavaFX program that uses multiple TranslateTransition
s to move multiple Node
s across a Pane
. I want the program to halt execution until after the transitions are complete.
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Stack Overflow MRE");
Pane root = new Pane();
Rectangle rect1 = new Rectangle(25, 100, Color.AQUA);
rect1.setX(10);
rect1.setY(10);
Rectangle rect2 = new Rectangle(25, 100, Color.BISQUE);
rect2.setX(465);
rect2.setY(10);
root.getChildren().addAll(rect1, rect2);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
for (int i = 0; i < 10; i++) {
if (i == 0) {
TranslateTransition translateRect1 = new TranslateTransition();
translateRect1.setNode(rect1);
translateRect1.setAutoReverse(true);
translateRect1.setCycleCount(1);
translateRect1.setToY(350);
translateRect1.setDuration(Duration.millis(5000));
translateRect1.play();
TranslateTransition translateRect2 = new TranslateTransition();
translateRect2.setNode(rect2);
translateRect2.setAutoReverse(true);
translateRect2.setCycleCount(1);
translateRect2.setToY(350);
translateRect2.setDuration(Duration.millis(5000));
translateRect2.play();
}
// The loop will continue iterating while the above transitions are still running
// I need the loop to pause until they complete
System.out.printf("The current iteration is %s\n", i);
}
}
public static void main(String[] args) {
launch(args);
}
}
In the above code sample, the two transitions occur simultaneously, which is what I want, however the loop continues before the transitions complete. I want the loop to pause until the transitions are complete, and then move on to the next iterations. How would I get the program to first complete the transitions before moving on to the rest of the code?
Just use an onFinished
handler for the transition after which you want the code to execute, e.g.
TranslateTransition translateRect2 = new TranslateTransition();
translateRect2.setNode(rect2);
translateRect2.setAutoReverse(true);
translateRect2.setCycleCount(1);
translateRect2.setToY(350);
translateRect2.setDuration(Duration.millis(5000));
translateRect2.setOnFinished(e -> {
System.out.println("Testing timing of output");
});
translateRect2.play();
// This line prints while the above transitions are still running
// System.out.println("Testing timing of output");
The solution for your edited question is essentially the same: refactor it in the obvious way so that the code that you want to run after the transitions is in the onFinished
handler:
TranslateTransition translateRect1 = new TranslateTransition();
translateRect1.setNode(rect1);
translateRect1.setAutoReverse(true);
translateRect1.setCycleCount(1);
translateRect1.setToY(350);
translateRect1.setDuration(Duration.millis(5000));
translateRect1.play();
TranslateTransition translateRect2 = new TranslateTransition();
translateRect2.setNode(rect2);
translateRect2.setAutoReverse(true);
translateRect2.setCycleCount(1);
translateRect2.setToY(350);
translateRect2.setDuration(Duration.millis(5000));
translateRect2.setOnFinished(e -> {
for (int i = 1; i < 10; i++) {
System.out.printf("The current iteration is %s\n", i);
}
});
translateRect2.play();
System.out.printf("The current iteration is 0\n");