8133713: [macosx] Accessible JTables always reported as empty

Reviewed-by: prr
This commit is contained in:
Sergey Bylokhov 2018-10-16 16:49:50 -07:00
parent 518f32791a
commit b3b647ef9a
3 changed files with 104 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,17 +25,39 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import sun.lwawt.LWWindowPeer; import java.awt.Component;
import java.awt.Container;
import java.awt.*; import java.awt.Dimension;
import java.beans.*; import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.accessibility.*; import javax.accessibility.Accessible;
import javax.swing.*; import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleTable;
import javax.accessibility.AccessibleText;
import javax.accessibility.AccessibleValue;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import sun.lwawt.LWWindowPeer;
class CAccessibility implements PropertyChangeListener { class CAccessibility implements PropertyChangeListener {
private static Set<String> ignoredRoles; private static Set<String> ignoredRoles;
@ -626,7 +648,7 @@ class CAccessibility implements PropertyChangeListener {
currentAC = currentAccessible.getAccessibleContext(); currentAC = currentAccessible.getAccessibleContext();
currentName = currentAC.getAccessibleName(); currentName = currentAC.getAccessibleName();
currentRole = (AccessibleRole)childrenAndRoles.get(i+1); currentRole = (AccessibleRole)childrenAndRoles.get(i+1);
if ( currentName.equals(activeDescendantName) && if (currentName != null && currentName.equals(activeDescendantName) &&
currentRole.equals(activeDescendantRole) ) { currentRole.equals(activeDescendantRole) ) {
newArray.add(0, currentAccessible); newArray.add(0, currentAccessible);
newArray.add(1, currentRole); newArray.add(1, currentRole);
@ -649,6 +671,26 @@ class CAccessibility implements PropertyChangeListener {
}, c); }, c);
} }
private static final int JAVA_AX_ROWS = 1;
private static final int JAVA_AX_COLS = 2;
public static int getTableInfo(final Accessible a, final Component c,
final int info) {
if (a == null) return 0;
return invokeAndWait(() -> {
AccessibleContext ac = a.getAccessibleContext();
AccessibleTable table = ac.getAccessibleTable();
if (table != null) {
if (info == JAVA_AX_COLS) {
return table.getAccessibleColumnCount();
} else if (info == JAVA_AX_ROWS) {
return table.getAccessibleRowCount();
}
}
return 0;
}, c);
}
private static AccessibleRole getAccessibleRoleForLabel(JLabel l, AccessibleRole fallback) { private static AccessibleRole getAccessibleRoleForLabel(JLabel l, AccessibleRole fallback) {
String text = l.getText(); String text = l.getText();
if (text != null && text.length() > 0) { if (text != null && text.length() > 0) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -368,7 +368,7 @@ void initializeRoles()
[sRoles setObject:NSAccessibilitySplitGroupRole forKey:@"splitpane"]; [sRoles setObject:NSAccessibilitySplitGroupRole forKey:@"splitpane"];
[sRoles setObject:NSAccessibilityValueIndicatorRole forKey:@"statusbar"]; [sRoles setObject:NSAccessibilityValueIndicatorRole forKey:@"statusbar"];
[sRoles setObject:NSAccessibilityGroupRole forKey:@"swingcomponent"]; [sRoles setObject:NSAccessibilityGroupRole forKey:@"swingcomponent"];
[sRoles setObject:NSAccessibilityTableRole forKey:@"table"]; [sRoles setObject:NSAccessibilityGridRole forKey:@"table"];
[sRoles setObject:NSAccessibilityTextFieldRole forKey:@"text"]; [sRoles setObject:NSAccessibilityTextFieldRole forKey:@"text"];
[sRoles setObject:NSAccessibilityTextAreaRole forKey:@"textarea"]; // supports top/bottom of document notifications: CAccessability.getAccessibleRole() [sRoles setObject:NSAccessibilityTextAreaRole forKey:@"textarea"]; // supports top/bottom of document notifications: CAccessability.getAccessibleRole()
[sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"togglebutton"]; [sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"togglebutton"];

View File

@ -54,6 +54,7 @@
// If the value is >=0, it's an index // If the value is >=0, it's an index
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;"); static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
static JNF_STATIC_MEMBER_CACHE(jm_getTableInfo, sjc_CAccessibility, "getTableInfo", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleComponent, sjc_CAccessibility, "getAccessibleComponent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleComponent;"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleComponent, sjc_CAccessibility, "getAccessibleComponent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleComponent;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleValue, sjc_CAccessibility, "getAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleValue;"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleValue, sjc_CAccessibility, "getAccessibleValue", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleValue;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
@ -117,6 +118,14 @@ static NSObject *sAttributeNamesLOCK = nil;
- (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable; - (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable;
@end @end
@interface TableAccessibility : JavaComponentAccessibility {
}
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
- (NSArray *)accessibilityRowsAttribute;
- (NSArray *)accessibilityColumnsAttribute;
@end
@implementation JavaComponentAccessibility @implementation JavaComponentAccessibility
@ -370,6 +379,8 @@ static NSObject *sAttributeNamesLOCK = nil;
JavaComponentAccessibility *newChild = nil; JavaComponentAccessibility *newChild = nil;
if ([javaRole isEqualToString:@"pagetablist"]) { if ([javaRole isEqualToString:@"pagetablist"]) {
newChild = [TabGroupAccessibility alloc]; newChild = [TabGroupAccessibility alloc];
} else if ([javaRole isEqualToString:@"table"]) {
newChild = [TableAccessibility alloc];
} else if ([javaRole isEqualToString:@"scrollpane"]) { } else if ([javaRole isEqualToString:@"scrollpane"]) {
newChild = [ScrollAreaAccessibility alloc]; newChild = [ScrollAreaAccessibility alloc];
} else { } else {
@ -484,7 +495,8 @@ static NSObject *sAttributeNamesLOCK = nil;
// children // children
if (attributeStatesArray[6]) { if (attributeStatesArray[6]) {
[attributeNames addObject:NSAccessibilityChildrenAttribute]; [attributeNames addObject:NSAccessibilityChildrenAttribute];
if ([javaRole isEqualToString:@"list"]) { if ([javaRole isEqualToString:@"list"]
|| [javaRole isEqualToString:@"table"]) {
[attributeNames addObject:NSAccessibilitySelectedChildrenAttribute]; [attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
[attributeNames addObject:NSAccessibilityVisibleChildrenAttribute]; [attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
} }
@ -652,7 +664,9 @@ static NSObject *sAttributeNamesLOCK = nil;
id myParent = [self accessibilityParentAttribute]; id myParent = [self accessibilityParentAttribute];
if ([myParent isKindOfClass:[JavaComponentAccessibility class]]) { if ([myParent isKindOfClass:[JavaComponentAccessibility class]]) {
NSString *parentRole = [(JavaComponentAccessibility *)myParent javaRole]; NSString *parentRole = [(JavaComponentAccessibility *)myParent javaRole];
if ([parentRole isEqualToString:@"list"]) {
if ([parentRole isEqualToString:@"list"]
|| [parentRole isEqualToString:@"table"]) {
NSMutableArray *moreNames = NSMutableArray *moreNames =
[[NSMutableArray alloc] initWithCapacity: [names count] + 2]; [[NSMutableArray alloc] initWithCapacity: [names count] + 2];
[moreNames addObjectsFromArray: names]; [moreNames addObjectsFromArray: names];
@ -1847,6 +1861,41 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
@end @end
// these constants are duplicated in CAccessibility.java
#define JAVA_AX_ROWS (1)
#define JAVA_AX_COLS (2)
@implementation TableAccessibility
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
NSMutableArray *names = (NSMutableArray *)[super initializeAttributeNamesWithEnv:env];
[names addObject:NSAccessibilityRowCountAttribute];
[names addObject:NSAccessibilityColumnCountAttribute];
return names;
}
- (id)getTableInfo:(jint)info {
if (fAccessible == NULL) return 0;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jint count = JNFCallStaticIntMethod(env, jm_getTableInfo, fAccessible,
fComponent, info);
NSNumber *index = [NSNumber numberWithInt:count];
return index;
}
- (id)accessibilityRowCountAttribute {
return [self getTableInfo:JAVA_AX_ROWS];
}
- (id)accessibilityColumnCountAttribute {
return [self getTableInfo:JAVA_AX_COLS];
}
@end
/* /*
* Returns Object.equals for the two items * Returns Object.equals for the two items
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock * This may use LWCToolkit.invokeAndWait(); don't call while holding fLock