1
votes

I'm having issue with dragging and dropping the label on each other. I could not able to drag the label and drop it onto another label. Event setOnDragDetected is detected and setOnDragDropped is not detected. These are the files.

FXML:


           <HBox fx:id="hboxTwo" alignment="CENTER" spacing="100" style="-fx-background-color: orange;">
               <padding>
                   <javafx.geometry.Insets bottom="25" left="25" right="25" top="25" />    
               </padding>
              <children>
                  <Label fx:id="labelTwo" prefHeight="50.0" text="labelTWO" />
              </children>    
           </HBox>
       </children>

    </HBox>

</center>

Controller:

public class HomeController implements Initializable {

@FXML
Label labelOne;

@FXML
Label labelTwo;

@FXML
HBox hboxOne;

@FXML
HBox hboxTwo;

@Override
public void initialize(URL url, ResourceBundle rb) {
    labelOne.setOnDragDetected((MouseEvent event) -> {
        System.out.println("source::" + event.getSource());
    });

    hboxTwo.setOnDragDropped((DragEvent event) -> {
        event.acceptTransferModes(TransferMode.ANY);
        System.out.println("source::" + event.getSource());
    });

    hboxTwo.setOnDragEntered((DragEvent event) -> {
        event.acceptTransferModes(TransferMode.ANY);
        System.out.println("source::" + event.getSource());
    });
}

}

2

2 Answers

1
votes

To make setOnDragDropped work, you have to set the TransferMode previously, and remove the according method call in setOnDragDropped:

 boxTwo.setOnDragOver((DragEvent event) -> {
        event.acceptTransferModes(TransferMode.ANY);
        event.consume();
 });

 boxTwo.setOnDragDropped((DragEvent event) -> {
        Label source = (Label) event.getGestureSource();
        boxTwo.getChildren().add(source);

        event.setDropCompleted()
        event.consume();
 });
1
votes

Just copy and pasting below, the relevant code for drag detection and dropping from the JavaFX 8 Drag and Drop tutorial.

When you compare the sample code to your code, you can see that you are missing stuff:

  1. You aren't constructing a Dragboard containing drag and drop data.
  2. You aren't extracting drag and drop data from a Dragboard on a drop.
  3. You aren't notifying that the drag and drop event was completed.
  4. You aren't appropriately consuming events.

source.setOnDragDetected(new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        /* drag was detected, start a drag-and-drop gesture*/
        /* allow any transfer mode */
        Dragboard db = source.startDragAndDrop(TransferMode.ANY);

        /* Put a string on a dragboard */
        ClipboardContent content = new ClipboardContent();
        content.putString(source.getText());
        db.setContent(content);

        event.consume();
    }
});

target.setOnDragOver(new EventHandler<DragEvent>() {
    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().hasString()) {
            /* allow for moving */
            event.acceptTransferModes(TransferMode.MOVE);
        }

        event.consume();
    }
});

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.hasString()) {
           target.setText(db.getString());
           success = true;
        }
        /* let the source know whether the string was successfully 
         * transferred and used */
        event.setDropCompleted(success);

        event.consume();
     }
});