Hany Alom
Hany Alom

Reputation: 67

JavaFX Drag View for Transparent png image

I am trying to drag an Object which is represented as PNG image with transparent background from an AnchorPane to an HBox.

I set the image to the Drag View with this lines:

        SliderItemHandler mh = (SliderItemHandler) event.getSource();
        Dragboard db = mh.startDragAndDrop(TransferMode.COPY);
        db.setDragView(mh.getModule().getImage());
        ClipboardContent content = new ClipboardContent();
        db.setContent(content);

It is all fine with nontransparent background images, but with the transparent ones the image got a white background with opacity "0.8" i think.

I tried taking a snapshot for the node:

        db.setDragView(mh.snapshot(new SnapshotParameters(), null));

but it didn't work, the white background still there. Is there any other way to make it transparent like the original image?

Upvotes: 3

Views: 1380

Answers (2)

Big Bad Baerni
Big Bad Baerni

Reputation: 996

You have to change your snapshot parameters to transpartent fill:

SnapshotParameters sp = new SnapshotParameters();
sp.setFill(Color.TRANSPARENT);
db.setDragView(mh.snapshot(sp, null));

The result will be transparent without the white borders.

Upvotes: 2

Jaims
Jaims

Reputation: 1575

I'm not really sure how you achieve to get a white background, taking the opacity into account. However, I re-created your use case and will show you how I implemented this.

The following image is a Scene divided between an AnchorPane on the left, and a HBox on the right. The small transparent circle being the source ImageView to copy, the larger circle next to it being a dropped Image and far-most right being a circle currently being dragged. (Screenshot didn't include the cursor.)

Drag

As you can see, in none of the 3 scenarios there is a white (or almost white) background. It is just the image itself, with the image itself being a bit more transparent while dragging.

To achieve this, we'll take 2 variables into account. The source ImageView and the destination HBox.

@FXML
private HBox destination;
@FXML
private ImageView image;

We'd like the image to be dragged, so we add a DRAG_DETECTED event onto the ImageView.

image.addEventHandler(MouseEvent.DRAG_DETECTED, mouseEvent -> {
    Dragboard db = image.startDragAndDrop(TransferMode.COPY);
    ClipboardContent content = new ClipboardContent();
    content.putImage(image.getImage());
    db.setContent(content);
    mouseEvent.consume();
});

Then we'd like the destination HBox to accept the dragged ImageView.

destination.addEventHandler(DragEvent.DRAG_OVER, (DragEvent event) -> {
    if (event.getDragboard().hasImage()) {
        event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
    }
    event.consume();
});

And of course we'd like to place the ImageView into the HBox when actually dropped. In this case, it just places a copy of it into the HBox, but that's open for implementation of course.

destination.addEventHandler(DragEvent.DRAG_DROPPED, (DragEvent event) -> {
    Dragboard db = event.getDragboard();
    destination.getChildren().add(new ImageView(db.getImage()));
    event.setDropCompleted(true);
    event.consume();
});

That's all there is to dragging and dropping an image. No white backgrounds involved for transparent images. However, if you're able to create a MCVE, it might be easier to look into your problem if it still maintains.

Upvotes: 1

Related Questions