RFR: JDK-8304323 Provide infrastructure to make it possible for properties to delay listener registration [v2]

John Hendrikx jhendrikx at openjdk.org
Mon Apr 17 11:32:44 UTC 2023


> This PR contains changes to make it easier to implement properties which want to conserve resources until they're observed themselves.  
> 
> `isObserved` is promoted from `ObjectBinding` to the `ObservableValue` interface, allowing you to ask any `ObservableValue` if it is currently observed (ie. if it has any listeners registered on it).  All JavaFX `ObservableValue`s implementations are modified to implement this method.
> 
> The protected methods `observed` and `unobserved` are added to all extendable (non final) `ObservableValue`s provided by JavaFX.  The `observed` call back is only called when the observable currently has 0 listeners and will soon have 1 listener.  During the call back, `isObserved` still returns `false` (see below for why this was chosen).  The `unobserved` call back is only called when the last listener was removed and the observable has 0 listeners.  During the call back, `isObserved` will already return `false`.
> 
> The reason why `observed` is called before `isObserved` starts returning `true` (and also why `unobserved` works the opposite) is to make it easy to implement a parent-child relationship where a nested property becoming observed may need to trigger behavior in its parent. Given a parent class and two nested properties `foo` and `bar`:
> 
>      class FooProperty extends ObjectPropertyBase<Foo> {
>           void observed() {
>                nestedPropertyObserved();  // call to parent
>           }
> 
>           void unobserved() {
>                nestedPropertyUnobserved();  // call to parent
>           }
>      }
> 
> The parent may determine whether any of the properties is observed with a helper:
> 
>       private boolean isANestedPropertyObserved() {
>            return foo.isObserved() || bar.isObserved();
>       }
> 
> The `nestedPropertyObserved` and `nestedPropertyUnobserved` methods can now be implemented simply as:
> 
>       private void nestedPropertyObserved() {
>             if (!isANestedPropertyObserved()) {
>                 // take action as no properties were observed before, but now one will become observed
>             }
>       }
> 
>       private void nestedPropertyUnobserved() {
>             if (!isANestedPropertyObserved()) {
>                 // take action as a property was observed before, but the last listener is about to be removed
>             }
>       }
> 
> If `isObserved` would change immediately, this becomes more difficult as the observed status of the property that has just become observed would need to be excluded to determine if this is the first observation of a nested property or a later one.
> 
> - Add `isObserved` to `ObservableValue` to check if it is observed and implement it in all overriding classes
> - Add `observed`/`unobserved` protected methods to all extendable observables
> - Use *Base classes in a few places (avoids duplication code)
> - Simplify `LazyObjectBinding`
> - In `ObjectBinding`, `isObserved` has become public as it is specified by the `ObservableValue` interface now

John Hendrikx has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits:

 - Merge branch 'master' into feature/delayed-infra
 - Add delayed listener registration support
   
   - Add isObserved to ObservableValue to check if it is observed
   - Add observed/unobserved protected methods to all subclassable
   observables
   - Use *Base classes in a few places (avoids duplication code)
   - Simplify LazyObjectBinding
   - In ObjectBinding, isObserved has become public as it is specified by
   the ObservableValue interface now

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

Changes: https://git.openjdk.org/jfx/pull/1023/files
 Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1023&range=01
  Stats: 1225 lines in 43 files changed: 802 ins; 211 del; 212 mod
  Patch: https://git.openjdk.org/jfx/pull/1023.diff
  Fetch: git fetch https://git.openjdk.org/jfx.git pull/1023/head:pull/1023

PR: https://git.openjdk.org/jfx/pull/1023


More information about the openjfx-dev mailing list