Issue
public class App extends javafx.application.Application {
@Override
public void start(Stage primaryStage) {
var root = new Pane();
var button = new Button("Change");
button.setLayoutX(225);
button.setLayoutY(300);
var rectangle = new Rectangle(150, 50, 200, 200);
var effect = new BoxBlur(0, 0, 1);
var text = new Text("POKUS");
text.setLayoutX(230);
text.setLayoutY(270);
text.setEffect(effect);
button.setOnMouseClicked((event) -> {
event.consume();
var random = new Random();
var fill = new FillTransition(Duration.seconds(1), rectangle, (Color) rectangle.getFill(), Color.color(random.nextFloat(), random.nextFloat(), random.nextFloat()));
var timeline = new Timeline(
new KeyFrame(Duration.millis(500),
new KeyValue(effect.widthProperty(), 10),
new KeyValue(effect.heightProperty(), 10)
)
);
var timeline2 = new Timeline(
new KeyFrame(Duration.millis(500),
new KeyValue(effect.widthProperty(), 0),
new KeyValue(effect.heightProperty(), 0)
)
);
timeline.setOnFinished((event2) -> {
var number = random.nextInt(10) + 1;
var word = "";
for (var i = 0; i < number; i++) {
word += (char) ('a' + random.nextInt(26));
}
text.setText(word);
text.setEffect(effect);
timeline2.play();
});
new ParallelTransition(fill, timeline).play();
});
root.getChildren().addAll(button, rectangle, text);
var scene = new Scene(root, 500, 500);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This demonstrates my problem.
The program only contains a rectangle, text, and a button that runs the animation of the color change of the rectangle and the text change - in both cases randomly.
However, the rectangle animation takes a second and the text animation takes twice a half second.
In addition, at the end of the first text animation, the text must be generated.
The difference is likely to be slight, but I want to ask if it is possible to adjust the time of the second text animation (timeline2
) to end at the same time as the rectangle animation (fill
)?
Please help
Thank you
Solution
You can use a Timeline
to animate the fill
property. Furthermore you don't need to use more than a single timeline to do all the animations:
button.setOnAction((event) -> { // better to use ActionEvent to listen to button activation
event.consume();
var random = new Random();
Color currentColor = (Color) rectangle.getFill();
Color targetColor = Color.color(random.nextFloat(), random.nextFloat(), random.nextFloat());
var timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rectangle.fillProperty(), currentColor)),
new KeyFrame(Duration.millis(500),
evt -> {
var number = random.nextInt(10) + 1;
var word = "";
for (var i = 0; i < number; i++) {
word += (char) ('a' + random.nextInt(26));
}
text.setText(word);
},
new KeyValue(effect.widthProperty(), 10),
new KeyValue(effect.heightProperty(), 10)
), new KeyFrame(Duration.millis(1000),
new KeyValue(effect.widthProperty(), 0),
new KeyValue(effect.heightProperty(), 0),
new KeyValue(rectangle.fillProperty(), targetColor)
)
);
timeline.play();
});
Answered By - fabian