简体   繁体   English

JavaFX拖放到GridPane吗?

[英]JavaFX Drag and drop to GridPane?

I have implemented a drag-and-drop function to my game, but so far I can only "drop" to hard-coded locations. 我已经为我的游戏实现了拖放功能,但是到目前为止,我只能“拖放”到硬编码位置。 As shown here: 如下所示:

在此处输入图片说明

在此处输入图片说明

What I would like is for either: 我想要的是:

  1. When the ships is dropped its x,y values (in relation to the GridPane) are saved, or 当船只掉落时,将保存其x,y值(相对于GridPane),或者
  2. The cell that the ship is dropped to is saved. 船舶放置到的单元格已保存。

My setOnDragDropped event is handled here: 我的setOnDragDropped事件在这里处理:

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

I feel like this should be simple to do as a MouseOver event or something similar but I am not sure what to do. 我觉得这作为MouseOver事件或类似事件应该很简单,但是我不确定该怎么做。

Edit: Full code for class below: 编辑:以下课程的完整代码:

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

} }

If you get access to the Node where this was actually dropped, you can determine the indices in the GridPane and use the same indices for the new node and/or use the indices any other way you want... 如果您可以访问实际上已删除该Node ,则可以确定GridPane的索引,并为新节点使用相同的索引和/或以其他任何需要的方式使用索引...

In this case you can get the target ImageView using DragEvent.getPickResult().getIntersectedNode() or Event.getTarget : 在这种情况下,您可以使用DragEvent.getPickResult().getIntersectedNode()Event.getTarget获取目标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();
}

Note: Since you use the drag events using the system clipboard, other applications may be the source or target of a drag gesture... 注意:由于您是通过系统剪贴板使用拖动事件的,因此其他应用程序可能是拖动手势的源或目标...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM