George R
George R

Reputation: 484

JavaFx drag Shape in Scollpane

I am currently creating a puzzle game. The idea is that on the left you have a ScrollPane containing a pane which has all the puzzle pieces (javafx.shapes).

I have code that allows me to drag around the pieces but if I want to drag it to the bottom of the ScrollPane it flies back up to its initial position. I want the shapes to be draggable from the top of the ScrollPane to the Bottom. enter image description here

Controller:

public class SpielModus extends Application{
    @FXML
    private ScrollPane pieceAreaScrollable;

    @FXML
    private Pane pieceArea;

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.stage = primaryStage;
        show();
    }

    @FXML
    public void initialize() {
        Circle circle = new Circle(50, 50, 50);
        Circle circle2 = new Circle(50, 200, 50);

        Group group = new Group(circle, circle2);

        // So that the Pane is bigger then ScrollPane to become Scrollable
        pieceArea.setMinHeight(2000);
        pieceArea.getChildren().addAll(group);

        group.setOnMouseDragged(e -> {
            group.setLayoutX(e.getSceneX());
            group.setLayoutY(e.getSceneY());
        });
    }

    public void show() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("SpielModus.fxml"));
            loader.setController(this);

            Parent layout = loader.load();
            stage.setScene(new Scene(layout));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1080.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.171">
  <columnConstraints>
    <ColumnConstraints minWidth="10.0" prefWidth="250.0" />
    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
  </columnConstraints>
  <rowConstraints>
    <RowConstraints minHeight="10.0" prefHeight="30.0" />
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
  </rowConstraints>
   <children>
      <ScrollPane fx:id="pieceAreaScrollable" hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0" vbarPolicy="ALWAYS" GridPane.rowSpan="2">
         <content>
            <Pane fx:id="pieceArea" prefHeight="200.0" prefWidth="200.0" />
         </content>
      </ScrollPane>
   </children>
</GridPane>

Upvotes: 2

Views: 500

Answers (1)

James_D
James_D

Reputation: 209684

You're relocating the circles within the large pane pieceArea to a location based on the mouse coordinates relative to the scene. If the pieceArea has been scrolled, this will give the incorrect location (because it doesn't account for the scrolling). You need the mouse coordinates relative to pieceArea (the parent of the group, which is the node on which the mouse drag event occurs).

You can do this with

    group.setOnMouseDragged(e -> {
        Point2D newLocation = group.localToParent(new Point2D(e.getX(), e.getY()));
        group.setLayoutX(newLocation.getX());
        group.setLayoutY(newLocation.getY());
    });

Upvotes: 4

Related Questions