无法在GridPane中进行拖放操作

时间:2015-08-30 14:31:15

标签: javafx drag-and-drop

我正在尝试在GridPane中拖放图像,但是虽然可以启动拖动操作,但我无法将图像放到另一个单元格上。

我已关注this example

这是我的Laucher.java:

package app;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Launcher extends Application {

    @Override
    public void start(Stage primaryStage) {
        Scene scene = new Scene(new DraggableGrid());

        primaryStage.setTitle("Hello draggable grid !");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

这是我的DraggableGrid.java:

package app;

import java.util.List;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.GridPane;

public class DraggableGrid extends GridPane {

    public DraggableGrid(){
        final int CELL_SIZE = 60;
        for (int rank = 0; rank < 2; rank++){
            for (int file = 0; file < 2; file++){
                Group group = new Group();

                Image bgImage = new     Image(String.format("/app/images/%s_bg.jpg",
                        (file+rank) % 2 == 0 ? "green" : "dark"));
                ImageView bgImageView = new ImageView(bgImage);
                bgImageView.setFitWidth(CELL_SIZE);
                bgImageView.setFitHeight(CELL_SIZE);

                Image fgImage = (file+rank) == 0 ? 
                        new Image("/app/images/car.png") : null;
                ImageView fgImageView = new ImageView(fgImage);
                fgImageView.setFitWidth(CELL_SIZE);
                fgImageView.setFitHeight(CELL_SIZE);

                group.getChildren().addAll(bgImageView, fgImageView);
                add(group, file, rank);
            }
        }

        addDndFeature();
    }

    private void addDndFeature() {
        List<Node> children = getChildrenUnmodifiable();
        for (int rank = 0; rank < 2; rank++){
            for (int file = 0; file < 2; file++){
                Node currentNode = children.get(file + rank*2);
                ImageView currentNodeImageView = (ImageView) ((Group) currentNode)
                        .getChildren().get(1);
                Image cellImage = currentNodeImageView.getImage();
                currentNodeImageView.setOnDragDetected(event -> {
                    if (cellImage == null){
                        event.consume();
                    }
                    else {
                        Dragboard dragboard = currentNodeImageView
                                .startDragAndDrop(TransferMode.MOVE);

                        ClipboardContent clipboardContent = new ClipboardContent();
                        clipboardContent.putImage(cellImage);
                        dragboard.setContent(clipboardContent);

                        /////////////////////////
                        System.err.println("Drag started !");
                        ///////////////////////////

                        event.consume();
                    }
                });

                currentNodeImageView.setOnDragOver(event -> {
                    if (event.getGestureSource() != currentNodeImageView
                            && event.getDragboard().hasImage()){
                       event.acceptTransferModes(TransferMode.MOVE);
                       /////////////////////////
                        System.err.println("Drag accepted !");
                        ///////////////////////////
                    }
                    event.consume();
                });

                currentNodeImageView.setOnDragDropped(event -> {
                    Dragboard dragboard = event.getDragboard();
                    boolean success = false;

                    if (dragboard.hasImage()){
                        currentNodeImageView.setImage(dragboard.getImage());
                        success = true;
                    }

                    event.setDropCompleted(success);

                    /////////////////////////
                    System.err.println("Drag dropped !");
                    ///////////////////////////

                    event.consume();
                });

                currentNodeImageView.setOnDragDone(event -> {
                    if (event.getTransferMode() == TransferMode.MOVE){
                        ((ImageView)     event.getSource()).setImage(null);
                    }

                    /////////////////////////
                    System.err.println("Drag done !");
                    ///////////////////////////

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

}

事实上,只有Strings“Drag start!”和“拖累!”被放在屏幕上,绕过被接受和放弃的状态。

1 个答案:

答案 0 :(得分:1)

问题是您要将DragOverDragDropped事件处理程序添加到源(即前景)图像视图中。应将它们添加到目标(即背景)图像视图中:

在循环中,获取目标图像视图:

ImageView targetNodeImageView = ( ImageView ) (( Group ) currentNode)
                            .getChildren().get( 0 );

然后添加linsteners:

targetNodeImageView.setOnDragOver(...);

targetNodeImageView.setOnDragDropped(...);