On Tue, 25 Feb 2025 22:33:40 GMT, Andy Goryachev <ango...@openjdk.org> wrote:

>> Root Cause:
>> (Multiple) properties are getting bound to the global 
>> `Platform.accessibilityActive` property. Binding (and I say, accessing) of 
>> properties is not thread-safe.
>> 
>> I also changed the design a bit.  Originally, every symbol in a chart had 
>> its `focusTraversableProperty` bound to `Platform.accessibilityActive` in 
>> order to enable the accessibility navigation across the chart data points.  
>> This is rather inefficient, as the property has to manage (thousands?) of 
>> listeners.
>> 
>> Instead, a single boolean property is added to each chart, with a listener 
>> added to it which iterates over data symbols to toggle the 
>> `focusTraversableProperty` directly.
>> 
>> The exact moment when the new property gets bound is also important, and has 
>> to happen in the FX application thread.
>> 
>> With this change, it is safe to create and populate charts with data in a 
>> background thread.
>> 
>> ---
>> 
>> ## NOTES
>> 
>> 1. It looks like the `Platform.accessibilityActive` property never 
>> transitions back to false  after it transitioned to true.  Some say it is 
>> because there is no mechanism in the platform to get notified which cannot 
>> possibly be true.
>> 2. The javadoc for `Platform.accessibilityActiveProperty()` method 
>> stipulates that "_This method may be called from any thread_" which is 
>> patently not true as the current implementation is simply not thread-safe.
>> 
>> ## Note to the Reviewers
>> 
>> To avoid merge conflicts, the preferred order of integrations:
>> 
>> #1697 
>> #1713 
>> #1717
>
> Andy Goryachev has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains 25 commits:
> 
>  - Merge remote-tracking branch 'origin/master' into 
> 8349091.charts.thread.safety
>  - review comments
>  - Merge remote-tracking branch 'origin/master' into 
> 8349091.charts.thread.safety
>  - Merge remote-tracking branch 'origin/master' into 
> 8349091.charts.thread.safety
>  - enabled pie chart test
>  - Merge branch 'master' into 8349091.charts.thread.safety
>  - Merge branch 'master' into 8349091.charts.thread.safety
>  - whitespace
>  - Merge remote-tracking branch 'origin/master' into 
> 8349091.charts.thread.safety
>  - cleanup
>  - ... and 15 more: https://git.openjdk.org/jfx/compare/7a7854c9...4288d1d0

What you have now works in all cases I've tried. I left a couple suggestions 
and will reapprove if you decide to make changes.

modules/javafx.controls/src/main/java/javafx/scene/chart/Chart.java line 106:

> 104: 
> 105:     // SimpleBooleanProperty or ObjectBinding
> 106:     private volatile Object accessibilityActive;

You can use `ObservableValue<?>` instead of `Object` as the type. 
Alternatively, use two fields, a `SimpleBooleanProperty` for use by the FX app 
thread and an ObjectBinding for use by a background thread. They wouldn't need 
to be volatile in that case. What you have is OK, but using two properties 
might simplify the logic a bit.

modules/javafx.controls/src/main/java/javafx/scene/chart/Chart.java line 561:

> 559:                 accessibilityActive = winProp; // keep the reference so 
> it won't get gc
> 560: 
> 561:                 // lambda cannot be used in place of a ChangeListener in 
> removeListener()

Why not use a Subscription then? It seems tailor-made for what you are trying 
to do.

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

Marked as reviewed by kcr (Lead).

PR Review: https://git.openjdk.org/jfx/pull/1697#pullrequestreview-2644733749
PR Review Comment: https://git.openjdk.org/jfx/pull/1697#discussion_r1971704069
PR Review Comment: https://git.openjdk.org/jfx/pull/1697#discussion_r1971713667

Reply via email to