1 year ago

#371464

test-img

Roy K.

Is it possible to change the white file icon that appears when dragging a node with setOnDragDetected? (JavaFX)

GOAL: I wish to change the white file icon that appears when dragging a node that has implemented setOnDragDetected. More specifically, I'm recreating chess in JavaFX, and want to have a chess piece image appear when dragging, instead of the current white file image, like as shown below.

Dragging an Image from one node to another

CODE: I've created a minimal example:

package application;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;


public class StackOverflowSample extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {

            primaryStage.setTitle("Chess Sample");
            Group root = new Group();
            Scene scene = new Scene(root, 400, 200);

            /* 1. Setting up Chess squares (aka stackpanes)*/
            StackPane source1 = new StackPane(new Rectangle(100,100,Color.BLUE));
            StackPane target1 = new StackPane(new Rectangle(100,100,Color.LIGHTBLUE));
            source1.setLayoutX(50);
            source1.setLayoutY(50);
            target1.setLayoutX(250);
            target1.setLayoutY(50);

            /*2. Setting up the chess piece to move*/
            Image whiteKnightImg = new Image("https://www.kindpng.com/picc/m/22-223299_white-knight-chess-png-transparent-png.png", 90,90,true,true);
            ImageView whiteKnightView = new ImageView(whiteKnightImg);
            source1.getChildren().add(whiteKnightView);
        

            /* 3. Adding Drag and Drop Functionality*/
            source1.setOnDragDetected(new EventHandler<MouseEvent>() {
                public void handle(MouseEvent event) {

                    Dragboard db = source1.startDragAndDrop(TransferMode.ANY);
                    ClipboardContent content = new ClipboardContent();

                    content.putString("hasPiece");
                    db.setContent(content);
                    event.consume();

                }
            });

            target1.setOnDragOver(new EventHandler <DragEvent>() {
                @Override
                public void handle(DragEvent event) {
                    if (event.getGestureSource() != target1 && event.getDragboard().hasString()) {
                        event.acceptTransferModes(TransferMode.MOVE);
                    }
                    event.consume();
                }
            });

            target1.setOnDragDropped(new EventHandler<DragEvent>() {
                public void handle(DragEvent event) {
                    Dragboard db = event.getDragboard();
                    boolean success = false;
                    if (db.hasString()) {
                        target1.getChildren().add(whiteKnightView);
                        success = true;
                    }
                    event.setDropCompleted(success);
                    event.consume();
                }
            });

            source1.setOnDragDone(new EventHandler<DragEvent>() {
                public void handle(DragEvent event) {
                    if (event.getTransferMode() == TransferMode.MOVE) {
                        System.out.println("success");
                    }
                    event.consume();
                }
            });

            
            root.getChildren().addAll(source1,target1);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

POSSIBLE SOLUTIONS:

  1. Java Source Code. Maybe there's a way to inherit the Node class that implement the dragging related methods. I took a look at the source code for JavaFX.scene.Node and found the section related to setOnDragDetected, but didn't look into it any further.
    public final void setOnDragDetected(
            EventHandler<? super MouseEvent> value) {
        onDragDetectedProperty().set(value);
    }

    public final EventHandler<? super MouseEvent> getOnDragDetected() {
        return (eventHandlerProperties == null)
                ? null : eventHandlerProperties.getOnDragDetected();
    }

    /**
     * Defines a function to be called when drag gesture has been
     * detected. This is the right place to start drag and drop operation.
     * @return the event handler that is called when drag gesture has been
     * detected
     */
    public final ObjectProperty<EventHandler<? super MouseEvent>>
            onDragDetectedProperty() {
        return getEventHandlerProperties().onDragDetectedProperty();
    }
  1. It's not possible. I've considered that it's not something that can be changed. believe it's possible that it's impossible to change this white icon, so I might just change my approach entirely. Instead of using StackPanes as squares that also hold images, I'm considering this tutorial.

java

javafx

javafx-8

draggable

0 Answers

Your Answer

Accepted video resources