Reputation: 303
What's the best way to show a semi-transparent "copy" of a Node next to the mouse icon during a drag/drop?
Basically I have HBoxes with colored backgrounds and text labels in them, and I'd like to give the appearance that they "stick" to the mouse cursor when they're being dragged.
It's nice if users can visually verify WHAT they're dragging, rather than just seeing the mouse cursor change into the various drag icons. Scene Builder tends to do this when you drag some components, like a RadioButton.
Upvotes: 1
Views: 2357
Reputation: 1864
The "semi-transparent "copy" of a Node" is accomplished by calling snapshot(null, null)
on a node, which returns a WritableImage
. Then you set this WritableImage
as the drag view of the DragBoard
. Here is a small example on how to do this:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class DragAndDrop extends Application {
private static final DataFormat DRAGGABLE_HBOX_TYPE = new DataFormat("draggable-hbox");
@Override
public void start(Stage stage) {
VBox content = new VBox(5);
for (int i = 0; i < 10; i++) {
Label label = new Label("Test drag");
DraggableHBox box = new DraggableHBox();
box.getChildren().add(label);
content.getChildren().add(box);
}
stage.setScene(new Scene(content));
stage.show();
}
class DraggableHBox extends HBox {
public DraggableHBox() {
this.setOnDragDetected(e -> {
Dragboard db = this.startDragAndDrop(TransferMode.MOVE);
// This is where the magic happens, you take a snapshot of the HBox.
db.setDragView(this.snapshot(null, null));
// The DragView wont be displayed unless we set the content of the dragboard as well.
// Here you probably want to do more meaningful stuff than adding an empty String to the content.
ClipboardContent content = new ClipboardContent();
content.put(DRAGGABLE_HBOX_TYPE, "");
db.setContent(content);
e.consume();
});
}
}
public static void main(String[] args) {
launch();
}
}
Upvotes: 6