Reputation: 227
I have a GridPane of Circles, and I want to be able to drag one circle on top of another and have the color from the first be applied to the second.
The problem I'm having is that I cannot get the target circle to detect a dragEntered or dragOver. I have been able to implement this successfully using Labels, but for some reason, a Circle does not give the same effect.
I have seen some quasi-solutions that involved setting circle.setMouseTransparent(true) so that the node under the dragged node can see the drag, but no luck here either.
Here's a link to the code that does a similar thing using Labels: Hello Drag and Drop
Here's an applicable snippet of my code:
circle.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Dragboard db = circle.startDragAndDrop(TransferMode.ANY);
System.out.print("Dragging...");
System.out.println("From row: " + draggedFromRow + " From col: " + draggedFromCol);
circle.setLayoutX(event.getSceneX());
circle.setLayoutY(event.getSceneY());
event.consume();
}
});
circle.setOnDragOver(new EventHandler <DragEvent>() {
public void handle(DragEvent event) {
System.out.println("onDragOver");
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
});
circle.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
int toCol = Integer.valueOf(circle.getId().substring(0, 1));
int toRow = Integer.valueOf(circle.getId().substring(1));
performSwap(draggedFromRow, draggedFromCol, toRow, toCol);
System.out.print("Dragg dropped on ");
System.out.println(toRow + " " + toCol);
event.consume();
}
});
circle.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
System.out.println("drag entered!");
event.consume();
}
});
circle.setOnDragExited(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
System.out.println("drag left!");
event.consume();
}
});
Upvotes: 0
Views: 2201
Reputation: 227
James_D had the correct answer to this problem in his comment above. Seems that even just to have the circle register that a drag and drop is occurring, you have to pass some data to a Dragboard (even if you don't want to pass data to the node).
This was added to my circle.setOnDragDetected
method:
Dragboard db = circle.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(circle.getId());
db.setContent(content);
So the method now looks like this:
circle.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Dragboard db = circle.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(circle.getId());
db.setContent(content);
System.out.print("onDragDetected");
event.consume();
}
});
Upvotes: 1