Why changing translate property of one Shape in JavaFX Group affects other Shapes after changing Scale of Group

pollux :

I am working on a program in which I am learning about zooming and moving objects in JavaFX. For my program I am using Group and in the Group I have two Rectangle and I have some Sliders to change properties of both Rectangle.

Problem that occurred is that when I change translateX or translateY of the Rectangle in the program, keeping the ScaleX and ScaleY of parent Group other than 1, it also changes the position of another Rectangle but when the scale is 1 this problem does not occur.

Here is my program:

In my program I have two Rectagle called a and b and I am using Slider called aTranslateX & aTranslateY and bTranslateX & bTranslateY to change translateX and translateY of Rectagles a and b respectively. And I am using another Slider called scale to change scaleX & scaleY of Group called group which contains a and b. Again the problem does not occur when I change translate properties of rectangles a and b keeping scale(scaleX & scaleY) of the group but when I change their(of rectangles a and b) translate properties keeping scale other than one changing translate property of one rectangle also changes position of another rectangle in opposite direction of change.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Example extends Application{

    private Group group;

    public static void main(String... arguments){launch(arguments);}

    @Override public void start(Stage primaryStage){
        Rectangle a = new Rectangle(200, 200, Color.WHITE);
        Rectangle b = new Rectangle(200, 200, Color.SKYBLUE);
        a.setStroke(Color.BLACK);
        b.setStroke(Color.MAGENTA);
        group = new Group(a, b);

        Slider aTranslateX = new Slider(-1600, 1600, 20);
        Slider aTranslateY = new Slider(-1600, 1600, 20);
        Slider bTranslateX = new Slider(-1600, 1600, 20);
        Slider bTranslateY = new Slider(-1600, 1600, 20);
        Slider scale = new Slider(0, 12, 1);

        aTranslateX.valueProperty().addListener((o, l, c) -> {
            if(c != null) b.setTranslateX(c.doubleValue());
        });
        aTranslateY.valueProperty().addListener((o, l, c) -> {
            if(c != null) b.setTranslateY(c.doubleValue());
        });
        bTranslateX.valueProperty().addListener((o, l, c) -> {
            if(c != null) a.setTranslateX(c.doubleValue());
        });
        bTranslateY.valueProperty().addListener((o, l, c) -> {
            if(c != null) a.setTranslateY(c.doubleValue());
        });
        scale.valueProperty().addListener((o, l, c) -> {
            if(c != null){
                group.setScaleX(c.doubleValue());
                group.setScaleY(c.doubleValue());
            }
        });

        aTranslateX.setMinWidth(200);
        aTranslateY.setMinWidth(200);
        bTranslateX.setMinWidth(200);
        bTranslateY.setMinWidth(200);
        scale.setMinWidth(200);

        Label[] labels = new Label[5];
        for(int x = 0; x < labels.length; x++){
            labels[x] = new Label();
            labels[x].setMinWidth(150);
        }

        labels[0].setText("Rectangle A Translate X: ");
        labels[1].setText("Rectangle A Translate Y: ");
        labels[2].setText("Rectangle B Translate X: ");
        labels[3].setText("Rectangle B Translate Y: ");
        labels[4].setText("Scale of Group: ");

        VBox top = new VBox(10,
                            new HBox(8, labels[0], aTranslateX, labels[1], aTranslateY),
                            new HBox(8, labels[2], bTranslateX, labels[3], bTranslateY),
                            new HBox(8, labels[4], scale));

        top.setPadding(new Insets(12));
        top.setStyle("-fx-background-color: #fefefe");

        Pane pane = new Pane(group);

        BorderPane root = new BorderPane(pane);
        root.setTop(top);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(1280);
        primaryStage.setHeight(700);
        primaryStage.show();
    }

}

How to resolve this problem or what is the correct way to change translate property of any object when scale of group is not default?

fabian :

Group includes the transformations of the children in the calculation of it's size. Since the pivot point for scaling via scaleX/scaleY properties is the center of the node, changing the translate properties can cause the position of the pivot point to change resulting in movement of all children of the group. If you don't want this either use a Pane (doesn't include transforms in size calculation) instead of the Group or use a Scale transform with (0,0) as pivot point instead of the scaleX/scaleY properties:

Scale groupScale = new Scale();
group.getTransforms().add(groupScale);
groupScale.xProperty().bind(scale.valueProperty());
groupScale.yProperty().bind(scale.valueProperty());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=148042&siteId=1