1

I have a node which is a child of a "local" group which is a child of a "global" group. I want to translate the child in the coordinates of the global group but TranslateTransition moves it in the local group coordinates.

In this example I have this parent hierarchy:

parent group
|- red circle
|- child group
  |- blue circle

I want to get the blue circle on top of the red circle. If I translate it to the coordinates of the red circle it moves away from it because it's in its own group. If i translate the whole group it works.

import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AnimTest extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Circle c = new Circle(5, Color.BLUE);
        Group group = new Group(c);
        group.setTranslateX(40);
        group.setTranslateY(50);

        Circle target = new Circle(10, Color.RED);
        target.setTranslateX(20);
        target.setTranslateY(20);

        Group parent = new Group(target, group);

        TranslateTransition t1 = new TranslateTransition(Duration.seconds(1), c); // 'group' works
        t1.setToX(target.getTranslateX());
        t1.setToY(target.getTranslateY());

        Button next = new Button("Play");
        next.setOnAction(e -> t1.play());

        Pane p = new Pane(parent);
        p.setPrefSize(200, 200);
        VBox root = new VBox(p, next);
        stage.setScene(new Scene(root));
        stage.show();
    }

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

How do I make the translation of the blue circle in the coordinates of the parent of the red circle?

Please understand that this is a simple example. In truth the hierarchy is bigger and looks something like

parent group
|- target node
|- group1
  |- group2
    |- group3
      |- moving node

And also i can use the bounds of the target and not its translate properties to find the final destination but translate were enough for the example.

Mark
  • 2,167
  • 4
  • 32
  • 64
  • `Node` provides many methods for converting coordinates to different spaces: [`Node.parentToLocal`](https://docs.oracle.com/javase/10/docs/api/javafx/scene/Node.html#parentToLocal(double,double)), [`Node.localToParent`](https://docs.oracle.com/javase/10/docs/api/javafx/scene/Node.html#localToParent(double,double)), etc... – Slaw Aug 21 '18 at 13:02

2 Answers2

2

You can combine Node.localToScene and Node.sceneToLocal to convert between coordinate systems in the same scene (assuming the transformations are invertible and you don't scale by 0 or something like this).

private static Point2D convertCoordinater(Node source, Node target, double x, double y) {
    Point2D sceneCoords = source.localToScene(x, y);
    return target.sceneToLocal(sceneCoords);
}
Point2D targetCoordinates = convertCoordinater(parent, group, target.getTranslateX(), target.getTranslateY());
t1.setToX(targetCoordinates.getX());
t1.setToY(targetCoordinates.getY());
fabian
  • 80,457
  • 12
  • 86
  • 114
  • I don't understand why `parent` is `source` and `group` is `target`. Isn't the source `c` and the target `target`? – Mark Aug 21 '18 at 18:36
  • @Mark the center of the circle is at `(circle.translateX, circle.translateY)` in the coordinate system of the parent of `circle`. Therefore you need to convert between the coordinate systems of those nodes. You could of course pass `x=0; y=0`, but if you pass `target` as second parameter, any transformation applies to `target` is likely to lead to incorrect results... – fabian Aug 21 '18 at 23:38
  • @Mark Firstly, you need to work with the parents of the nodes you want to move and "to target" because the nodes exist in their coordinate system, not in their own coordinate system. Secondly, the `source` is the node that owns the coordinate you want convert for the use of a node in `target`. `target` here is not your `target`, it's the parent of the node you want to move to your `target`. – user1803551 Aug 22 '18 at 18:30
0

You can translate any node using setTranslateX() and setTranslateY() the problem is how to know the amount you need to translate in each direction
you can do so by get the bounds of the Node you wanna move like so

Bounds nodeBounds = node.localToScreen(node.getBoundInLocal());

and also the bounds of the target node and then you can translate using their bounds I hope this might help

Ahmed Emad
  • 674
  • 6
  • 19