On Thu, 1 Dec 2022 17:38:01 GMT, John Hendrikx <jhendr...@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 incrementally with one additional 
> commit since the last revision:
> 
>   Adjust Node
>   
>   - Fixed javadoc
>   - Added comment for code that avoid eager instantiation
>   - Changed `isShown` to use property if it is available

modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 1413:

> 1411:      * Indicates whether or not this {@code Node} is shown. A node is 
> considered shown if it's
> 1412:      * part of a {@code Scene} that is part of a {@code Window} whose
> 1413:      * {@link Window#showingProperty showing property} is {@code true}. 
> The {@link Node#visibleProperty visibility}

I think you should choose one of the following:
`...whose {@link Window#showingProperty} is...`
`...whose {@link Window#showingProperty showing} property is...`

modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 1420:

> 1418:      * <p>
> 1419:      * This property can also be used to start animations when the node 
> is shown, and to stop them
> 1420:      * when it is no longer shown.

This sentence sounds like `shownProperty()` is quite deeply connected to 
animations, which it isn't. Maybe you can clarify with "For example, ..."?

modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 1437:

> 1435:     }
> 1436: 
> 1437:     public final ReadOnlyBooleanProperty shownProperty() {

This property probably should have been named `showing` to align it with 
`Window.showing`, but the "good name" is already taken by `ComboBox` and other 
controls. Just out of interest, have you considered alternatives to `shown`?

modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 1443:

> 1441:                 .flatMap(Window::showingProperty);  // note: the null 
> case is handled by the delegate with an orElse(false)
> 1442: 
> 1443:             shown = new ReadOnlyBooleanDelegate(Node.this, "shown", ov);

`shownProperty()` might be used quite a lot, have you considered using a 
specialized implementation that doesn't need several intermediate observable 
values?

modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 1453:

> 1451:         private final ObservableValue<Boolean> delegate;
> 1452:         private final Object bean;
> 1453:         private final String name;

You could omit the `bean` and `name` fields by making this a non-static inner 
class and returning `Node.this` and `"shown"` directly from `getBean()` and 
`getName()` respectively. In that case, you could also make this class an 
anonymous implementation of `ReadOnlyBooleanProperty`. This pattern is used 
quite extensively in JavaFX, since it can potentially save a few bytes of 
memory.

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

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

Reply via email to