On Mon, 3 Mar 2025 19:58:08 GMT, Andy Goryachev <[email protected]> wrote:
>> I don't know how to use Subscription in this case.
>> This does not work:
>>
>>
>> ObservableValue<Window> winProp =
>> sceneProperty().flatMap(Scene::windowProperty);
>> accessibilityActive = winProp; // keep the reference so it
>> won't get gc
>> Subscription sub = winProp.subscribe((win) -> {
>> if (win != null) {
>> if (accessibilityActive == winProp) {
>> accessibilityActive = null;
>> }
>> if (isAccessibilityActive()) {
>> handleAccessibilityActive(true);
>> }
>> //winProp.removeListener(this);
>> sub.unsubscribe(); <-- COMPILE ERROR
>> }
>> });
>
> @hjohn could you help here please? How could we use Subscription in a
> situation when it has to be unsubscribed from within the lambda?
I haven't been tracking these fixes for allowing initialization in background
threads, but it seems to me that basically anything should be allowed as long
as you're not part of a visible scene graph -- and I think there's also no
expectation that all functionality of a control "works" as long as it is not
yet part of such a graph (ie. the listeners are only needed once it is part of
a scene graph).
If you make listeners conditional on being part of a scene graph, then I think
you can handle these with a single code path. Such a condition would be:
ObservableValue<Boolean> partOfSceneGraph = node.sceneProperty()
.flatMap(Scene::windowProperty)
.flatMap(Window::showingProperty)
.orElse(false);
You can then safely install any listeners directly, regardless if they're on a
background thread or not:
someProperty().when(partOfSceneGraph).subscribe( ... );
Or:
someProperty().when(partOfSceneGraph).addListener( ... );
On a background thread, `partOfSceneGraph` will be `false`, and no listener
gets installed (yet). As soon as it becomes `true` all listeners with that
same condition become active. It becomes `true` automatically when the node
has a scene belonging to a window that is visible. Vice versa, if it ever
becomes `false` again, (which it may when the Node is removed or replaced) all
listeners using this condition are removed again.
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/1697#discussion_r1978157784