RFR: 8290040: Provide simplified deterministic way to manage listeners [v13]

Kevin Rushforth kcr at openjdk.org
Mon Dec 12 22:24:19 UTC 2022


On Mon, 12 Dec 2022 21:57:18 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:

>> This PR adds a new (lazy*) property on `Node` which provides a boolean which indicates whether or not the `Node` is currently part of a `Scene`, which in turn is part of a currently showing `Window`.
>> 
>> It also adds a new fluent binding method on `ObservableValue` dubbed `when` (open for discussion, originally I had `conditionOn` here).
>> 
>> Both of these together means it becomes much easier to break strong references that prevent garbage collection between a long lived property and one that should be shorter lived. A good example is when a `Label` is bound to a long lived property:
>> 
>>      label.textProperty().bind(longLivedProperty.when(label::isShowingProperty));
>> 
>> The above basically ties the life cycle of the label to the long lived property **only** when the label is currently showing.  When it is not showing, the label can be eligible for GC as the listener on `longLivedProperty` is removed when the condition provided by `label::isShowingProperty` is `false`.  A big advantage is that these listeners stop observing the long lived property **immediately** when the label is no longer showing, in contrast to weak bindings which may keep observing the long lived property (and updating the label, and triggering its listeners in turn) until the next GC comes along.
>> 
>> The issue in JBS also describes making the `Subscription` API public, but I think that might best be a separate PR.
>> 
>> Note that this PR contains a bugfix in `ObjectBinding` for which there is another open PR: https://github.com/openjdk/jfx/pull/829 -- this is because the tests for the newly added method would fail otherwise; once it has been integrated to jfx19 and then to master, I can take the fix out.
>> 
>> (*) Lazy means here that the property won't be creating any listeners unless observed itself, to avoid problems creating too many listeners on Scene/Window.
>
> John Hendrikx has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 17 commits:
> 
>  - Merge branch 'openjdk:master' into feature/conditional-bindings
>  - Remove example referencing Node#shownProperty
>  - Remove changes to javafx.graphics Node
>  - Improve wording in javadoc and comments
>  - Adjust Node
>    
>    - Fixed javadoc
>    - Added comment for code that avoid eager instantiation
>    - Changed `isShown` to use property if it is available
>  - Fix javadoc error
>  - Fix comment in test
>  - Improve documentation of shown property
>  - Merge remote-tracking branch 'origin/master' into
>    feature/conditional-bindings
>    
>    # Conflicts:
>    #	modules/javafx.base/src/test/java/test/javafx/beans/value/LazyObjectBindingTest.java
>  - Fix review comments
>  - ... and 7 more: https://git.openjdk.org/jfx/compare/8763e8b0...24872f09

Looks good. The additional tests for `when` look to be quite thorough and are very easy to follow. I left one minor formatting comment. I'll reapprove if you fix that.

modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueFluentBindingsTest.java line 931:

> 929:         @Nested
> 930:         class WithNotNullReturns_ObservableValue_Which {
> 931:             private ObjectProperty<Boolean> condition = new SimpleObjectProperty<Boolean>(true);  // using object property here so it can be set to null for testing

Minor: can you wrap this line? (it's a fair bit longer than the recommended max of 120 or so)

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

Marked as reviewed by kcr (Lead).

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


More information about the openjfx-dev mailing list