2

It seems that when I move the circle outside the group of squares, it moves the squares even though there is no code that does that. I'm 99% percent sure it is because the group is trying to auto center itself, but it only does it if I change the scale of the group. Here is the code that demonstrates the problem I'm currently having.(Note that I don't want the square to move at all)

import javafx.application.Application;
import javafx.scene.shape.Circle;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.util.Duration;
import javafx.scene.layout.Pane;
import javafx.scene.Scene;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;
import javafx.scene.Group;
import javafx.stage.Stage;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;

public class Test extends Application
{
    private static Circle circle = new Circle(0, 0, 10);
    private static Group group = new Group(circle);
    private static Group mainPane = new Group(group);
    private Scene scene = new Scene(mainPane, 600, 600);
    public void start(Stage stage){
        circle.setViewOrder(-1);
        for(int i = 0; i < 100; i++){
            Rectangle backGround = new Rectangle(-10, -10, 20, 20);
            backGround.setLayoutX((i - (int)(i * .1) * 10) * 20 - 100);
            backGround.setLayoutY((int)(i * .1) * 20 - 100);
            group.getChildren().add(backGround);
        }
        
        /*This line causes the problem*/group.setScaleX(1.5);
        /*This line causes the problem*/group.setScaleY(1.5);
        group.setLayoutX(200);
        group.setLayoutY(200);
        circle.setFill(Color.RED);
        Timeline time = new Timeline();
        time.setCycleCount(Timeline.INDEFINITE);
        KeyFrame frame = new KeyFrame(Duration.millis(1), new EventHandler<ActionEvent>(){
            @Override public void handle(ActionEvent e){
                circle.setLayoutX(circle.getLayoutX() + .1);
                if(circle.getLayoutX() > 150) circle.setLayoutX(0);                
            }
        });
        time.getKeyFrames().add(frame);
        time.playFromStart();
        stage.setScene(scene);
        stage.show();
    }
}
Dragger123
  • 23
  • 5

1 Answers1

2

So I believe the problem is that scaleX / scaleY uses the center of the node as the pivot point. Combine that with the fact that the Group grows as the Circle moves to the right, and the scaling causes the Group to "move" because the new center becomes the pivot point.

When I replace:

/*This line causes the problem*/group.setScaleX(1.5);
/*This line causes the problem*/group.setScaleY(1.5);

With:

// javafx.scene.transform.Scale
Scale scale = new Scale(1.5, 1.5);
group.getTransforms().add(scale);

Your problem goes away. Unlike with scaleX / scaleY, the pivot point used by Scale is not automatically adjusted as the Group grows. Note the above Scale is using (0,0) as the pivot point. I assume that's okay, but if you want then you can set the pivot point to the initial center point of the Group (just don't constantly update the pivot point, or you'll probably run into the same problem as before).

Slaw
  • 37,820
  • 8
  • 53
  • 80