theAnon
theAnon

Reputation: 77

Moving a Rectangle to the position where a mouse click happen

I am trying to create a project where the user clicks on the screen and then a rectangle will move to the position where the clicked occurred. My intention was to get the center of the rectangle to move the exact location of the click but my code only moves the rectangle into the general area of where the click occurred. My question is how do I get the center of the rectangle to move the exact location of where a mouse click occurs?

public void start(Stage primaryStage) {

    BorderPane root = new BorderPane();
    Scene scene = new Scene(root,400,400);

    Rectangle rec = new Rectangle(50,50,50,50);
    rec.setLayoutX(200);
    rec.setLayoutY(200);

    TranslateTransition transition = new TranslateTransition(Duration.seconds(0.50), rec);
    transition.setOnFinished(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent t) {
            rec.setLayoutX(rec.getTranslateX() + rec.getLayoutX());
            rec.setLayoutY(rec.getTranslateY() + rec.getLayoutY());
            rec.setTranslateX(0);
            rec.setTranslateY(0);
        }
    });

    scene.setOnMousePressed(e->{
        transition.setToX(e.getSceneX() - rec.getLayoutX());
        transition.setToY(e.getSceneY() - rec.getLayoutY());
        transition.playFromStart();
    });

    root.getChildren().add(rec);

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

}

Upvotes: 1

Views: 2536

Answers (2)

jewelsea
jewelsea

Reputation: 159566

Here a complete sample using a Pane as suggested by fabian.

import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Translator extends Application {
    private static final double W = 400, H = 400;
    private static final double S = 50;

    public void start(Stage stage) {
        Rectangle rec = new Rectangle(W / 2 - S / 2,H / 2 - S / 2,S,S);

        TranslateTransition transition = new TranslateTransition(Duration.millis(500), rec);
        transition.setOnFinished(t -> {
            rec.setX(rec.getTranslateX() + rec.getX());
            rec.setY(rec.getTranslateY() + rec.getY());
            rec.setTranslateX(0);
            rec.setTranslateY(0);
        });

        Pane root = new Pane(rec);
        Scene scene = new Scene(root,W,H);

        root.setOnMousePressed(e -> {
            transition.stop();
            transition.setToX(e.getX() - S / 2 - rec.getX());
            transition.setToY(e.getY() - S / 2 - rec.getY());
            transition.playFromStart();
        });

        stage.setScene(scene);
        stage.show();
    }

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

Upvotes: 0

fabian
fabian

Reputation: 82491

You ignore the x/y properties of the Rectangle which also shift the position where the Rectangle is drawn. Furthermore for the center to be moved to this position, you need to also subtract half the width/height from the position to move to...

Also I recommend using a Pane instead of BorderPane, is you want to set the layoutX/layoutY properties yourself. Nonetheless in this case it should work too with some small adjustments:

scene.setOnMousePressed(e -> {
    transition.setToX(e.getSceneX() - rec.getLayoutX() - rec.getWidth() / 2 - rec.getX());
    transition.setToY(e.getSceneY() - rec.getLayoutY() - rec.getHeight() / 2 - rec.getY());
    transition.playFromStart();
});

Upvotes: 1

Related Questions