-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
None
Apparently I’m not the only developer to discover that after firing an event the consumed flag is almost guaranteed to be false even if the event was consumed. I’m also not the first to start poking around and discover that there’s a lot of event copying going on. The JavaDocs are not clear on why this is happening or the correct way to determine if an event was consumed after being fired. As an example of this confusion look at the fix for JDK-8207774 which only partially solves the original issue.
This is largely because the way event dispatch works isn’t well documented. The following points need to be added to the documentation (somewhere).
- The consumed flag is used by an event handler or filter to signal that the event has been handled and dispatch can end. It is only used locally to communicate between a handler and the event dispatcher that invoked the handler.
- Event dispatchers use a different method of signaling that an event has been handled and dispatch should end; the dispatchEvent call returns null. This isn’t clearly spelled out in the EventDispatcher documentation but only mentioned in passing in the description of the return value from dispatchEvent.
- With the exception of the consumed flag events are treated as immutable objects. If an event is fired at a new target the system may make a copy of the event with the correct target and send it down the dispatch chain. If a dispatcher needs to update the `source` of an event it will also make a copy before passing it to a handler. This almost guarantees that the event passed to an event handler won’t be the same event that was passed into fireEvent.
- It is never guaranteed that the event passed to fireEvent will be the same one passed to a handler. There’s also no guarantee that the event passed into or returned from a dispatcher’s dispatchEvent call will be the same one passed to a handler.
- The correct way of determining that an event has been consumed after being fired is to check the return value of dispatchEvent for null.
- The documentation for the Event `source` field is inherited from AWT and is incorrect. What AWT treats as the `source` corresponds to the JavaFX `target`. In JavaFX the `source` is the object the event handler was registered on.
- Event dispatchers are responsible for ensuring that the `source` field is correct before invoking a handler. This isn’t currently documented and isn't shown in the sample code.
- After the capturing phase an event dispatcher may have two separate events in hand, the one passed into it’s dispatchEvent call and the one produced by calling dispatchEvent on the next dispatcher in the chain. Which of these events should be used during the bubbling phase? The sample code suggests that the second event should be used but this isn’t actually stated in the text.
A developer should not be required to understand all of this if they just want to fire an event and check if it was consumed. There should be a variant of Event.fireEvent() that returns this information (see JDK-8303209). There should also be a note pointing out that checking the consumed flag isn’t the correct way to do this.
This is largely because the way event dispatch works isn’t well documented. The following points need to be added to the documentation (somewhere).
- The consumed flag is used by an event handler or filter to signal that the event has been handled and dispatch can end. It is only used locally to communicate between a handler and the event dispatcher that invoked the handler.
- Event dispatchers use a different method of signaling that an event has been handled and dispatch should end; the dispatchEvent call returns null. This isn’t clearly spelled out in the EventDispatcher documentation but only mentioned in passing in the description of the return value from dispatchEvent.
- With the exception of the consumed flag events are treated as immutable objects. If an event is fired at a new target the system may make a copy of the event with the correct target and send it down the dispatch chain. If a dispatcher needs to update the `source` of an event it will also make a copy before passing it to a handler. This almost guarantees that the event passed to an event handler won’t be the same event that was passed into fireEvent.
- It is never guaranteed that the event passed to fireEvent will be the same one passed to a handler. There’s also no guarantee that the event passed into or returned from a dispatcher’s dispatchEvent call will be the same one passed to a handler.
- The correct way of determining that an event has been consumed after being fired is to check the return value of dispatchEvent for null.
- The documentation for the Event `source` field is inherited from AWT and is incorrect. What AWT treats as the `source` corresponds to the JavaFX `target`. In JavaFX the `source` is the object the event handler was registered on.
- Event dispatchers are responsible for ensuring that the `source` field is correct before invoking a handler. This isn’t currently documented and isn't shown in the sample code.
- After the capturing phase an event dispatcher may have two separate events in hand, the one passed into it’s dispatchEvent call and the one produced by calling dispatchEvent on the next dispatcher in the chain. Which of these events should be used during the bubbling phase? The sample code suggests that the second event should be used but this isn’t actually stated in the text.
A developer should not be required to understand all of this if they just want to fire an event and check if it was consumed. There should be a variant of Event.fireEvent() that returns this information (see JDK-8303209). There should also be a note pointing out that checking the consumed flag isn’t the correct way to do this.