JavaFX 将一个形状拖放到另一个形状上

JavaFX Drag and Drop a Shape on to Another Shape

我有一个 GridPane of Circles,我希望能够将一个圆圈拖到另一个圆圈之上,并将第一个圆圈的颜色应用到第二个圆圈。

我遇到的问题是我无法让目标圈检测到 dragEntered 或 dragOver。我已经能够使用标签成功地实现这一点,但由于某种原因,圆不能产生相同的效果。

我看到一些涉及设置 circle.setMouseTransparent(true) 的准解决方案,以便 下被拖拽的节点可以看到拖拽,但这里没有运气要么。

下面是使用标签执行类似操作的代码 link:Hello Drag and Drop

这是我的代码的适用片段:

              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();
                }
            });

James_D 在他上面的评论中给出了这个问题的正确答案。似乎即使只是让圆圈注册正在发生拖放,您也必须将一些数据传递给拖板(即使您不想将数据传递给节点)。

这已添加到我的 circle.setOnDragDetected 方法中:

Dragboard db = circle.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(circle.getId());
db.setContent(content);

所以方法现在看起来像这样:

            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();
                }
            });