How to stop playing JavaFX Parent Node after drag and drop between children

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

I want to know: how to stop the parent receiving this click event? I tried all kinds of event filters and event handlers on the left and right nodes that consume events, but I just can’t find the right ones (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(); } } 
+7
javafx javafx-8
source share
2 answers

You cannot prevent an accidental event, but isStillSincePressed() (in MouseEvent ) can be used in the parent ( HBox in this example) to distinguish between click and drag.

+9
source share

My second reaction (as noted): how strange. My expectation of a click is Swing-based (probably Win-based also seems to remember VB for a long time): the click is received when both are pressed / released on the same component in the same place.

The semantics of FX are different because they come from actually reading the MouseEvent.MOUSE_CLICKED document:

 /** * This event occurs when mouse button has been clicked (pressed and * released on the same node). This event provides a button-like behavior * to any node. Note that even long drags can generate click event (it * is delivered to the top-most node on which the mouse was both * pressed and released). */ 

So, a short answer to your question: you cannot prevent a click on the parent. Depending on what you need to achieve, there are options for how to deal with the pressed:

  • don't use it at all, use pressed / released
  • implement your own semantics with the same location: listen to the pressed button at the capture stage, save the location, compare locations in a click and cause a reaction only if it is close to
0
source share

All Articles