changeset 7844:2676b22761e5

RT-37792: [Accessibility] Combobox list items are counted incorrectly part 1: prevent screen reader from counting invalid list items.
author fheidric
date Mon, 25 Aug 2014 14:59:42 -0700
parents 0b9677f61b09
children 993ca4d96165
files modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java
diffstat 3 files changed, 28 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Mon Aug 25 11:57:57 2014 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ComboBoxListViewSkin.java	Mon Aug 25 14:59:42 2014 -0700
@@ -40,6 +40,7 @@
 import javafx.event.EventHandler;
 import javafx.event.EventTarget;
 import javafx.scene.AccessibleAttribute;
+import javafx.scene.AccessibleRole;
 import javafx.scene.Node;
 import javafx.scene.Parent;
 import javafx.scene.control.ComboBox;
@@ -575,7 +576,11 @@
                 comboBox.getButtonCell() : getDefaultCellFactory().call(listView);
         buttonCell.setMouseTransparent(true);
         buttonCell.updateListView(listView);
-    } 
+        // As long as the screen-reader is concerned this node is not a list item.
+        // This matters because the screen-reader counts the number of list item
+        // within combo and speaks it to the user.
+        buttonCell.setRole(AccessibleRole.NODE);
+    }
 
     private void updateCellFactory() {
         Callback<ListView<T>, ListCell<T>> cf = comboBox.getCellFactory();
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Mon Aug 25 11:57:57 2014 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/VirtualFlow.java	Mon Aug 25 14:59:42 2014 -0700
@@ -33,6 +33,7 @@
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
 import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.BooleanPropertyBase;
 import javafx.beans.value.ChangeListener;
@@ -40,6 +41,7 @@
 import javafx.event.EventDispatcher;
 import javafx.event.EventHandler;
 import javafx.geometry.Orientation;
+import javafx.scene.AccessibleRole;
 import javafx.scene.Group;
 import javafx.scene.Node;
 import javafx.scene.Parent;
@@ -1757,6 +1759,19 @@
             if (createCell != null) {
                 accumCell = createCell.call(this);
                 accumCellParent.getChildren().setAll(accumCell);
+
+                // Note the screen reader will attempt to find all
+                // the items inside the view to calculate the item count.
+                // Having items under different parents (sheet and accumCellParent)
+                // leads the screen reader to compute wrong values.
+                // The regular scheme to provide items to the screen reader
+                // uses getPrivateCell(), which places the item in the sheet.
+                // The accumCell, and its children, should be ignored by the
+                // screen reader. 
+                accumCell.setRole(AccessibleRole.NODE);
+                accumCell.getChildrenUnmodifiable().addListener((Observable c) -> {
+                    accumCell.getChildrenUnmodifiable().forEach(n -> n.setRole(AccessibleRole.NODE));
+                });
             }
         }
         setCellIndex(accumCell, index);
--- a/modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Mon Aug 25 11:57:57 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Mon Aug 25 14:59:42 2014 -0700
@@ -917,6 +917,13 @@
         if (count == null || count == 0) return 0;
         Integer index = (Integer)listItemAccessible.getAttribute(INDEX);
         if (index == null) return 0;
+
+        /* A view implementation can use stock items to measuring, these items can 
+         * have index equal to -1 for identification. See ViewFlow#accumCell as an example.
+         * These items should be ignored to avoid incorrect item count computation by
+         * the screen reader.
+         */
+        if (!(0 <= index && index < count)) return 0;
         switch (direction) {
             case NavigateDirection_NextSibling: index++; break;
             case NavigateDirection_PreviousSibling: index--; break;