如何拖放而不显示正在拖动的图片?

时间:2018-10-03 16:39:50

标签: java javafx drag-and-drop fxml

我正在设置一个战舰游戏,我希望能够通过将ImageView个战舰拖动到网格中的按钮上来在游戏板上设置飞船。我有以下代码来设置到目前为止的所有拖放操作:

        private void configureDragAndDrop(ImageView image) {

        image.setOnDragDetected(new EventHandler<MouseEvent>(){

            @Override
            public void handle(MouseEvent event) {
                Dragboard db = pictureOne.startDragAndDrop(TransferMode.ANY);

                ClipboardContent content = new ClipboardContent();
                content.putImage(pictureOne.getImage());
                db.setContent(content);

                event.consume();
            }

        });



        for(Node target: playerGrid.getChildren()) {
            if(target.getId() != null) {
                target.setOnDragOver(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                        /* data is dragged over the target */
                        /* accept it only if it is not dragged from the same node 
                         * and if it has a string data */
                        if (event.getGestureSource() != target &&
                                event.getDragboard().hasImage()) {
                            /* allow for moving */
                            event.acceptTransferModes(TransferMode.MOVE);
                        }

                        event.consume();
                    }
                });
            }

        }

        for(Node target: playerGrid.getChildren()) {
            if(target.getId() != null) {
                target.setOnDragEntered(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                    /* the drag-and-drop gesture entered the target */
                    /* show to the user that it is an actual gesture target */
                         if (event.getGestureSource() != target &&
                                 event.getDragboard().hasImage()) {
                             target.setStyle("-fx-background-color: pink");
                         }

                         event.consume();
                    }
                });
            }

        }

        for(Node target: playerGrid.getChildren()) {
            if(target.getId() != null) {
                target.setOnDragExited(new EventHandler<DragEvent>() {
                    public void handle(DragEvent event) {
                        /* mouse moved away, remove the graphical cues */
                        target.setStyle("-fx-background-color:blue");

                        event.consume();
                    }
                });
            }

        }

        for(Node target: playerGrid.getChildren()) {
            if(target.getId() != null) {
                target.setOnDragDropped(new EventHandler<DragEvent>() {
                    public void handle(DragEvent event) {
                        /* data dropped */
                        /* if there is a string data on dragboard, read it and use it */
                        Dragboard db = event.getDragboard();
                        boolean success = false;
                        if (db.hasImage()) {
                           target.setStyle("-fx-background-color:green");
                           success = true;
                        }
                        /* let the source know whether the string was successfully 
                         * transferred and used */
                        event.setDropCompleted(success);

                        event.consume();
                     }
                });
            }

        }

        for(Node target: playerGrid.getChildren()) {
            if(target.getId() != null) {
                target.setOnDragDone(new EventHandler<DragEvent>() {
                    public void handle(DragEvent event) {
                        /* data dropped */
                        /* if there is a string data on dragboard, read it and use it */
                        Dragboard db = event.getDragboard();
                        boolean success = false;
                        if (db.hasImage()) {
                           target.setStyle("-fx-background-color:yellow");
                           success = true;
                        }
                        /* let the source know whether the string was successfully 
                         * transferred and used */
                        event.setDropCompleted(success);

                        event.consume();
                     }
                });
            }
        }

        image.setOnDragDone(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                /* the drag and drop gesture ended */
                /* if the data was successfully moved, clear it */
                if (event.getTransferMode() == TransferMode.MOVE) {
                    pictureOne.setOpacity(0.0);
                }
                event.consume();
            }
        });




    }

到目前为止,除了setOnDragDone部分没有将颜色更改为绿色(但我稍后会进行处理)以外,大部分拖动工作正常。

我的问题是,当我开始拖动时,无论如何都可以设置要拖动的图像的大小(而不是显示的原始图像的完整大小)。如果不是,我是否仍可以拖动图像但不显示正在拖动的图像,而只是更改目标的颜色。

1 个答案:

答案 0 :(得分:0)

首先是一个非常快速的建议,为什么要使用五个单独的“ for”循环为同一组节点设置不同的拖动处理程序。您只能在一个for循环中完成所有操作。

for(Node target: playerGrid.getChildren()) {
   if(target.getId() != null) {
      target.setOnDragOver(..);
      target.setOnDragEntered(..);
      target.setOnDragExited(..);
      target.setOnDragDropped(..);
      target.setOnDragDone(..);
   }
}

谈到实际问题,要调整图像大小并在拖动板上进行设置,您可以使用“快照”功能。检查以下代码,以在剪贴板中设置调整大小的图像。

double displaySize = 150;
double dragSize = 50;
ImageView pictureOne = new ImageView(new Image(ImageDragDemo.class.getResourceAsStream(imgName)));
pictureOne.setFitHeight(displaySize);
pictureOne.setFitWidth(displaySize);
pictureOne.setOnDragDetected(event -> {
    Dragboard db = pictureOne.startDragAndDrop(TransferMode.ANY);
    ClipboardContent content = new ClipboardContent();
    // Resizing the image to required size before taking the snapshot.
    pictureOne.setFitHeight(dragSize);
    pictureOne.setFitWidth(dragSize);

    content.putImage(pictureOne.snapshot(null,null));

    // Resetting the image to initial size after taking the snapshot.
    pictureOne.setFitHeight(displaySize);
    pictureOne.setFitWidth(displaySize);
    db.setContent(content);
    event.consume();
});

如果您对还原图像大小的实现不感兴趣,则可以创建一个新的ImageView并拍摄快照。

ImageView dragImage = new ImageView(pictureOne.getImage());
dragImage.setFitHeight(dragSize);
dragImage.setFitWidth(dragSize);
content.putImage(dragImage.snapshot(null,null));

对于另一个不显示图像的问题,我认为您可以设置任何STRING内容并进行验证,而不是使用event.getDragboard()。hasImage()。像..

// Instead of content.putImage(..) use
content.putString("DRAG_IMAGE");
..
// And instead of checking using event.getDragboard().hasImage() use
event.getDragboard().hasString() && event.getDragboard().getString().equals("DRAG_IMAGE")