<div dir="ltr">Didn't look too deep, but seems like a bug or incorrect doc. I don't see such specifications in other "setOnX" methods.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, May 28, 2023 at 1:02 PM John Hendrikx <<a href="mailto:john.hendrikx@gmail.com">john.hendrikx@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">When looking at the code for Scene#setOnKeyPressed, I noticed that it <br>
calls Scene#setEventHandler.  This is documented as:<br>
<br>
     /**<br>
      * Sets the handler to use for this event type. There can only be <br>
one such<br>
      * handler specified at a time. This handler is guaranteed to be called<br>
      * first. This is used for registering the user-defined onFoo event<br>
      * handlers.<br>
      *<br>
      * @param <T> the specific event class of the handler<br>
      * @param eventType the event type to associate with the given <br>
eventHandler<br>
      * @param eventHandler the handler to register, or null to unregister<br>
      * @throws NullPointerException if the event type is null<br>
      */<br>
     protected final <T extends Event> void setEventHandler(<br>
             final EventType<T> eventType,<br>
             final EventHandler<? super T> eventHandler) {<br>
<br>
Note that it specifically says "This handler is guaranteed to be called <br>
first."<br>
<br>
This function eventualy calls CompositeEventHandler#setEventHandler.  <br>
This class tracks a chain of handlers, and reserves a special spot for a <br>
single special "eventHandler".  Yet, in its dispatchBubblingEvent <br>
method, it clearly calls the "special" handler LAST... see below:<br>
<br>
     public void dispatchBubblingEvent(final Event event) {<br>
         final T specificEvent = (T) event;<br>
<br>
         EventProcessorRecord<T> record = firstRecord;<br>
         while (record != null) {<br>
             if (record.isDisconnected()) {<br>
                 remove(record);<br>
             } else {<br>
                 record.handleBubblingEvent(specificEvent);<br>
             }<br>
             record = record.nextRecord;<br>
         }<br>
<br>
         if (eventHandler != null) {<br>
             eventHandler.handle(specificEvent);<br>
         }<br>
     }<br>
<br>
I've confirmed this with this small program (order of calls doesn't make <br>
a difference):<br>
<br>
     public static class App extends Application {<br>
       @Override<br>
       public void start(Stage primaryStage) {<br>
         Button button1 = new Button("111");<br>
<br>
         HBox hBox = new HBox();<br>
         hBox.getChildren().addAll(button1);<br>
         Scene scene = new Scene(hBox, 300, 300);<br>
<br>
         scene.addEventHandler(KeyEvent.KEY_PRESSED, e -> {<br>
           System.out.println("KeyPressedHandler " + e);<br>
         });<br>
         scene.setOnKeyPressed(e -> {<br>
           System.out.println("Main " + e);<br>
           e.consume();<br>
         });<br>
<br>
         primaryStage.setScene(scene);<br>
         primaryStage.show();<br>
       }<br>
<br>
Which outputs the events not in the order documented:<br>
<br>
KeyPressedHandler KeyEvent [source = javafx.scene.Scene@36dbf594, target <br>
= Button@5dd3d27e[styleClass=button]'111', eventType = KEY_PRESSED, <br>
consumed = false, character =  , text = f, code = F]<br>
Main KeyEvent [source = javafx.scene.Scene@36dbf594, target = <br>
Button@5dd3d27e[styleClass=button]'111', eventType = KEY_PRESSED, <br>
consumed = false, character =  , text = f, code = F]<br>
<br>
--John<br>
<br>
</blockquote></div>