RFR: JDK-8304439: Subscription based listeners [v2]
John Hendrikx
jhendrikx at openjdk.org
Tue Apr 18 00:39:01 UTC 2023
On Mon, 10 Apr 2023 19:18:42 GMT, Michael Strauß <mstrauss at openjdk.org> wrote:
>> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision:
>>
>> Move Subscription method for invalidations to Observable
>>
>> - moved Subscription class to the Observable package
>
> modules/javafx.base/src/main/java/javafx/beans/Observable.java line 107:
>
>> 105: * @since 21
>> 106: */
>> 107: default Subscription invalidations(Runnable subscriber) {
>
> I think re-using `InvalidationListener` may fit better into the existing JavaFX API:
>
> interface Observable {
> Subscription subscribe(InvalidationListener);
> }
>
>
> The method can then be overloaded for `ChangeListener`, `ListChangeListener`, `SetChangeListener`, and `MapChangeListener` as well. Doing so allows users to use the same functional interfaces they've used before with the `addListener`/`removeListener` APIs.
>
> As an added bonus, we don't need to allocate a wrapper for the listeners.
This would depend I think how you want to approach this. I added three variants, invalidations, changes and values. Using the same name `subscribe`, you need to make sure the lambda's used all have a different arity, or you'll need to add a cast to disambiguate them.
I purposely removed the first `Observable` parameter on all of the variants because I think it will be a much better match when you want to register a listener, and "pipe" it to some existing code. Now we often have to "strip" the unnecessary parameter. I can't do this easily for example:
minimumWidthProperty().addListener(this::requestLayout);
selectedItem.addListener(getSelectionModel()::select);
modelStatus.addListener(statusLabel.textProperty()::set);
It must be these now:
minimumWidthProperty().addListener(obs -> this.requestLayout());
selectedItem.addListener((obs, o, n) -> gelectionModel().select(n));
modelStatus.addListener((obs, o, n) -> statusLabel.setText(n));
The `values` variant is highly useful for this, as `ChangeListener` has a 2nd rarely used parameter (oldValue).
Also I think calling unsubscribe on subscriptions should preferably be the only way to remove a listener again; reusing the existing listeners would allow you to bypass this with `removeListener`.
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/1069#discussion_r1169379284
More information about the openjfx-dev
mailing list