2

I have a node I want to implement drag and drop for (this object is the source not the target). I also want the object to move along with the mouse cursor. I managed to do both of these but not at the same time.

It appears that setOnDragDetected and setOnMouseDragged don't work well together. Consider a node with the following handlers:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Example extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        Rectangle rect = new Rectangle(20, 20);
        rect.setOnMousePressed(e -> System.out.println("Pressed"));
        rect.setOnMouseDragged(e -> System.out.println("Dragged"));
        rect.setOnDragDetected(e -> {
            System.out.println("Detected");
            ClipboardContent content = new ClipboardContent();
            content.putString("something");
            Dragboard db = rect.startDragAndDrop(TransferMode.ANY);
            db.setContent(content);
        });
        Group subGroup = new Group(rect);

        Scene scene = new Scene(subGroup, 100, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {

        Example.launch(args);
    }
}

Now press the mouse on the node and move the mouse. This is the output:

Pressed
Dragged
Dragged
Dragged
Dragged
Dragged
Dragged
Detected

Once the drag is detected the MouseDragged handler stops.

How do I achieve what I described? One thing i noticed was maybe that I can use a onDragOver for the parent but i want the behavior to be in the node because that's where it really should be.

Mark
  • 2,167
  • 4
  • 32
  • 64
  • I don't observe this behavior at all; the `onMouseDragged` handler continues reporting after the drag gesture is detected. You should create a [MCVE] and [edit] your question to include it. – James_D Nov 17 '16 at 16:33
  • @James_D sorry. here is the code. it has to do with the dragboard i think. – Mark Nov 17 '16 at 16:55

1 Answers1

1

You are mixing two things up here. In short, when you call the startDragAndDrop method the system switches to drag and drop mode and Java stops delivering MouseEvent to rect.

The MouseEvent documentation has a section "Dragging gestures" which explains the three types of dragging gestures. Here is just a short summary:

  • simple press-drag-release - when a drag is detected Java continues to deliver MouseEvents to the node where the drag was detected.
  • full press-drag-release - you can call startFullDrag inside the handler you set with setOnDragDetected. Then Java also starts to deliver MouseDragEvents to other nodes (potential gesture targets).
  • platform-supported drag-and-drop - if you call startDragAndDrop inside the OnDragDetected handler, Java will stop to deliver MouseEvents and start to deliver DragEvents instead. This is used for drag and drop interaction with other applications.

It is not clear to me what you want to achieve, but as long as you do not want to drag something outside of your application, try using startFullDrag instead.

Also, it might be helpful to have a further look at the DragEvent and MouseDragEvent documentation.

Mark
  • 2,167
  • 4
  • 32
  • 64
FelixRabe
  • 976
  • 7
  • 9
  • I need only events within my application. If I use `startFullDrag` the target nodes don't react to `OnDragEntered` and exited. Something needs to check that a drag and drop operation is happening, is entering/leaving their space and react according to the content - if it's valid or not. this I can do only with `startDragAndDrop`. – Mark Nov 18 '16 at 04:45
  • @Mark if you use `startFullDrag` you need to set the `OnMouseDragEntered` handler on the target instead of `OnDragEntered`. – FelixRabe Nov 18 '16 at 07:14
  • yes, but the functionality of the mouse drag handlers is different than the D&D handlers. for example: `OnDragDone` allows to do things on the source at the end of the drag, but there is no equivalent for it like "onMouseDragDone". Also the mouse pointer doesn't change to indicate if the drop target is valid or not like it does with D&D. – Mark Nov 18 '16 at 14:45