RFR: JDK-8304439: Subscription based listeners [v7]

John Hendrikx jhendrikx at openjdk.org
Sun Jul 9 20:40:08 UTC 2023


On Sun, 9 Jul 2023 18:48:16 GMT, Jose Pereda <jpereda at openjdk.org> wrote:

>> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Add newline at end of ConditionalBinding file
>
> modules/javafx.base/src/main/java/javafx/beans/Observable.java line 110:
> 
>> 108:     default Subscription subscribe(Runnable subscriber) {
>> 109:         Objects.requireNonNull(subscriber, "subscriber cannot be null");
>> 110:         InvalidationListener listener = obs -> subscriber.run();
> 
> InvalidationListeners are widely used in this pattern:
> 
> 
> javaFXProperty.addListener(new InvalidationListener() {
>             @Override
>             public void invalidated(Observable observable) {
>                 if (value.get() != null) {
>                     // do something
>                     javaFXProperty.removeListener(this);
>                 }
>             }
>         });
> 
> 
> Does subscribe/unsubscribe allows something like this?

The new `subscribe` methods don't support this usage, but they're also not intended to replace the old methods.  Cases like the one you show above, but also cases where a single listener is registered on many properties still are best handled using the `addListener`/`removeListener` methods.  I consider them more advanced usage which you are more likely to encounter in the internals of JavaFX or libraries.

I don't see this pattern that often though, but I know it exists as removing listeners during notification is something that `ExpressionHelper` specifically needs to deal with (also see https://github.com/openjdk/jfx/pull/1081 where I'm advocating for a better `ExpressionHelper` that provides correct old values when dealing with nested notifications and listener list changes).

I suppose you could still do this in a hacky way:

      private Subscription subscription;

      {
           subscription = property.subscribe(() -> {
                 if (condition) {
                     this.subscription.unsubscribe();
                 }
           });
      }

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1069#discussion_r1257538675


More information about the openjfx-dev mailing list