everybody,
I want to insert a graphic into my application that can be dragged and dropped out of the application. As soon as the graphic is released outside the window, an Undecoraded / Transparent window should be opened, where only this graphic is displayed.
Stage newStage = new Stage();
StackPane stack = new StackPane();
ImageView imageView = new ImageView(new Image(this.getClass().getResourceAsStream(InBoxEnum.Graphic.INBOXLOGO.getFilename())));
stack.getChildren().add(imageView);
imageView.setOnDragDetected(event -> {
Dragboard dragboard = imageView.startDragAndDrop(TransferMode.MOVE);
dragboard.setDragView(imageView.snapshot(null, null));
ClipboardContent content = new ClipboardContent();
content.put(DRAGGABLE_INBOX_TYPE, "dontcare");
dragboard.setContent(content);
event.consume();
});
imageView.setOnDragDone(event -> {
System.out.println(event.getScreenX());
System.out.println(event.getScreenY());
});
Scene scene = new Scene(stack, 500, 500);
newStage.setScene(scene);
newStage.show();
The DragDetected event works so far also without problems.
The problem is that inside the dragDone event the position of the mouse is always 0 and I can't tell if the mouse is inside or outside my application. If the mouse is released inside the application, nothing should happen.
I also tried with Robot Class, but I always get a static strange x/y position.
I am using JAVA 11 (Adopt JDK).
Thanks for your help
Using Robot
works fine for me (Oracle JDK 11 + JavaFX 12). Since you don't actually want to drag&drop any image data, you could simply work around this issue by creating a new stage immediately and use the MOUSE_DRAGGED
of the ImageView
to update the position of the window:
Stage newStage = new Stage();
StackPane stack = new StackPane();
ImageView imageView = new ImageView(new Image(...));
stack.getChildren().add(imageView);
class DragHandler implements EventHandler<MouseEvent> {
Stage dragTarget;
@Override
public void handle(MouseEvent event) {
if (dragTarget != null) {
// move stage
dragTarget.setX(event.getScreenX());
dragTarget.setY(event.getScreenY());
event.consume();
}
}
}
final DragHandler dragHandler = new DragHandler();
imageView.setOnDragDetected(event -> {
// init stage at half transparency
Group root = new Group(new ImageView(imageView.getImage()));
root.setOpacity(0.5);
Scene displayScene = new Scene(root);
displayScene.setFill(null);
Stage displayStage = new Stage();
displayStage.initStyle(StageStyle.TRANSPARENT);
displayStage.setScene(displayScene);
displayStage.setX(event.getScreenX());
displayStage.setY(event.getScreenY());
displayStage.show();
dragHandler.dragTarget = displayStage;
event.consume();
});
imageView.setOnMouseDragged(dragHandler);
imageView.setOnMouseReleased(event -> {
if (dragHandler.dragTarget != null) {
if (stack.contains(event.getX(), event.getY())) { // check, if drop happened inside the bounds of the scene root
dragHandler.dragTarget.hide();
} else {
// make stage fully opaque & cleanup
dragHandler.dragTarget.getScene().getRoot().setOpacity(1);
imageView.setImage(null);
}
dragHandler.dragTarget = null;
event.consume();
}
});
Scene scene = new Scene(stack, 500, 500);
newStage.setScene(scene);
newStage.show();