--- old/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java 2017-02-27 15:54:15.879441600 +0300 +++ new/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java 2017-02-27 15:54:15.107397400 +0300 @@ -4504,10 +4504,10 @@ * * 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"); @@ -4515,7 +4515,13 @@ return -1; } _visibleChildrenCount = 0; - _getVisibleChildrenCount(ac); + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + _getVisibleChildrenCount(ac); + return null; + } + }, ac); debugString(" _visibleChildrenCount = "+_visibleChildrenCount); return _visibleChildrenCount; } @@ -4527,47 +4533,71 @@ private void _getVisibleChildrenCount(final AccessibleContext ac) { if (ac == null) return; - int numChildren = InvocationUtils.invokeAndWait(new Callable() { - @Override - public Integer call() throws Exception { - return ac.getAccessibleChildrenCount(); - } - }, ac); + if(ac instanceof AccessibleExtendedTable) { + _getVisibleChildrenCount((AccessibleExtendedTable)ac); + return; + } + int numChildren = ac.getAccessibleChildrenCount(); for (int i = 0; i < numChildren; i++) { - final int idx = i; - final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable() { - @Override - public AccessibleContext call() throws Exception { - Accessible a = ac.getAccessibleChild(idx); - if (a != null) - return a.getAccessibleContext(); - else - return null; - } - }, ac); - if ( ac2 == null || - (!InvocationUtils.invokeAndWait(new Callable() { - @Override - public Boolean call() throws Exception { - return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); - } - }, ac)) - ) { + ; + Accessible a = ac.getAccessibleChild(i); + AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null; + if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) { continue; } _visibleChildrenCount++; - if (InvocationUtils.invokeAndWait(new Callable() { - @Override - public Integer call() throws Exception { - return ac2.getAccessibleChildrenCount(); - } - }, ac) > 0 ) { + if (ac2.getAccessibleChildrenCount() > 0 ) { _getVisibleChildrenCount(ac2); } } } + /* + * 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 (ac2.getAccessibleChildrenCount() > 0) { + _getVisibleChildrenCount(ac2); + } + } + } + } + /** * Gets the visible child of an AccessibleContext at the * specified index @@ -4582,7 +4612,13 @@ _visibleChild = null; _currentVisibleIndex = 0; _foundVisibleChild = false; - _getVisibleChild(ac, index); + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + _getVisibleChild(ac, index); + return null; + } + }, ac); if (_visibleChild != null) { debugString( " getVisibleChild: found child = " + @@ -4604,51 +4640,77 @@ if (_visibleChild != null) { return; } - - int numChildren = InvocationUtils.invokeAndWait(new Callable() { - @Override - public Integer call() throws Exception { - return ac.getAccessibleChildrenCount(); - } - }, ac); + if(ac instanceof AccessibleExtendedTable) { + _getVisibleChild((AccessibleExtendedTable)ac, index); + return; + } + int numChildren = ac.getAccessibleChildrenCount(); for (int i = 0; i < numChildren; i++) { - final int idx=i; - final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable() { - @Override - public AccessibleContext call() throws Exception { - Accessible a = ac.getAccessibleChild(idx); - if (a == null) - return null; - else - return a.getAccessibleContext(); - } - }, ac); - if (ac2 == null || - (!InvocationUtils.invokeAndWait(new Callable() { - @Override - public Boolean call() throws Exception { - return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); - } - }, ac))) { + Accessible a = ac.getAccessibleChild(i); + final AccessibleContext ac2 = a != null ? a.getAccessibleContext() : null; + if (ac2 == null || ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING)) { continue; } if (!_foundVisibleChild && _currentVisibleIndex == index) { - _visibleChild = ac2; - _foundVisibleChild = true; - return; + _visibleChild = ac2; + _foundVisibleChild = true; + return; } _currentVisibleIndex++; - if ( InvocationUtils.invokeAndWait(new Callable() { - @Override - public Integer call() throws Exception { - return ac2.getAccessibleChildrenCount(); - } - }, ac) > 0 ) { + 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 (ac2.getAccessibleChildrenCount() > 0) { + _getVisibleChild(ac2, index); + } + } + } + } /* ===== Java object memory management code ===== */