JavaFX brings a new event handling approach, making an improvement over the Java use of the too verbose observer pattern.
Normally in javafx you’ll use binding to listen to state changes and update other objects as appropriate. However this approach is not adequate when you want to listen to something that doesn’t imply a state change, something like say pressing a button (not a two state button, that would involve state).
With this post I wanted to share an idea I had about how javafx could handle those cases not covered by binding.
In JavaFX functions are variables, you can have a sequence of functions with this:
var buttonPressedListeners: function(:MouseEvent)[];
Let’s say you have a button and every time the button is pressed you iterate through the sequence above and call the listener functions. If you want to expose this to any interested listener you can declare the above sequence public. Now lets say a listener wants to register for listening, he can do so by inserting a function on the listener sequence:
insert fooListener into button.buttonPressedListeners;
If he wants to unregister this simple call would do it:
delete fooListener from button.buttonPressedListeners;
There is however a problem with this, you can insert the same listener two times into the sequence. We could iterate through the sequence list and check for duplicates but that would imply writing the same boiler plate code over and over again. So I would propose a language feature to enable declaring a sequence which doesn’t allow repeating values. Something like:
var buttonPressedListeners: function(:MouseEvent) unique [];
Every time you want to call the functions on the sequence you’ll have to write down a for each statement which iterates through the sequence of functions, to fix this I would propose a second language feature: the ability to call all the functions in a function sequence with a single method call.
And that’s my event handling proposal. 🙂
Maybe it’s much simpler to just have maps and sets as first-class JavaFX Script data types? Then it’s just changing the type of buttonPressedListeners to set-of-functions, and you don’t have the duplication issue anymore.
In this specific example of event listeners, this might only work if the set preserves iteration order, like JavaSE’s LinkedHashSet. But other scenarios wouldn’t have this requirement.
Even in the current system, a simple on replace trigger could be used to check for duplication. These sequences are usually very small (0-1 elements should be dominant) so even a linear scan is basically free, no need of O(1) lookup.
Osvaldo, thanks for commenting.
If javafx had generics those sets could be typified to be of a specific function type.
Cheers