src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java

Print this page

        

@@ -4502,22 +4502,28 @@
     /**
      * Gets the number of visible children of an AccessibleContext.
      *
      * Bug ID 4944762- getVisibleChildren for list-like components needed
      */
-    private int _visibleChildrenCount;
-    private AccessibleContext _visibleChild;
-    private int _currentVisibleIndex;
-    private boolean _foundVisibleChild;
+    private volatile int _visibleChildrenCount;
+    private volatile AccessibleContext _visibleChild;
+    private volatile int _currentVisibleIndex;
+    private volatile boolean _foundVisibleChild;
 
     private int getVisibleChildrenCount(AccessibleContext ac) {
         debugString("getVisibleChildrenCount");
         if (ac == null) {
             return -1;
         }
         _visibleChildrenCount = 0;
+        InvocationUtils.invokeAndWait(new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
         _getVisibleChildrenCount(ac);
+                return null;
+            }
+        }, ac);
         debugString("  _visibleChildrenCount = "+_visibleChildrenCount);
         return _visibleChildrenCount;
     }
 
     /*

@@ -4525,50 +4531,74 @@
      * of visible children
      */
     private void _getVisibleChildrenCount(final AccessibleContext ac) {
         if (ac == null)
             return;
-        int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
-            @Override
-            public Integer call() throws Exception {
-                return ac.getAccessibleChildrenCount();
+        if(ac instanceof AccessibleExtendedTable) {
+            _getVisibleChildrenCount((AccessibleExtendedTable)ac);
+            return;
             }
-        }, ac);
+        int numChildren = ac.getAccessibleChildrenCount();
         for (int i = 0; i < numChildren; i++) {
-            final int idx = i;
-            final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
-                @Override
-                public AccessibleContext call() throws Exception {
-                    Accessible a = ac.getAccessibleChild(idx);
-                    if (a != null)
-                        return a.getAccessibleContext();
-                    else
-                        return null;
+            ;
+            Accessible a = ac.getAccessibleChild(i);
+            AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null;
+            if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) {
+                continue;
+            }
+            _visibleChildrenCount++;
+
+            if (ac2.getAccessibleChildrenCount() > 0 ) {
+                _getVisibleChildrenCount(ac2);
                 }
-            }, ac);
-            if ( ac2 == null ||
-                 (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
-                     @Override
-                     public Boolean call() throws Exception {
-                         return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
                      }
-                 }, ac))
-               ) {
+    }
+
+    /*
+    * Recursively descends AccessibleContext and gets the number
+    * of visible children. Stops search if get to invisible part of table.
+    */
+    private void _getVisibleChildrenCount(final AccessibleExtendedTable acTable) {
+        if (acTable == null)
+            return;
+        int lastVisibleRow = -1;
+        int lastVisibleColumn = -1;
+        boolean foundVisible = false;
+        int rowCount = acTable.getAccessibleRowCount();
+        int columnCount = acTable.getAccessibleColumnCount();
+        for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+            for (int columnIdx = 0; columnIdx < columnCount; columnIdx++) {
+                if (lastVisibleRow != -1 && rowIdx > lastVisibleRow) {
                 continue;
             }
+                if (lastVisibleColumn != -1 && columnIdx > lastVisibleColumn) {
+                    continue;
+                }
+                Accessible a = acTable.getAccessibleAt(rowIdx, columnIdx);
+                AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null;
+                if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) {
+                    if (foundVisible) {
+                        if (columnIdx != 0 && lastVisibleColumn == -1) {
+                            //the same row, so we found the last visible column
+                            lastVisibleColumn = columnIdx - 1;
+                        } else if (columnIdx == 0 && lastVisibleRow == -1) {
+                            lastVisibleRow = rowIdx - 1;
+                        }
+                    }
+                    continue;
+                }
+
+                foundVisible = true;
+
             _visibleChildrenCount++;
 
-            if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
-                @Override
-                public Integer call() throws Exception {
-                    return ac2.getAccessibleChildrenCount();
-                }
-            }, ac) > 0 ) {
+                if (ac2.getAccessibleChildrenCount() > 0) {
                 _getVisibleChildrenCount(ac2);
             }
         }
     }
+    }
 
     /**
      * Gets the visible child of an AccessibleContext at the
      * specified index
      *

@@ -4580,11 +4610,17 @@
             return null;
         }
         _visibleChild = null;
         _currentVisibleIndex = 0;
         _foundVisibleChild = false;
+        InvocationUtils.invokeAndWait(new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
         _getVisibleChild(ac, index);
+                return null;
+            }
+        }, ac);
 
         if (_visibleChild != null) {
             debugString( "    getVisibleChild: found child = " +
                          InvocationUtils.invokeAndWait(new Callable<String>() {
                              @Override

@@ -4602,55 +4638,81 @@
      */
     private void _getVisibleChild(final AccessibleContext ac, final int index) {
         if (_visibleChild != null) {
             return;
         }
-
-        int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
-            @Override
-            public Integer call() throws Exception {
-                return ac.getAccessibleChildrenCount();
+        if(ac instanceof AccessibleExtendedTable) {
+            _getVisibleChild((AccessibleExtendedTable)ac, index);
+            return;
             }
-        }, ac);
+        int numChildren = ac.getAccessibleChildrenCount();
         for (int i = 0; i < numChildren; i++) {
-            final int idx=i;
-            final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
-                @Override
-                public AccessibleContext call() throws Exception {
-                    Accessible a = ac.getAccessibleChild(idx);
-                    if (a == null)
-                        return null;
-                    else
-                        return a.getAccessibleContext();
+            Accessible a = ac.getAccessibleChild(i);
+            final AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null;
+            if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) {
+                continue;
                 }
-            }, ac);
-            if (ac2 == null ||
-            (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
-                @Override
-                public Boolean call() throws Exception {
-                    return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
+            if (!_foundVisibleChild && _currentVisibleIndex == index) {
+                _visibleChild = ac2;
+                _foundVisibleChild = true;
+                return;
                 }
-            }, ac))) {
+            _currentVisibleIndex++;
+
+            if ( ac2.getAccessibleChildrenCount() > 0 ) {
+                _getVisibleChild(ac2, index);
+            }
+        }
+    }
+
+    private void _getVisibleChild(final AccessibleExtendedTable acTable, final int index) {
+        if (_visibleChild != null) {
+            return;
+        }
+        int lastVisibleRow = -1;
+        int lastVisibleColumn = -1;
+        boolean foundVisible = false;
+        int rowCount = acTable.getAccessibleRowCount();
+        int columnCount = acTable.getAccessibleColumnCount();
+        for (int rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+            for (int columnIdx = 0; columnIdx < columnCount; columnIdx++) {
+                if (lastVisibleRow != -1 && rowIdx > lastVisibleRow) {
+                    continue;
+                }
+                if (lastVisibleColumn != -1 && columnIdx > lastVisibleColumn) {
                 continue;
             }
+                int finalRowIdx = rowIdx;
+                int finalColumnIdx = columnIdx;
+                Accessible a = acTable.getAccessibleAt(finalRowIdx, finalColumnIdx);
+                final AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null;
+                if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) {
+                    if (foundVisible) {
+                        if (columnIdx != 0 && lastVisibleColumn == -1) {
+                            //the same row, so we found the last visible column
+                            lastVisibleColumn = columnIdx - 1;
+                        } else if (columnIdx == 0 && lastVisibleRow == -1) {
+                            lastVisibleRow = rowIdx - 1;
+                        }
+                    }
+                    continue;
+                }
+                foundVisible = true;
+
             if (!_foundVisibleChild && _currentVisibleIndex == index) {
             _visibleChild = ac2;
             _foundVisibleChild = true;
             return;
             }
             _currentVisibleIndex++;
 
-            if ( InvocationUtils.invokeAndWait(new Callable<Integer>() {
-                @Override
-                public Integer call() throws Exception {
-                    return ac2.getAccessibleChildrenCount();
-                }
-            }, ac) > 0 ) {
+                if (ac2.getAccessibleChildrenCount() > 0) {
                 _getVisibleChild(ac2, index);
             }
         }
     }
+    }
 
 
     /* ===== Java object memory management code ===== */
 
     /**