Reputation: 185
I have Pane with:
pane.addEventFilter(MouseEvent.ANY, new EventsHandler(e -> System.out.println(""), e -> {
createEvents(e.getX(), e.getY());
})});
And method createEvents:
Circle circle = new Circle(x, y, 5);
circle.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println("Clicked!"));
pane.getChildren().add(circle);
When I click in a circle, it calls two events: the string click and create a new event. How do you not passed click event to a parent?
My EvendsHandler add pane:
public class EventsHandler implements EventHandler<MouseEvent> {
private final EventHandler<MouseEvent> onDraggedEventHandler;
private final EventHandler<MouseEvent> onClickedEventHandler;
private boolean dragging = false;
public EventsHandler(EventHandler<MouseEvent> onDraggedEventHandler, EventHandler<MouseEvent> onClickedEventHandler) {
this.onDraggedEventHandler = onDraggedEventHandler;
this.onClickedEventHandler = onClickedEventHandler;
}
@Override
public void handle(MouseEvent event) {
if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
dragging = false;
} else if (event.getEventType() == MouseEvent.DRAG_DETECTED) {
dragging = true;
} else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
// maybe filter on dragging (== true)
onDraggedEventHandler.handle(event);
} else if (event.getEventType() == MouseEvent.MOUSE_CLICKED) {
if (!dragging) {
onClickedEventHandler.handle(event);
}}}}
Upvotes: 0
Views: 869
Reputation: 82451
You're using event filters. Filters are called while traversing from the root to the target node. Since all filters of the ancestors are called before a node's own filter is called it's impossible for the node's filter to prevent the execution of the parent's filter.
You should use event handlers instead which are called while traversing from the target node to the root node and allow you to prevent execution of the parent's event handlers by consuming the event:
pane.addEventHandler(MouseEvent.ANY, new EventsHandler(e -> System.out.println(""), e -> {
createEvents(e.getX(), e.getY());
})});
circle.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
System.out.println("Clicked!");
event.consume();
});
Note: If you only register a single event handler for a specific event type you can assign e.g. the onMouseClicked
property instead of using addEventHandler
:
circle.setOnMouseClicked(event -> {
System.out.println("Clicked!");
event.consume();
});
Upvotes: 1