JavaFX:StackPane顺序转换

JavaFX:StackPane顺序转换,java,javafx,Java,Javafx,我正试图在3种不同的AnchorPane(点击按钮)和FadeTransition之间切换,下面是我的代码 public class TestSlide extends Application { private ObjectBinding<Node> frontNode; @Override public void start(Stage primaryStage) { StackPane root = new StackPane();

我正试图在3种不同的
AnchorPane
(点击
按钮
)和
FadeTransition
之间切换,下面是我的代码

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);
    }
}
公共类TestSlide扩展了应用程序{
私有对象绑定前端节点;
@凌驾
公共无效开始(阶段primaryStage){
StackPane root=新的StackPane();
锚烷面板1=新锚烷(新按钮(“1”));
锚烷面板2=新锚烷(新按钮(“2”));
锚烷窗格E3=新锚烷(新按钮(“3”));
root.getChildren().addAll(pane1、pane2、pane3);
手感(根);
BorderPane border=新的BorderPane(根);
HBox底部=新的HBox(10);
按钮前部1=新按钮(“窗格1”);
按钮前部2=新按钮(“窗格2”);
按钮前部3=新按钮(“窗格3”);
front1.setOnAction((ActionEvent事件)->{
窗格1.toFront();
});
front2.setOnAction((ActionEvent事件)->{
pane2.toFront();
});
front3.setOnAction((ActionEvent事件)->{
窗格3.toFront();
});
bottom.getChildren().addAll(front1、front2、front3);
边框。立根底部(底部);
场景=新场景(边框,400400);
初级阶段。场景(场景);
primaryStage.show();
}
私有void handleAnimation(堆栈窗格根){
frontNode=Bindings.valueAt(root.getChildren(),
Bindings.size(root.getChildren()).subtract(1));
frontNode.addListener((obs、oldNode、newNode)->{
顺序转换淡出=新的顺序转换();
if(oldNode!=null){
FadeTransition淡出=新的淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出淡出;
衰减设置值(0);
fadeOut.getChildren().add(fadeOut);
}
if(newNode!=null){
FADETRANSION fadeIn=新的FADETRANSION(持续时间.毫秒(500),新节点);
fadeIn.setFromValue(0);
fadeIn.setToValue(1);
fadeOutIn.getChildren().add(fadeIn);
}
fadeOutIn.play();
});
}
公共静态void main(字符串[]args){
发射(args);
}
}
handleAnimation
方法引用自另一个SO帖子

问题是,

  • 启动应用程序后,单击窗格1
    按钮
    ->转换将首先显示
    pane2
    ,然后显示
    pane1

  • 现在点击窗格3
    按钮
    ->转换将首先显示
    窗格2
    ,然后显示
    窗格3

  • 现在单击窗格2
    按钮
    ->转换将显示
    窗格2
    ,上述两点中提到的问题不再出现

  • 为什么在第1点和第2点显示实际窗格之前,转换显示
    pane2
    ?这是由于不透明度设置造成的吗

    为什么在第三点之后问题得到解决


    如何在不显示第三个窗格的情况下将转换工作转换到相应的
    窗格
    淡出

    这里的问题是
    堆栈窗格
    子节点的初始状态错误:所有节点的不透明度均为1。没有运行动画时所需的状态具有所有节点,但最后一个节点完全透明(不透明度=0)和最后一个节点完全不透明(不透明度=1)。您应该能够通过正确初始化不透明度来解决此问题:

    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);
    }
    
    现在,在
    顺序转换的前半部分完成后,如下所示:

    Pane 1: opacity = 0
    Pane 3: opacity = 0
    Pane 2: opacity = 1 ------------------------------
    
    动画完成后:

    Pane 1: opacity = 1 ------------------------------
    Pane 3: opacity = 0
    Pane 2: opacity = 1
    
    使用
    pane3.toFront()
    会产生类似的结果:

    Pane 3: opacity = 0
    Pane 1: opacity = 1 ------------------------------
    Pane 2: opacity = 1
    

    我没有这样做,但我想你可以跟踪前节点。单击按钮后,在该节点上运行淡出转换。使用过渡的onfinished在新的front节点上开始淡入。确保用淡入的节点替换旧的正面。
    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