简体   繁体   English

具有多个节点的JavaFx Transition Animation

[英]JavaFx Transition Animation with multiple nodes

I am trying to implement a Transition effect on a node, below is SSCE, 我正在尝试在节点上实现Transition效果,下面是SSCE,

public class GridPaneExperiments extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Experiment");

        Button button2 = new Button("Expand");
        Button button3 = new Button("Button 3");
        Button button4 = new Button("Button 4");

        GridPane gridPane = new GridPane();

        ToolBar bar = new ToolBar();
        bar.getItems().addAll(button3, button4);

        gridPane.add(button2, 0, 0, 1, 1);
        gridPane.add(bar, 1, 0, 1, 1);

        //Handle Mouse on Button
        button2.setOnMouseEntered((MouseEvent event) -> {
            TranslateTransition openNav = new TranslateTransition(new Duration(350), bar);
            openNav.setToX(0);
            if (bar.getTranslateX() != 0) {
                openNav.play();
            }
        });

        button2.setOnMouseExited((MouseEvent event) -> {
            TranslateTransition closeNav = new TranslateTransition(new Duration(350), bar);
            closeNav.setToX(-(((GridPane) gridPane).getWidth()));
            closeNav.play();
        });
        //Handle Mouse on ToolBar
        bar.setOnMouseExited((MouseEvent event) -> {
            TranslateTransition closeNav = new TranslateTransition(new Duration(350), bar);
            closeNav.setToX(-(((GridPane) gridPane).getWidth()));
            closeNav.play();
        });

        bar.setOnMouseEntered((MouseEvent event) -> {
            TranslateTransition openNav = new TranslateTransition(new Duration(350), bar);
            openNav.setToX(0);
            if (bar.getTranslateX() != 0) {
                openNav.play();
            }
        });

        Scene scene = new Scene(gridPane, 240, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

What I am trying to achieve is: 我想要实现的是:

  1. When mouse entered the Button " Expand " a Node will be opened to its right, after which if mouse entered the opened node it should not get close . 当鼠标进入ButtonExpand ”时,将在其右侧打开一个Node ,此后,如果鼠标进入打开的节点,则该节点不会关闭。

  2. When mouse entered the Button " Expand " a Node will be opened and mouse exited from Button "Expand" (but not entered the opened node) , then the opened node should be closed. 当鼠标进入ButtonExpand ”时,将打开一个Node并且鼠标从按钮“ Expand”退出(但未进入打开的节点),则应关闭打开的节点。

Currently I am playing the Transition animation in Mouse events of both Button and Node. 目前,我正在Button和Node的Mouse事件中播放Transition动画。

How can I achieve this? 我该如何实现?

Just use a single animation for closing and opening. 只需使用一个动画即可关闭和打开。 This way you can reverse the animation easily, don't run the risk of starting multiple animations in parallel and starting a closing animation is not an issue, since you change the animation to a opening animation when entering one of the nodes: 这样,您可以轻松地反转动画,而不必冒着并行启动多个动画的风险,而关闭动画的启动也不成问题,因为在输入一个节点时将动画更改为开始动画:

@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Experiment");

    Button button2 = new Button("Expand");
    Button button3 = new Button("Button 3");
    Button button4 = new Button("Button 4");

    GridPane gridPane = new GridPane();

    ToolBar bar = new ToolBar();
    bar.getItems().addAll(button3, button4);
    bar.setTranslateX(-10000); // somewhere outside view

    gridPane.add(button2, 0, 0, 1, 1);
    gridPane.add(bar, 1, 0, 1, 1);

    TranslateTransition transition = new TranslateTransition(Duration.millis(300), bar);
    transition.setToX(0);

    EventHandler<MouseEvent> enterHandler = (MouseEvent event) -> {
        transition.setFromX(-gridPane.getWidth());
        Duration time = transition.getCurrentTime();
        transition.setRate(1);
        transition.playFrom(time);
    };

    EventHandler<MouseEvent> exitHandler = (MouseEvent event) -> {
        if (!(button2.isHover() || bar.isHover())) {
            Duration time = transition.getCurrentTime();
            transition.setRate(-1);
            transition.playFrom(time);
        }
    };

    //Handle Mouse on Button
    button2.setOnMouseEntered(enterHandler);
    bar.setOnMouseEntered(enterHandler);
    button2.setOnMouseExited(exitHandler);
    bar.setOnMouseExited(exitHandler);


    Scene scene = new Scene(gridPane, 240, 100);
    primaryStage.setScene(scene);
    primaryStage.show();
}

you can simply achive your task using a helper HBox and setting setOnMouseExited to only that: 您可以使用助手HBox并将setOnMouseExited设置为仅完成以下任务:

public class GridPaneExperiments extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Experiment");

        Button button2 = new Button("Expand");
        Button button3 = new Button("Button 3");
        Button button4 = new Button("Button 4");

        ToolBar bar = new ToolBar();
        bar.getItems().addAll(button3, button4);

        GridPane gridPane = new GridPane();

        HBox hbox = new HBox(button2, bar);
        hbox.setStyle("-fx-border-color: red");

        gridPane.add(hbox, 0, 0);

        //Handle Mouse on Button
        button2.setOnMouseEntered((MouseEvent event) -> {
            TranslateTransition openNav = new TranslateTransition(new Duration(350), bar);
            openNav.setToX(0);
            if (bar.getTranslateX() != 0) {
                openNav.play();
            }
        });

//        button2.setOnMouseExited((MouseEvent event) -> {
//            TranslateTransition closeNav = new TranslateTransition(new Duration(350), bar);
//            closeNav.setToX(-(((GridPane) gridPane).getWidth()));
//            closeNav.play();
//        });
        //Handle Mouse on ToolBar
        hbox.setOnMouseExited((MouseEvent event) -> {
            TranslateTransition closeNav = new TranslateTransition(new Duration(350), bar);
            closeNav.setToX(-(((GridPane) gridPane).getWidth()));
            closeNav.play();
        });

//        bar.setOnMouseEntered((MouseEvent event) -> {
//            TranslateTransition openNav = new TranslateTransition(new Duration(350), bar);
//            openNav.setToX(0);
//            if (bar.getTranslateX() != 0) {
//                openNav.play();
//            }
//        });

        Scene scene = new Scene(gridPane, 240, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM