nablex
nablex

Reputation: 4767

JavaFX event handler priority

I have a custom component with a "default" event handler (KeyEvent.KEY_PRESS in this case). However I want other people to be able to also register handlers that in this case get precedence so they have the ability to "override" default behavior.

Currently the handler order seems to be based on insertion order of the handlers, however my handler is always registered first as it is registered on creation of a new instance.

How do I control the priority of the event handlers in java fx to allow other people to register handlers that are triggered before mine is?

Upvotes: 1

Views: 2004

Answers (1)

James_D
James_D

Reputation: 209714

From the documentation:

A node can register more than one handler. The order in which each handler is called is based on the hierarchy of event types. Handlers for a specific event type are executed before handlers for generic event types. For example, a handler for the KeyEvent.KEY_TYPED event is called before the handler for the InputEvent.ANY event. The order in which two handlers at the same level are executed is not specified, with the exception that handlers that are registered by the convenience methods described in Working with Convenience Methods are executed last.

This implies there's really no way to guarantee your handler is invoked after client code handlers; however if you add your handler for the most generic event type, Event.ANY, then specific events will be handled before yours.

E.g.:

import javafx.application.Application;
import javafx.event.Event;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class EventPriorityTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        Pane testPane = new Pane();
        testPane.setFocusTraversable(true);

        testPane.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> 
            System.out.println("Mouse pressed handler added first"));

        testPane.addEventHandler(Event.ANY, e-> {
            if (e.getEventType() == MouseEvent.MOUSE_PRESSED) {
                System.out.println("Generic handler added second");
            }
        });

        testPane.setOnMousePressed(e -> 
            System.out.println("Mouse pressed handler added third via convenience method"));

        testPane.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> 
            System.out.println("Mouse pressed handler added fourth"));

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

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

In this example, the first and fourth event handlers will be executed first, but in no predetermined order. Then the third event handler (since it used the convenience method), and finally the second event handler (since it uses the most generic event type).

Upvotes: 2

Related Questions