使用LineTo,MoveTo通过路径转换将按钮移动到JavaFX中的指定坐标

时间:2015-04-12 21:10:42

标签: java animation button javafx transition

我制作的动画涉及移动表示网络中传输数据的按钮。到目前为止,我已经能够通过更新LayoutX和LayoutY字段以及使用顺序转换将按钮移动到动画不同阶段的不同位置。

但是现在我试图让名为蓝色的按钮从一个阶段的位置沿着对角线移动到"路由器3,"它位于按钮的右侧和右侧。目的地的确切布局坐标是426(x)和364(y),并且起始位置的布局坐标是309(x)和585(y)。我一直在尝试使用moveTo和LineTo来获得上述坐标的按钮,但由于两个原因,它很难证明:

首先,我使用转换来获取起始坐标,因此按钮到达起始位置时的实际坐标是LayoutX:14,LayoutY:445,TranslateX:295 ,翻译Y:140。 我尝试用代码纠正这个问题:

        blue.setLayoutX(blue.getLayoutX() + blue.getTranslateX());
        blue.setLayoutY(blue.getLayoutY() + blue.getTranslateY());
        blue.setTranslateX(0);
        blue.setTranslateY(0);

然后将蓝色的路径定义为:

        Path path = new Path();
        MoveTo start = new MoveTo();
        start.setX(blue.getTranslateX());
        start.setY(blue.getTranslateY());
        path.getElements().add(start);
        path.getElements().add(new LineTo(125.0f, -220.0f));
        PathTransition pathTransition = new PathTransition();
        pathTransition.setDuration(Duration.millis(1000));
        pathTransition.setPath(path);
        pathTransition.setNode(blue);
        pathTransition.setCycleCount((int) 1f);
        pathTransition.setAutoReverse(false);
        pathTransition.play();

但这似乎是一个麻烦的解决方法。例如,该程序的下一个阶段有按钮遍历多个路由器的网络"根据Dijkstra的算法,我希望能够直接定义直线到下一个路由器的线路径,而不必在每个阶段摆弄翻译和布局坐标。或者,例如,Swing可以重新绘制圆形,同时逐个像素地更新其坐标,以便制作对角线动画并在到达某个位置后停止。这可以使用JavaFX吗?

其次,即使这个动画开始实施,按钮似乎也会跳回来#34;稍微好一点,就好像要走的路径的起点是按钮实际所在位置的左边几个像素,尽管据我所知,我已经指定路径的起点准确无误按钮在动画开始之前的位置。这有什么特别的原因吗?

感谢您提出与我的问题有关的任何帮助;这是我第一次使用StackOverflow。我非常确定我会彻底搜索这个问题的答案,但如果这是重复的话,我很抱歉。

1 个答案:

答案 0 :(得分:0)

这是一个已知问题,你可以在Create a path transition with absolute coordinates for a StackPane object主题中阅读它。

不幸的是,您必须解决该问题,JavaFX中没有解决方案。幸运的是,解决方案很简单,只需使用MoveTo和LineTo的修改版本即可。

这是一个经过修改的示例代码。只需点击场景中的某个位置,节点就会移动到那里,而不会跳过"跳跃"。

public class PathTransitionExample extends Application {

    PathTransition transition;

    @Override
    public void start(Stage primaryStage) throws Exception {

        Group root = new Group();

        // create movable object
        Rectangle rect = new Rectangle(50, 50);
        rect.setStroke(Color.BLUE);
        rect.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.3));
        rect.relocate(100, 80);
        root.getChildren().add(rect);

        Label label = new Label("Click on scene to set destination");
        label.relocate(0, 0);
        root.getChildren().add(label);

        // init transition
        transition = new PathTransition();
        transition.setNode(rect);
        transition.setDuration(Duration.seconds(2));

        Scene scene = new Scene(root, 1024, 768);

        scene.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {

            @Override
            public void handle(Event event) {

                transition.stop();

                setPositionFixed( rect);

                double toX = ((MouseEvent) event).getX();
                double toY = ((MouseEvent) event).getY();

                Path path = new Path();
                path.getElements().add(new MoveToAbs(rect));
                path.getElements().add(new LineToAbs(rect, toX, toY));

                transition.setPath(path);
                transition.play();

            }

            // change layout to current position, reset translate
            private void setPositionFixed( Node node) {
                double x = rect.getLayoutX() + rect.getTranslateX();
                double y = rect.getLayoutY() + rect.getTranslateY();
                rect.relocate(x, y);
                rect.setTranslateX(0);
                rect.setTranslateY(0);
            }

        });

        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static class MoveToAbs extends MoveTo {

        public MoveToAbs(Node node) {
            super(node.getLayoutBounds().getWidth() / 2, node.getLayoutBounds().getHeight() / 2);
        }

        public MoveToAbs(Node node, double x, double y) {
            super(x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
        }

    }

    public static class LineToAbs extends LineTo {

        public LineToAbs(Node node, double x, double y) {
            super(x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
        }

    }

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

}