8329667: [macos] Issue with JTree related fix for JDK-8317771
Reviewed-by: asemenov, abhiscxk, psadhukhan
This commit is contained in:
parent
7bf1989f59
commit
05f13e75ee
src/java.desktop/macosx
classes/sun/lwawt/macosx
native/libawt_lwawt/awt/a11y
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,10 +36,11 @@ import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.annotation.Native;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.Arrays;
|
||||
@ -64,7 +65,6 @@ import javax.swing.JTextArea;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.lwawt.LWWindowPeer;
|
||||
@ -759,21 +759,6 @@ class CAccessibility implements PropertyChangeListener {
|
||||
return new Object[]{childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1)};
|
||||
}
|
||||
|
||||
private static Accessible createAccessibleTreeNode(JTree t, TreePath p) {
|
||||
Accessible a = null;
|
||||
|
||||
try {
|
||||
Class<?> accessibleJTreeNodeClass = Class.forName("javax.swing.JTree$AccessibleJTree$AccessibleJTreeNode");
|
||||
Constructor<?> constructor = accessibleJTreeNodeClass.getConstructor(t.getAccessibleContext().getClass(), JTree.class, TreePath.class, Accessible.class);
|
||||
constructor.setAccessible(true);
|
||||
a = ((Accessible) constructor.newInstance(t.getAccessibleContext(), t, p, null));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// This method is called from the native
|
||||
// Each child takes up three entries in the array: one for itself, one for its role, and one for the recursion level
|
||||
private static Object[] getChildrenAndRolesRecursive(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored, final int level) {
|
||||
@ -781,62 +766,21 @@ class CAccessibility implements PropertyChangeListener {
|
||||
return invokeAndWait(new Callable<Object[]>() {
|
||||
public Object[] call() throws Exception {
|
||||
ArrayList<Object> allChildren = new ArrayList<Object>();
|
||||
|
||||
Accessible at = null;
|
||||
if (a instanceof CAccessible) {
|
||||
at = CAccessible.getSwingAccessible(a);
|
||||
} else {
|
||||
at = a;
|
||||
}
|
||||
|
||||
if (at instanceof JTree) {
|
||||
JTree tree = ((JTree) at);
|
||||
|
||||
if (whichChildren == JAVA_AX_ALL_CHILDREN) {
|
||||
int count = tree.getRowCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
TreePath path = tree.getPathForRow(i);
|
||||
Accessible an = createAccessibleTreeNode(tree, path);
|
||||
if (an != null) {
|
||||
AccessibleContext ac = an.getAccessibleContext();
|
||||
if (ac != null) {
|
||||
allChildren.add(an);
|
||||
allChildren.add(ac.getAccessibleRole());;
|
||||
allChildren.add(String.valueOf((tree.isRootVisible() ? path.getPathCount() : path.getPathCount() - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
int count = tree.getSelectionCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
TreePath path = tree.getSelectionPaths()[i];
|
||||
Accessible an = createAccessibleTreeNode(tree, path);
|
||||
if (an != null) {
|
||||
AccessibleContext ac = an.getAccessibleContext();
|
||||
if (ac != null) {
|
||||
allChildren.add(an);
|
||||
allChildren.add(ac.getAccessibleRole());
|
||||
allChildren.add(String.valueOf((tree.isRootVisible() ? path.getPathCount() : path.getPathCount() - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allChildren.toArray();
|
||||
}
|
||||
|
||||
ArrayList<Object> currentLevelChildren = new ArrayList<Object>();
|
||||
ArrayList<Accessible> parentStack = new ArrayList<Accessible>();
|
||||
HashMap<Accessible, List<Object>> childrenOfParent = new HashMap<>();
|
||||
parentStack.add(a);
|
||||
ArrayList<Integer> indexses = new ArrayList<Integer>();
|
||||
Integer index = 0;
|
||||
int currentLevel = level;
|
||||
while (!parentStack.isEmpty()) {
|
||||
Accessible p = parentStack.get(parentStack.size() - 1);
|
||||
|
||||
currentLevelChildren.addAll(Arrays.asList(getChildrenAndRolesImpl(p, c, JAVA_AX_ALL_CHILDREN, allowIgnored, ChildrenOperations.COMMON)));
|
||||
if (!childrenOfParent.containsKey(p)) {
|
||||
childrenOfParent.put(p, Arrays.asList(getChildrenAndRolesImpl(p,
|
||||
c, JAVA_AX_ALL_CHILDREN, allowIgnored,
|
||||
ChildrenOperations.COMMON)));
|
||||
}
|
||||
currentLevelChildren.addAll(childrenOfParent.get(p));
|
||||
if ((currentLevelChildren.size() == 0) || (index >= currentLevelChildren.size())) {
|
||||
if (!parentStack.isEmpty()) parentStack.remove(parentStack.size() - 1);
|
||||
if (!indexses.isEmpty()) index = indexses.remove(indexses.size() - 1);
|
||||
@ -879,7 +823,6 @@ class CAccessibility implements PropertyChangeListener {
|
||||
currentLevel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return allChildren.toArray();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,12 @@
|
||||
// This is a tree representation. See: https://developer.apple.com/documentation/appkit/nsoutlineview
|
||||
|
||||
@interface OutlineAccessibility : ListAccessibility <NSAccessibilityOutline>
|
||||
|
||||
{
|
||||
NSMutableArray<id<NSAccessibilityRow>> *rowCache;
|
||||
BOOL rowCacheValid;
|
||||
NSMutableArray<id<NSAccessibilityRow>> *selectedRowCache;
|
||||
BOOL selectedRowCacheValid;
|
||||
}
|
||||
@property(readonly) BOOL isTreeRootVisible;
|
||||
|
||||
@end
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -55,4 +55,88 @@ static jmethodID sjm_isTreeRootVisible = NULL;
|
||||
return [[super accessibilityLabel] isEqualToString:@"list"] ? @"tree" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
return [self accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
return [self accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityChildren
|
||||
{
|
||||
if (![self isCacheValid]) {
|
||||
NSArray *t = [super accessibilityChildren];
|
||||
if (t != nil) {
|
||||
rowCache = [[NSMutableArray arrayWithArray:t] retain];
|
||||
} else {
|
||||
rowCache = nil;
|
||||
}
|
||||
rowCacheValid = YES;
|
||||
}
|
||||
return rowCache;
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedChildren
|
||||
{
|
||||
if (!selectedRowCacheValid) {
|
||||
NSArray *t = [super accessibilitySelectedChildren];
|
||||
if (t != nil) {
|
||||
selectedRowCache = [[NSMutableArray arrayWithArray:t] retain];
|
||||
} else {
|
||||
selectedRowCache = nil;
|
||||
}
|
||||
selectedRowCacheValid = YES;
|
||||
}
|
||||
return selectedRowCache;
|
||||
}
|
||||
|
||||
- (BOOL)isCacheValid
|
||||
{
|
||||
if (rowCacheValid && [[self parent] respondsToSelector:NSSelectorFromString(@"isCacheValid")]) {
|
||||
return [[self parent] isCacheValid];
|
||||
}
|
||||
return rowCacheValid;
|
||||
}
|
||||
|
||||
- (void)invalidateCache
|
||||
{
|
||||
rowCacheValid = NO;
|
||||
}
|
||||
|
||||
- (void)invalidateSelectionCache
|
||||
{
|
||||
selectedRowCacheValid = NO;
|
||||
}
|
||||
|
||||
- (void)postSelectionChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
[self invalidateSelectionCache];
|
||||
[super postSelectionChanged];
|
||||
}
|
||||
|
||||
- (void)postTreeNodeCollapsed
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
[self invalidateCache];
|
||||
[super postTreeNodeCollapsed];
|
||||
}
|
||||
|
||||
- (void)postTreeNodeExpanded
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
[self invalidateCache];
|
||||
[super postTreeNodeExpanded];
|
||||
}
|
||||
|
||||
- (void)postSelectedCellsChanged
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
[self invalidateSelectionCache];
|
||||
[super postSelectedCellsChanged];
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user