JavaFX拖放到GridPane?

时间:2016-12-11 15:59:58

标签: java javafx javafx-8

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

enter image description here

enter image description here

我想要的是:

  1. 当船只掉落时,x,y值(相对于GridPane)被保存,或
  2. 保存了放置船只的单元格。
  3. 我的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();
            }
        });
    

    我觉得这应该像MouseOver事件或类似事件一样简单,但我不知道该怎么做。

    编辑:以下课程的完整代码:

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

    }

1 个答案:

答案 0 :(得分:4)

如果您可以访问实际丢弃的Node,您可以确定GridPane中的索引,并为新节点使用相同的索引和/或以任何其他方式使用索引你想要......

在这种情况下,您可以使用ImageViewDragEvent.getPickResult().getIntersectedNode()获取目标Event.getTarget

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

注意:由于您使用系统剪贴板使用拖动事件,因此其他应用程序可能是拖动手势的来源或目标......