How to redirect MouseEvent.MOUSE_PRESSED to another Node?

I have an area called "R" and Node called "N". N is the only child on R. Consider this behavior:

  • the user presses the left mouse button on some part of R
  • N (which is somewhere else on R) moves so that it is centered on the place where the user clicked
  • the user releases the left mouse button and then clicks it again without moving the mouse.
  • with the left mouse button pressed, the user drags the mouse, and N now follows the mouse cursor when it is dragged.

I have no problem implementing the behavior I just described. I set the MOUSE_PRESSED handler to R, which implements step 2. And I set the MOUSE_DRAGGED handler to N, which implements step 4. JavaFX automatically routes MouseEvents to these handlers to R and N for presses in steps 1 and 3, respectively.

Problem:

I need to do this WITHOUT step 3. That is, the user will not need to press the "press release-click-drag" key, but instead just need to click "drag", and "N" should "go" to the mouse position on " click "and then immediately start receiving MOUSE_DRAGGED events.

Unfortunately, this does not happen. The click that I am trying to skip seems to be necessary, otherwise the drag events occur on R instead of N.

, MOUSE_PRESSED - . - ( ?)

+4
2

Node api, :

public void startFullDrag()

node . DRAG_DETECTED . MouseEvent MouseDragEvent.

, node ( / ),

  • mousePressed , .
  • dragDetected , startFullDrag
  • dragAny ,

:

pane.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        circle.setCenterX(event.getX());
        circle.setCenterY(event.getY());
    }
});
pane.setOnDragDetected(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        circle.startFullDrag();
    }
});
circle.addEventHandler(MouseDragEvent.ANY, new EventHandler<MouseDragEvent>() {
    @Override
    public void handle(MouseDragEvent event) {
        circle.setCenterX(event.getX());
        circle.setCenterY(event.getY());
    }
});
+2

node , , :

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class ClickAndDragTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        final Pane pane = new Pane();
        final Circle circle = new Circle(100, 100, 50, Color.CORNFLOWERBLUE);
        pane.getChildren().add(circle);

        pane.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                circle.setCenterX(event.getX());
                circle.setCenterY(event.getY());
            }
        });
        pane.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                circle.setCenterX(event.getX());
                circle.setCenterY(event.getY());
            }
        });

        final Scene scene = new Scene(pane, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
+2

All Articles