Mercurial > hg > icedtea8-forest > jdk
changeset 13057:cec5310dcc2b jdk8u121-b35
8171808: Performance problems in dialogs with large tables when JAB activated
Reviewed-by: serb, alexsch
author | mcherkas |
---|---|
date | Thu, 02 Mar 2017 14:59:28 +0300 |
parents | 1f5c744d3d57 |
children | e526e1d9f14c |
files | src/windows/classes/com/sun/java/accessibility/AccessBridge.java |
diffstat | 1 files changed, 181 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/windows/classes/com/sun/java/accessibility/AccessBridge.java Fri Feb 17 17:29:44 2017 +0300 +++ b/src/windows/classes/com/sun/java/accessibility/AccessBridge.java Thu Mar 02 14:59:28 2017 +0300 @@ -4625,6 +4625,10 @@ private void _getVisibleChildrenCount(final AccessibleContext ac) { if (ac == null) return; + if(ac instanceof AccessibleExtendedTable) { + _getVisibleChildrenCount((AccessibleExtendedTable)ac); + return; + } int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() { @Override public Integer call() throws Exception { @@ -4666,6 +4670,83 @@ } } + /* + * 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 = InvocationUtils.invokeAndWait(new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return acTable.getAccessibleRowCount(); + } + }, acTable); + int columnCount = InvocationUtils.invokeAndWait(new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return acTable.getAccessibleColumnCount(); + } + }, acTable); + 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; + final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = acTable.getAccessibleAt(finalRowIdx, finalColumnIdx); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + }, acTable); + if (ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, acTable)) + ) { + 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(); + } + }, acTable) > 0) { + _getVisibleChildrenCount(ac2); + } + } + } + } + /** * Gets the visible child of an AccessibleContext at the * specified index @@ -4702,7 +4783,10 @@ if (_visibleChild != null) { return; } - + if(ac instanceof AccessibleExtendedTable) { + _getVisibleChild((AccessibleExtendedTable)ac, index); + return; + } int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() { @Override public Integer call() throws Exception { @@ -4711,7 +4795,7 @@ }, ac); for (int i = 0; i < numChildren; i++) { final int idx=i; - final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() { + final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() { @Override public AccessibleContext call() throws Exception { Accessible a = ac.getAccessibleChild(idx); @@ -4748,6 +4832,82 @@ } } + private void _getVisibleChild(final AccessibleExtendedTable acTable, final int index) { + if (_visibleChild != null) { + return; + } + int lastVisibleRow = -1; + int lastVisibleColumn = -1; + boolean foundVisible = false; + int rowCount = InvocationUtils.invokeAndWait(new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return acTable.getAccessibleRowCount(); + } + }, acTable); + int columnCount = InvocationUtils.invokeAndWait(new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return acTable.getAccessibleColumnCount(); + } + }, acTable); + 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; + final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = acTable.getAccessibleAt(finalRowIdx, finalColumnIdx); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + }, acTable); + if (ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, acTable))) { + 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(); + } + }, acTable) > 0) { + _getVisibleChild(ac2, index); + } + } + } + } /* ===== Java object memory management code ===== */ @@ -7128,6 +7288,25 @@ * and waits for it to finish blocking the caller thread. * * @param callable the {@code Callable} to invoke + * @param accessibleTable the {@code AccessibleExtendedTable} which would be used to find the right context + * for the task execution + * @param <T> type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static <T> T invokeAndWait(final Callable<T> callable, + final AccessibleExtendedTable accessibleTable) { + if (accessibleTable instanceof AccessibleContext) { + return invokeAndWait(callable, (AccessibleContext)accessibleTable); + } + throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleTable); + } + + /** + * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke * @param accessible the {@code Accessible} which would be used to find the right context * for the task execution * @param <T> type parameter for the result value