Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop JavaFX Parent Node getting click after drag between children

I have a situation where I have a container node (HBox) and two child nodes in JavaFX. When I drag from the left child nodes in to the right, I get lots of drag events to the left node, and finally at the end when I release the mouse over the right node, I get a click event in the parent. Below is some code to replicate this situation.

What I want to know is: how do I stop the parent receiving this click event? I've tried all sorts of event filters and event handlers on the left and right nodes that consume the events, but I just can't seem to find the right one(s) to prevent the click event being sent to the parent. Any ideas?

package test;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class TestDrag extends Application
{

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        String leftHead = "Start dragging from me\n";
        String dragStarted = "Drag begun; staying simple\n";
        Label left = new Label(leftHead);

        left.setOnDragDetected(e -> {
            left.setText(leftHead + dragStarted);
            e.consume();
        });

        left.setOnMouseDragged(e -> {
            left.setText(leftHead + dragStarted + "Mouse dragged to: " + e.getSceneX() + ", " + e.getSceneY());
            e.consume();
        });

        left.setOnMouseReleased(e -> {
            left.setText(leftHead + "Mouse released\n");
            e.consume();
        });

        String rightHead = "Drag on to me\n";
        Label right = new Label(rightHead);
        right.setOnMouseClicked(e -> {
            right.setText(rightHead + "Clicked me!\n");
        });

        left.setPrefSize(400, 300);
        left.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, null, null)));
        right.setPrefSize(400, 300);
        right.setBackground(new Background(new BackgroundFill(Color.LIGHTPINK, null, null)));

        HBox hbox = new HBox(left, right);
        hbox.setOnMouseClicked(e -> {
            right.setText(rightHead + "Clicked the underlying HBox at " + System.currentTimeMillis() + "\n");
        });


        primaryStage.setScene(new Scene(hbox));
        primaryStage.show();
    }

}
like image 226
Neil Brown Avatar asked Oct 27 '14 14:10

Neil Brown


1 Answers

You can't prevent the event from happening per-se, but isStillSincePressed() (in MouseEvent) can be used in the parent (the HBox in this example) to distinguish between a click and a drag.

like image 71
Michael Berry Avatar answered Oct 24 '22 17:10

Michael Berry