Reputation: 1432
I am trying to switch between 3 different AnchorPane
(on click of a Button
) with a FadeTransition
and below is my code,
public class TestSlide extends Application {
private ObjectBinding<Node> frontNode;
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
AnchorPane pane1 = new AnchorPane(new Button("1"));
AnchorPane pane2 = new AnchorPane(new Button("2"));
AnchorPane pane3 = new AnchorPane(new Button("3"));
root.getChildren().addAll(pane1, pane2, pane3);
handleAnimation(root);
BorderPane border= new BorderPane(root);
HBox bottom = new HBox(10);
Button front1 = new Button("Pane 1");
Button front2 = new Button("Pane 2");
Button front3 = new Button("Pane 3");
front1.setOnAction((ActionEvent event) -> {
pane1.toFront();
});
front2.setOnAction((ActionEvent event) -> {
pane2.toFront();
});
front3.setOnAction((ActionEvent event) -> {
pane3.toFront();
});
bottom.getChildren().addAll(front1, front2, front3);
border.setBottom(bottom);
Scene scene = new Scene(border,400,400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void handleAnimation(StackPane root) {
frontNode = Bindings.valueAt(root.getChildren(),
Bindings.size(root.getChildren()).subtract(1));
frontNode.addListener((obs, oldNode, newNode) -> {
SequentialTransition fadeOutIn = new SequentialTransition();
if (oldNode != null) {
FadeTransition fadeOut = new FadeTransition(Duration.millis(500), oldNode);
fadeOut.setToValue(0);
fadeOutIn.getChildren().add(fadeOut);
}
if (newNode != null) {
FadeTransition fadeIn = new FadeTransition(Duration.millis(500), newNode);
fadeIn.setFromValue(0);
fadeIn.setToValue(1);
fadeOutIn.getChildren().add(fadeIn);
}
fadeOutIn.play();
});
}
public static void main(String[] args) {
launch(args);
}
}
The handleAnimation
method is referenced from another SO post.
The problem is ,
After launching the application, Click on Pane 1 Button
. -> Transition will first show pane2
and then pane1
.
Now Click on Pane 3 Button
-> Transition will first show pane2
and then pane3
.
Now Click on Pane 2 Button
-> Transition will show pane2
and the problem mentioned in above 2 points doesn't appear again.
Why the transition shows pane2
before showing the actual pane in points 1 & 2 ? is it due to opacity setting ?
and why after point 3 the problem gets resolved ?
How can i make the transition work to FadeIn
and FadeOut
the respective Pane
without showing the third Pane ?
Upvotes: 3
Views: 408
Reputation: 82491
The issue here is that the initial state of the children of the StackPane
is wrong: All nodes have opacity 1. Your desired state when no animation is running has all the nodes but the last one fully transparent (opacity = 0) and the last one fully opaque (opacity = 1). You should be able to fix the issue by initializing the opacities properly:
root.getChildren().addAll(pane1, pane2, pane3);
// set opacity for all but the last child to 0
List<Node> children = root.getChildren();
for (int i = children.size()-2; i >= 0; i--) {
children.get(i).setOpacity(0);
}
Otherwise the following happens:
Just after pane1.toFront()
. Note that (SequentialTransition
makes sure that the state for the start of the animation is established.
The topmost node is the last child in the list and ----...
is put next to the visible "layer".
Pane 1: opacity = 0
Pane 3: opacity = 1 ------------------------------
Pane 2: opacity = 1
Now after the first half of the SequentialTransition
is done, this looks as follows:
Pane 1: opacity = 0
Pane 3: opacity = 0
Pane 2: opacity = 1 ------------------------------
And after the animation is completeled:
Pane 1: opacity = 1 ------------------------------
Pane 3: opacity = 0
Pane 2: opacity = 1
Using pane3.toFront()
produces similar results:
Pane 3: opacity = 0
Pane 1: opacity = 1 ------------------------------
Pane 2: opacity = 1
Pane 3: opacity = 0
Pane 1: opacity = 0
Pane 2: opacity = 1 ------------------------------
Pane 3: opacity = 1 ------------------------------
Pane 1: opacity = 0
Pane 2: opacity = 1
Upvotes: 4