JavaFX拖放到GridPane?

JavaFX拖放到GridPane?,java,javafx,javafx-8,Java,Javafx,Javafx 8,我已经在我的游戏中实现了拖放功能,但到目前为止,我只能“拖放”到硬编码的位置。如图所示: 我想要的是: 当船舶被丢弃时,其x、y值(相对于网格窗格)被保存,或者 船舶放置到的单元格已保存 我的SetOnDragDrop事件在此处处理: //Drag dropped draws the image to the receiving node target.setOnDragDropped(new EventHandler<DragEvent>() { pub

我已经在我的游戏中实现了拖放功能,但到目前为止,我只能“拖放”到硬编码的位置。如图所示:

我想要的是:

  • 当船舶被丢弃时,其x、y值(相对于网格窗格)被保存,或者
  • 船舶放置到的单元格已保存
  • 我的SetOnDragDrop事件在此处处理:

    //Drag dropped draws the image to the receiving node
        target.setOnDragDropped(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //Data dropped
                //If there is an image on the dragboard, read it and use it
                Dragboard db = event.getDragboard();
                boolean success = false;
                int x, y;
                if(db.hasImage()){
                    //target.setText(db.getImage()); --- must be changed to target.add(source, col, row)
                    //target.add(source, 5, 5, 1, 1);
                    //Places at 0,0 - will need to take coordinates once that is implemented
                    Board.add(test, 0, 0, 1, 1);
                    success = true;
                }
                //let the source know whether the image was successfully transferred and used
                event.setDropCompleted(success);
    
                event.consume();
            }
        });
    
    //拖放将图像绘制到接收节点
    target.setOnDragDrop(新的EventHandler(){
    公共无效句柄(DrageEvent事件){
    //数据丢失
    //如果拖板上有图像,请阅读并使用它
    Dragboard db=event.getDragboard();
    布尔成功=假;
    int x,y;
    if(db.hasImage()){
    //target.setText(db.getImage());---必须更改为target.add(源、列、行)
    //目标。添加(源,5,5,1,1);
    //0,0处的位置-一旦实现,将需要获取坐标
    添加(测试,0,0,1,1);
    成功=真实;
    }
    //让源知道图像是否已成功传输和使用
    事件。setDropCompleted(成功);
    event.consume();
    }
    });
    
    我觉得这应该是一个简单的鼠标悬停事件或类似的事情,但我不知道该怎么做

    编辑:下面类的完整代码:

    public class Controller implements Initializable{
    @FXML
    public GridPane Board;
    public GridPane ShipsToBePlaced;
    public Rectangle MessageBox;
    public Button ReadyButton;
    public Button QuitButton;
    public ImageView[][] water;
    public ImageView[] ships;
    public ImageView[][] ships2d;
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //Adds water to each cell in grid
        water = new ImageView[10][10];
        //ships2d = new ImageView[10][10];
        for(int i =0; i<10; i++){
            for(int j=0; j <10; j++){
                water[i][j] = new ImageView("Tiles/watertile.png");
                water[i][j].setPreserveRatio(true);
                water[i][j].setFitHeight(49);
                water[i][j].setFitWidth(49);
                Board.add(water[i][j], i, j);
                //ships2d[i][j] = new ImageView("Ships/ship2.png");
                //ships2d[i][j].setPreserveRatio(true);
                //ships2d[i][j].setFitWidth(49);
                //Board.add(ships2d[i][j], i, j);
    
            }
        }
        //Adds ships
        ships = new ImageView[5];
        ships[0] = new ImageView("Ships/ship2.png");
        ships[1] = new ImageView("Ships/ship3.png");
        ships[2] = new ImageView("Ships/ship3.png");
        ships[3] = new ImageView("Ships/ship4.png");
        ships[4] = new ImageView("Ships/ship5.png");
        for(int i=0; i < 5; i++){
            ships[i].setPreserveRatio(true);
        }
        ships[0].setFitWidth(80);
        ships[1].setFitWidth(120);
        ships[2].setFitWidth(120);
        ships[3].setFitWidth(160);
        ships[4].setFitWidth(200);
        //ShipsToBePlaced.add(ships[0], 0, 0);
        ShipsToBePlaced.add(ships[1], 0, 1);
        ShipsToBePlaced.add(ships[2], 0, 2);
        ShipsToBePlaced.add(ships[3], 0, 3);
        ShipsToBePlaced.add(ships[4], 0, 4);
    
    
        //Test imageview for dropped ship
        ImageView test = new ImageView("Ships/ship2.png");
        test.setPreserveRatio(true);
        test.setFitWidth(80);
    
    
        //First attempt at drag and drop
        ImageView source = new ImageView ("Ships/ship2.png");
        source.setPreserveRatio(true);
        source.setFitWidth(80);
        ShipsToBePlaced.add(source, 0, 0);
        final GridPane target = Board;
    
        //Drag detected event handler is used for adding drag functionality to the boat node
        source.setOnDragDetected(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                //Drag was detected, start drap-and-drop gesture
                //Allow any transfer node
                Dragboard db = source.startDragAndDrop(TransferMode.ANY);
    
                //Put ImageView on dragboard
                ClipboardContent cbContent = new ClipboardContent();
                cbContent.putImage(source.getImage());
                //cbContent.put(DataFormat.)
                db.setContent(cbContent);
                source.setVisible(false);
                event.consume();
            }
        });
    
        //Drag over event handler is used for the receiving node to allow movement
        target.setOnDragOver(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //data is dragged over to target
                //accept it only if it is not dragged from the same node
                //and if it has image data
                if(event.getGestureSource() != target && event.getDragboard().hasImage()){
                    //allow for moving
                    event.acceptTransferModes(TransferMode.MOVE);
                }
                event.consume();
            }
        });
    
        //Drag entered changes the appearance of the receiving node to indicate to the player that they can place there
        target.setOnDragEntered(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //The drag-and-drop gesture entered the target
                //show the user that it is an actual gesture target
                if(event.getGestureSource() != target && event.getDragboard().hasImage()){
                    source.setVisible(false);
                    target.setOpacity(0.7);
                    System.out.println("Drag entered");
                }
                event.consume();
            }
        });
    
        //Drag exited reverts the appearance of the receiving node when the mouse is outside of the node
        target.setOnDragExited(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //mouse moved away, remove graphical cues
                source.setVisible(true);
                target.setOpacity(1);
    
                event.consume();
            }
        });
    
        //Drag dropped draws the image to the receiving node
        target.setOnDragDropped(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //Data dropped
                //If there is an image on the dragboard, read it and use it
                Dragboard db = event.getDragboard();
                boolean success = false;
                int x, y;
                if(db.hasImage()){
                    //target.setText(db.getImage()); --- must be changed to target.add(source, col, row)
                    //target.add(source, 5, 5, 1, 1);
                    //Places at 0,0 - will need to take coordinates once that is implemented
                    Board.add(test, 0, 0, 1, 1);
                    success = true;
                }
                //let the source know whether the image was successfully transferred and used
                event.setDropCompleted(success);
    
                event.consume();
            }
        });
    
        source.setOnDragDone(new EventHandler<DragEvent>() {
            public void handle(DragEvent event) {
                //the drag and drop gesture has ended
                //if the data was successfully moved, clear it
                if(event.getTransferMode() == TransferMode.MOVE){
                    source.setVisible(false);
                }
                event.consume();
            }
        });
    }
    
    公共类控制器实现可初始化{
    @FXML
    公共网格板;
    放置公共网格窗格;
    公共矩形消息框;
    公共按钮就绪按钮;
    公共按钮;
    公共图像视图[]水;
    公众视野[]船舶;
    公共图像视图[][]发货2d;
    @凌驾
    公共void初始化(URL位置、ResourceBundle资源){
    //将水添加到栅格中的每个单元
    水=新图像视图[10][10];
    //ships2d=新图像视图[10][10];
    
    对于(int i=0;i如果您可以访问实际删除该节点的
    节点
    ,您可以在
    网格窗格
    中确定索引,并对新节点使用相同的索引和/或以任何其他方式使用索引

    在这种情况下,您可以使用
    DragEvent.getPickResult().getIntersectedNode()
    事件获取目标
    ImageView

    public void handle(DragEvent event) {
        //Data dropped
        //If there is an image on the dragboard, read it and use it
        Dragboard db = event.getDragboard();
        boolean success = false;
        Node node = event.getPickResult().getIntersectedNode();
        if(node != target && db.hasImage()){
    
            Integer cIndex = GridPane.getColumnIndex(node);
            Integer rIndex = GridPane.getRowIndex(node);
            int x = cIndex == null ? 0 : cIndex;
            int y = rIndex == null ? 0 : rIndex;
            //target.setText(db.getImage()); --- must be changed to target.add(source, col, row)
            //target.add(source, 5, 5, 1, 1);
            //Places at 0,0 - will need to take coordinates once that is implemented
            ImageView image = new ImageView(db.getImage());
    
            // TODO: set image size; use correct column/row span
            Board.add(image, x, y, 1, 1);
            success = true;
        }
        //let the source know whether the image was successfully transferred and used
        event.setDropCompleted(success);
    
        event.consume();
    }
    

    注意:由于您使用系统剪贴板使用拖动事件,其他应用程序可能是拖动动作的源或目标…

    GridPane
    还是
    GridPane
    的子项?是的,很抱歉,我不想包含整个文件,但目标是对名为board的GridPane的引用(因此,Board.add调用)