JavaFX : StackPane Sequential Transition

10
August 13, 2019, at 10:10 PM

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 ,

  1. After launching the application, Click on Pane 1 Button. -> Transition will first show pane2 and then pane1.

  2. Now Click on Pane 3 Button -> Transition will first show pane2 and then pane3.

  3. 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 ?

Answer 1

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
READ ALSO
How can I convert this code to prepared-statement or statement in jdbc? [on hold]

How can I convert this code to prepared-statement or statement in jdbc? [on hold]

I'm trying to insert this values to a new table but eclipse doesn't read this query:

46
Taking multiple lines with multiple inputs in each Lines

Taking multiple lines with multiple inputs in each Lines

My requirement is to take multiple inputs from user on multiple lines

32
BouncyCastle get specific crypto algorithm classes to strip down size

BouncyCastle get specific crypto algorithm classes to strip down size

I'm creating a library that requires ECC (elliptic curve cryptography, secp256k1) algorithmAs of now, I'm using BouncyCastle and it works perfectly

45
How to use MicroProfile FaultTolerance in Liberty profile [on hold]

How to use MicroProfile FaultTolerance in Liberty profile [on hold]

I want to use the circuit break function in MP FaultTolerance feature in my web applicationNow I have no idea about how to know if this function has been working in my application

23