Reputation: 484
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.
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
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