Я пытаюсь перетащить прямоугольник на VBox, а затем снова перетащить его изнутри VBox.
Если прямоугольник отбрасывается где-либо за пределами целевого VBox, то он должен вернуть свою позицию обратно туда, где он принадлежал: если это был дочерний элемент левого VBox, сбросьте его обратно в него;если это был дочерний элемент правого VBox, сбросьте его обратно в правый VBox.
Первая часть работает нормально, я могу перетащить его в VBox и добавить в качестве дочернего.Во второй части возникла проблема.
package application;
import javafx.application.Application;
import javafx.event.Event;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class DragNodeMultipleTimes extends Application {
private Disk sourceDisk = new Disk();
private VBox targetVBox = new VBox();
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
// Build the UI
GridPane root = getUI();
// Add the event handlers
this.addEventHandlers();
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
stage.show();
}
private GridPane getUI() {
GridPane pane = new GridPane();
VBox sourceVBox = new VBox();
sourceDisk.setWidth(90);
sourceDisk.setHeight(20);
sourceVBox.setStyle(" -fx-border-color:red; -fx-border-width: 1; -fx-border-style: solid;");
targetVBox.setStyle(" -fx-border-color:green; -fx-border-width: 1; -fx-border-style: solid;");
sourceVBox.getChildren().add(sourceDisk);
targetVBox.getChildren().add(new Rectangle(200, 20));
pane.setHgap(200);
pane.addColumn(0, sourceVBox);
pane.addColumn(1, targetVBox);
pane.setPadding(new Insets(200, 100, 200, 100));
return pane;
}
private void addEventHandlers() {
sourceDisk.setOnMousePressed(event -> {
sourceDisk.setOrgSceneX(event.getSceneX());
sourceDisk.setOrgSceneY(event.getSceneY());
sourceDisk.setOrgTranslateX(sourceDisk.getTranslateX());
sourceDisk.setOrgTranslateY(sourceDisk.getTranslateY());
sourceDisk.setMouseTransparent(true);
event.consume();
});
sourceDisk.setOnDragDetected(event -> sourceDisk.startFullDrag());
sourceDisk.setOnMouseDragged(event -> {
double offsetX = event.getSceneX() - sourceDisk.getOrgSceneX();
double offsetY = event.getSceneY() - sourceDisk.getOrgSceneY();
double newTranslateX = sourceDisk.getOrgTranslateX() + offsetX;
double newTranslateY = sourceDisk.getOrgTranslateY() + offsetY;
sourceDisk.setTranslateX(newTranslateX);
sourceDisk.setTranslateY(newTranslateY);
});
sourceDisk.setOnMouseReleased(event -> {
//reset the position of the disk
sourceDisk.setTranslateX(0);
sourceDisk.setTranslateY(0);
sourceDisk.setMouseTransparent(false);
});
targetVBox.setOnMouseDragEntered(Event::consume);
targetVBox.setOnMouseDragOver(event -> System.out.println("VBox: mouseDragOver"));
targetVBox.setOnMouseDragReleased(event -> {
((VBox) (event.getSource())).getChildren().add(0, sourceDisk);
//reset translate values
sourceDisk.setTranslateX(0);
sourceDisk.setTranslateY(0);
sourceDisk.setMouseTransparent(false);
});
}
private class Disk extends Rectangle {
private double orgSceneX;
private double orgSceneY;
private double orgTranslateX;
private double orgTranslateY;
public double getOrgSceneX() {
return orgSceneX;
}
public void setOrgSceneX(double orgSceneX) {
this.orgSceneX = orgSceneX;
}
public double getOrgSceneY() {
return orgSceneY;
}
public void setOrgSceneY(double orgSceneY) {
this.orgSceneY = orgSceneY;
}
public double getOrgTranslateX() {
return orgTranslateX;
}
public void setOrgTranslateX(double orgTranslateX) {
this.orgTranslateX = orgTranslateX;
}
public double getOrgTranslateY() {
return orgTranslateY;
}
public void setOrgTranslateY(double orgTranslateY) {
this.orgTranslateY = orgTranslateY;
}
}
}
Действия по воспроизведению проблемы:
1) Перетащите левый прямоугольник поверх правого (внутри VBox)
2) Перетащите только что добавленный прямоугольник за пределы VBox
3) Отпустите кнопку мыши
Проблема возникает на шаге 2. Я ожидаю, что VBox больше не получает никаких событийот мыши, так как он покинул свою границу.Этого не происходит, как видно из вывода консоли (onMouseDragOver все еще вызывается).
На шаге 3 выдается исключение, но это происходит потому, что он пытается добавить тот же прямоугольник обратно в VBox.
Что я ожидаю, так это то, что если я перетащу прямоугольник за пределы правого VBox и отпущу мышь, тогда прямоугольник сбрасывает свою позицию, чтобы вернуться обратно в правый VBox.
По сути, я пытаюсь выяснить, как получается, что, даже если курсор не находится в границах VBox, он все еще получает события MOUSE_DRAGGED?
Я также открыт дляпредложения других подходов к достижению этого результата.