8267385: Create NSAccessibilityElement implementation for JavaComponentAccessibility
8262031: Create implementation for NSAccessibilityNavigableStaticText protocol 8264287: Create implementation for NSAccessibilityComboBox protocol peer 8264303: Create implementation for NSAccessibilityTabGroup protocol peer 8264292: Create implementation for NSAccessibilityList protocol peer 8267387: Create implementation for NSAccessibilityOutline protocol 8267388: Create implementation for NSAccessibilityTable protocol 8264286: Create implementation for NSAccessibilityColumn protocol peer 8264298: Create implementation for NSAccessibilityRow protocol peer 8264291: Create implementation for NSAccessibilityCell protocol peer Reviewed-by: kizune, pbansal, serb
This commit is contained in:
parent
0ac2be9b35
commit
9c6457f222
src/java.desktop/macosx
classes/sun/lwawt/macosx
native/libawt_lwawt/awt
AWTView.mJavaAccessibilityAction.hJavaAccessibilityAction.mJavaAccessibilityUtilities.hJavaAccessibilityUtilities.mJavaComponentAccessibility.mJavaTextAccessibility.m
a11y
ButtonAccessibility.mCellAccessibility.hCellAccessibility.mCheckboxAccessibility.mColumnAccessibility.hColumnAccessibility.mComboBoxAccessibility.hComboBoxAccessibility.mCommonComponentAccessibility.hCommonComponentAccessibility.mCommonTextAccessibility.mGroupAccessibility.mImageAccessibility.mListAccessibility.hListAccessibility.mListRowAccessibility.hListRowAccessibility.mNavigableTextAccessibility.hNavigableTextAccessibility.mOutlineAccessibility.hOutlineAccessibility.mOutlineRowAccessibility.hOutlineRowAccessibility.mRadiobuttonAccessibility.mScrollAreaAccessibility.mSliderAccessibility.mSpinboxAccessibility.mStaticTextAccessibility.mTabButtonAccessibility.hTabButtonAccessibility.mTabGroupAccessibility.hTabGroupAccessibility.mTableAccessibility.hTableAccessibility.mTableRowAccessibility.hTableRowAccessibility.m
test/jdk/java/awt/a11y
@ -34,11 +34,13 @@ import java.awt.Window;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.annotation.Native;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleAction;
|
||||
@ -57,6 +59,8 @@ import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
@ -120,12 +124,7 @@ class CAccessibility implements PropertyChangeListener {
|
||||
private native void focusChanged();
|
||||
|
||||
static <T> T invokeAndWait(final Callable<T> callable, final Component c) {
|
||||
if (c != null) {
|
||||
try {
|
||||
return LWCToolkit.invokeAndWait(callable, c);
|
||||
} catch (final Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
return null;
|
||||
return invokeAndWait(callable, c, null);
|
||||
}
|
||||
|
||||
static <T> T invokeAndWait(final Callable<T> callable, final Component c, final T defValue) {
|
||||
@ -555,6 +554,10 @@ class CAccessibility implements PropertyChangeListener {
|
||||
if (pac == null) return;
|
||||
AccessibleSelection as = pac.getAccessibleSelection();
|
||||
if (as == null) return;
|
||||
if (parent instanceof JList) {
|
||||
((JList) parent).setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
as.addAccessibleSelection(i);
|
||||
}
|
||||
}, c);
|
||||
@ -655,77 +658,148 @@ class CAccessibility implements PropertyChangeListener {
|
||||
|
||||
// Duplicated from JavaComponentAccessibility
|
||||
// Note that values >=0 are indexes into the child array
|
||||
static final int JAVA_AX_ALL_CHILDREN = -1;
|
||||
static final int JAVA_AX_SELECTED_CHILDREN = -2;
|
||||
static final int JAVA_AX_VISIBLE_CHILDREN = -3;
|
||||
@Native static final int JAVA_AX_ALL_CHILDREN = -1;
|
||||
@Native static final int JAVA_AX_SELECTED_CHILDREN = -2;
|
||||
@Native static final int JAVA_AX_VISIBLE_CHILDREN = -3;
|
||||
|
||||
// Each child takes up two entries in the array: one for itself and one for its role
|
||||
public static Object[] getChildrenAndRoles(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(new Callable<Object[]>() {
|
||||
public Object[] call() throws Exception {
|
||||
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
|
||||
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
|
||||
|
||||
/* In the case of fetching a selection, need to check to see if
|
||||
* the active descendant is at the beginning of the list. If it
|
||||
* is not it needs to be moved to the beginning of the list so
|
||||
* VoiceOver will annouce it correctly. The list returned
|
||||
* from Java is always in order from top to bottom, but when shift
|
||||
* selecting downward (extending the list) or multi-selecting using
|
||||
* the VO keys control+option+command+return the active descendant
|
||||
* is not at the top of the list in the shift select down case and
|
||||
* may not be in the multi select case.
|
||||
*/
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
if (!childrenAndRoles.isEmpty()) {
|
||||
AccessibleContext activeDescendantAC =
|
||||
CAccessible.getActiveDescendant(a);
|
||||
if (activeDescendantAC != null) {
|
||||
String activeDescendantName =
|
||||
activeDescendantAC.getAccessibleName();
|
||||
AccessibleRole activeDescendantRole =
|
||||
activeDescendantAC.getAccessibleRole();
|
||||
// Move active descendant to front of list.
|
||||
// List contains pairs of each selected item's
|
||||
// Accessible and AccessibleRole.
|
||||
ArrayList<Object> newArray = new ArrayList<Object>();
|
||||
int count = childrenAndRoles.size();
|
||||
Accessible currentAccessible = null;
|
||||
AccessibleContext currentAC = null;
|
||||
String currentName = null;
|
||||
AccessibleRole currentRole = null;
|
||||
for (int i = 0; i < count; i+=2) {
|
||||
// Is this the active descendant?
|
||||
currentAccessible = (Accessible)childrenAndRoles.get(i);
|
||||
currentAC = currentAccessible.getAccessibleContext();
|
||||
currentName = currentAC.getAccessibleName();
|
||||
currentRole = (AccessibleRole)childrenAndRoles.get(i+1);
|
||||
if (currentName != null && currentName.equals(activeDescendantName) &&
|
||||
currentRole.equals(activeDescendantRole) ) {
|
||||
newArray.add(0, currentAccessible);
|
||||
newArray.add(1, currentRole);
|
||||
} else {
|
||||
newArray.add(currentAccessible);
|
||||
newArray.add(currentRole);
|
||||
}
|
||||
}
|
||||
childrenAndRoles = newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
|
||||
return childrenAndRoles.toArray();
|
||||
}
|
||||
|
||||
return new Object[] { childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1) };
|
||||
return getChildrenAndRolesImpl(a, c, whichChildren, allowIgnored);
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static final int JAVA_AX_ROWS = 1;
|
||||
private static final int JAVA_AX_COLS = 2;
|
||||
private static Object[] getChildrenAndRolesImpl(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored) {
|
||||
if (a == null) return null;
|
||||
|
||||
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
|
||||
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
|
||||
|
||||
/* In case of fetching a selection, we need to check if
|
||||
* the active descendant is at the beginning of the list, or
|
||||
* otherwise move it, so that VoiceOver announces it correctly.
|
||||
* The java list is always in order from top to bottom, but when
|
||||
* (1) shift-selecting downward (extending the list) or (2) multi-selecting with
|
||||
* the VO keys (CTRL+ALT+CMD+RETURN) the active descendant
|
||||
* is not at the top of the list in the 1st case and may not be in the 2nd.
|
||||
*/
|
||||
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
|
||||
if (!childrenAndRoles.isEmpty()) {
|
||||
AccessibleContext activeDescendantAC =
|
||||
CAccessible.getActiveDescendant(a);
|
||||
if (activeDescendantAC != null) {
|
||||
String activeDescendantName =
|
||||
activeDescendantAC.getAccessibleName();
|
||||
AccessibleRole activeDescendantRole =
|
||||
activeDescendantAC.getAccessibleRole();
|
||||
// Move active descendant to front of list.
|
||||
// List contains pairs of each selected item's
|
||||
// Accessible and AccessibleRole.
|
||||
ArrayList<Object> newArray = new ArrayList<Object>();
|
||||
int count = childrenAndRoles.size();
|
||||
Accessible currentAccessible = null;
|
||||
AccessibleContext currentAC = null;
|
||||
String currentName = null;
|
||||
AccessibleRole currentRole = null;
|
||||
for (int i = 0; i < count; i += 2) {
|
||||
// Is this the active descendant?
|
||||
currentAccessible = (Accessible) childrenAndRoles.get(i);
|
||||
currentAC = currentAccessible.getAccessibleContext();
|
||||
currentName = currentAC.getAccessibleName();
|
||||
currentRole = (AccessibleRole) childrenAndRoles.get(i + 1);
|
||||
if (currentName != null && currentName.equals(activeDescendantName) &&
|
||||
currentRole.equals(activeDescendantRole)) {
|
||||
newArray.add(0, currentAccessible);
|
||||
newArray.add(1, currentRole);
|
||||
} else {
|
||||
newArray.add(currentAccessible);
|
||||
newArray.add(currentRole);
|
||||
}
|
||||
}
|
||||
childrenAndRoles = newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
|
||||
return childrenAndRoles.toArray();
|
||||
}
|
||||
|
||||
return new Object[]{childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1)};
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(new Callable<Object[]>() {
|
||||
public Object[] call() throws Exception {
|
||||
ArrayList<Object> currentLevelChildren = new ArrayList<Object>();
|
||||
ArrayList<Object> allChildren = new ArrayList<Object>();
|
||||
ArrayList<Accessible> parentStack = new ArrayList<Accessible>();
|
||||
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)));
|
||||
if ((currentLevelChildren.size() == 0) || (index >= currentLevelChildren.size())) {
|
||||
if (!parentStack.isEmpty()) parentStack.remove(parentStack.size() - 1);
|
||||
if (!indexses.isEmpty()) index = indexses.remove(indexses.size() - 1);
|
||||
currentLevel -= 1;
|
||||
currentLevelChildren.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
Accessible ca = null;
|
||||
Object obj = currentLevelChildren.get(index);
|
||||
if (!(obj instanceof Accessible)) {
|
||||
index += 2;
|
||||
currentLevelChildren.clear();
|
||||
continue;
|
||||
}
|
||||
ca = (Accessible) obj;
|
||||
Object role = currentLevelChildren.get(index + 1);
|
||||
currentLevelChildren.clear();
|
||||
|
||||
AccessibleContext cac = ca.getAccessibleContext();
|
||||
if (cac == null) {
|
||||
index += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cac.getAccessibleStateSet().contains(AccessibleState.SELECTED) && (whichChildren == JAVA_AX_SELECTED_CHILDREN)) ||
|
||||
(cac.getAccessibleStateSet().contains(AccessibleState.VISIBLE) && (whichChildren == JAVA_AX_VISIBLE_CHILDREN)) ||
|
||||
(whichChildren == JAVA_AX_ALL_CHILDREN)) {
|
||||
allChildren.add(ca);
|
||||
allChildren.add(role);
|
||||
allChildren.add(String.valueOf(currentLevel));
|
||||
}
|
||||
|
||||
index += 2;
|
||||
|
||||
if (cac.getAccessibleStateSet().contains(AccessibleState.EXPANDED)) {
|
||||
parentStack.add(ca);
|
||||
indexses.add(index);
|
||||
index = 0;
|
||||
currentLevel += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return allChildren.toArray();
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
|
||||
@Native private static final int JAVA_AX_ROWS = 1;
|
||||
@Native private static final int JAVA_AX_COLS = 2;
|
||||
|
||||
public static int getTableInfo(final Accessible a, final Component c,
|
||||
final int info) {
|
||||
@ -744,6 +818,23 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static int[] getTableSelectedInfo(final Accessible a, final Component c,
|
||||
final int info) {
|
||||
if (a == null) return null;
|
||||
return invokeAndWait(() -> {
|
||||
AccessibleContext ac = a.getAccessibleContext();
|
||||
AccessibleTable table = ac.getAccessibleTable();
|
||||
if (table != null) {
|
||||
if (info == JAVA_AX_COLS) {
|
||||
return table.getSelectedAccessibleColumns();
|
||||
} else if (info == JAVA_AX_ROWS) {
|
||||
return table.getSelectedAccessibleRows();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, c);
|
||||
}
|
||||
|
||||
private static AccessibleRole getAccessibleRoleForLabel(JLabel l, AccessibleRole fallback) {
|
||||
String text = l.getText();
|
||||
if (text != null && text.length() > 0) {
|
||||
@ -862,4 +953,18 @@ class CAccessibility implements PropertyChangeListener {
|
||||
}
|
||||
}, (Component)ax);
|
||||
}
|
||||
|
||||
private static boolean isTreeRootVisible(Accessible a, Component c) {
|
||||
if (a == null) return false;
|
||||
|
||||
return invokeAndWait(new Callable<Boolean>() {
|
||||
public Boolean call() throws Exception {
|
||||
Accessible sa = CAccessible.getSwingAccessible(a);
|
||||
if (sa instanceof JTree) {
|
||||
return ((JTree) sa).isRootVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, c);
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +31,7 @@ import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY;
|
||||
import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
|
||||
@ -75,6 +71,8 @@ class CAccessible extends CFRetainedResource implements Accessible {
|
||||
private static native void menuOpened(long ptr);
|
||||
private static native void menuClosed(long ptr);
|
||||
private static native void menuItemSelected(long ptr);
|
||||
private static native void treeNodeExpanded(long ptr);
|
||||
private static native void treeNodeCollapsed(long ptr);
|
||||
|
||||
private Accessible accessible;
|
||||
|
||||
@ -137,6 +135,13 @@ class CAccessible extends CFRetainedResource implements Accessible {
|
||||
if (parentAccessible != null) {
|
||||
parentRole = parentAccessible.getAccessibleContext().getAccessibleRole();
|
||||
}
|
||||
|
||||
if (newValue == AccessibleState.EXPANDED) {
|
||||
treeNodeExpanded(ptr);
|
||||
} else if (newValue == AccessibleState.COLLAPSED) {
|
||||
treeNodeCollapsed(ptr);
|
||||
}
|
||||
|
||||
// At least for now don't handle combo box menu state changes.
|
||||
// This may change when later fixing issues which currently
|
||||
// exist for combo boxes, but for now the following is only
|
||||
|
@ -27,8 +27,7 @@
|
||||
#import "CGLGraphicsConfig.h"
|
||||
#import "AWTView.h"
|
||||
#import "AWTWindow.h"
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "JavaTextAccessibility.h"
|
||||
#import "a11y/CommonComponentAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "GeomUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
@ -611,42 +610,29 @@ static BOOL shouldUsePressAndHold() {
|
||||
- (id)getAxData:(JNIEnv*)env
|
||||
{
|
||||
jobject jcomponent = [self awtComponent:env];
|
||||
id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
|
||||
id ax = [[[CommonComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ax;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityAttributeNames
|
||||
{
|
||||
return [[super accessibilityAttributeNames] arrayByAddingObject:NSAccessibilityChildrenAttribute];
|
||||
}
|
||||
|
||||
// NSAccessibility messages
|
||||
// attribute methods
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
- (id)accessibilityChildren
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
|
||||
|
||||
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
|
||||
- (BOOL)isAccessibilityElement
|
||||
{
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id)accessibilityHitTest:(NSPoint)point
|
||||
@ -656,7 +642,7 @@ static BOOL shouldUsePressAndHold() {
|
||||
|
||||
(*env)->PushLocalFrame(env, 4);
|
||||
|
||||
id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env];
|
||||
id result = [[self getAxData:env] accessibilityHitTest:point];
|
||||
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
@ -681,17 +667,24 @@ static BOOL shouldUsePressAndHold() {
|
||||
// --- Services menu support for lightweights ---
|
||||
|
||||
// finds the focused accessible element, and if it is a text element, obtains the text from it
|
||||
- (NSString *)accessibleSelectedText
|
||||
- (NSString *)accessibilitySelectedText
|
||||
{
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil;
|
||||
return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute];
|
||||
if (![focused respondsToSelector:@selector(accessibilitySelectedText)]) return nil;
|
||||
return [focused accessibilitySelectedText];
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if ([focused respondsToSelector:@selector(setAccessibilitySelectedText:)]) {
|
||||
[focused setAccessibilitySelectedText:accessibilitySelectedText];
|
||||
}
|
||||
}
|
||||
|
||||
// same as above, but converts to RTFD
|
||||
- (NSData *)accessibleSelectedTextAsRTFD
|
||||
{
|
||||
NSString *selectedText = [self accessibleSelectedText];
|
||||
NSString *selectedText = [self accessibilitySelectedText];
|
||||
NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText];
|
||||
NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length])
|
||||
documentAttributes:
|
||||
@ -704,8 +697,8 @@ static BOOL shouldUsePressAndHold() {
|
||||
- (BOOL)replaceAccessibleTextSelection:(NSString *)text
|
||||
{
|
||||
id focused = [self accessibilityFocusedUIElement];
|
||||
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO;
|
||||
[(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text];
|
||||
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText)]) return NO;
|
||||
[focused setAccessibilitySelectedText:text];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -715,7 +708,7 @@ static BOOL shouldUsePressAndHold() {
|
||||
if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
|
||||
|
||||
if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
|
||||
NSString *selectedText = [self accessibleSelectedText];
|
||||
NSString *selectedText = [self accessibilitySelectedText];
|
||||
if (selectedText) return self;
|
||||
}
|
||||
|
||||
@ -728,7 +721,7 @@ static BOOL shouldUsePressAndHold() {
|
||||
if ([types containsObject:NSStringPboardType])
|
||||
{
|
||||
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
|
||||
return [pboard setString:[self accessibilitySelectedText] forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
if ([types containsObject:NSRTFDPboardType])
|
||||
|
@ -26,6 +26,10 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <jni.h>
|
||||
|
||||
extern NSMutableDictionary *sActions;
|
||||
extern NSMutableDictionary *sActionSelectors;
|
||||
extern NSMutableArray *sAllActionSelectors;
|
||||
void initializeActions();
|
||||
|
||||
@protocol JavaAccessibilityAction
|
||||
|
||||
|
@ -29,6 +29,10 @@
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
NSMutableDictionary *sActions = nil;
|
||||
NSMutableDictionary *sActionSelectors = nil;
|
||||
NSMutableArray *sAllActionSelectors = nil;
|
||||
void initializeActions();
|
||||
|
||||
@implementation JavaAxAction
|
||||
|
||||
@ -148,3 +152,31 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void initializeActions() {
|
||||
int actionsCount = 5;
|
||||
|
||||
sActions = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sActions setObject:NSAccessibilityPressAction forKey:@"click"];
|
||||
[sActions setObject:NSAccessibilityIncrementAction forKey:@"increment"];
|
||||
[sActions setObject:NSAccessibilityDecrementAction forKey:@"decrement"];
|
||||
[sActions setObject:NSAccessibilityShowMenuAction forKey:@"togglePopup"];
|
||||
[sActions setObject:NSAccessibilityPressAction forKey:@"toggleExpand"];
|
||||
|
||||
sActionSelectors = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformPress)) forKey:NSAccessibilityPressAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu)) forKey:NSAccessibilityShowMenuAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformDecrement)) forKey:NSAccessibilityDecrementAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformIncrement)) forKey:NSAccessibilityIncrementAction];
|
||||
[sActionSelectors setObject:NSStringFromSelector(@selector(accessibilityPerformPick)) forKey:NSAccessibilityPickAction];
|
||||
|
||||
sAllActionSelectors = [[NSMutableArray alloc] initWithCapacity:actionsCount];
|
||||
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformPick))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformIncrement))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformDecrement))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformShowMenu))];
|
||||
[sAllActionSelectors addObject:NSStringFromSelector(@selector(accessibilityPerformPress))];
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ BOOL isVertical(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isShowing(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component);
|
||||
BOOL isExpanded(JNIEnv *env, jobject axContext, jobject component);
|
||||
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component);
|
||||
jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component);
|
||||
|
||||
@ -60,3 +61,6 @@ void JavaAccessibilitySetAttributeValue(id element, NSString *attribute, id valu
|
||||
void JavaAccessibilityRaiseSetAttributeToIllegalTypeException(const char *functionName, id element, NSString *attribute, id value);
|
||||
void JavaAccessibilityRaiseUnimplementedAttributeException(const char *functionName, id element, NSString *attribute);
|
||||
void JavaAccessibilityRaiseIllegalParameterTypeException(const char *functionName, id element, NSString *attribute, id parameter);
|
||||
BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber);
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute);
|
||||
static void JavaAccessibilityLogError(NSString *message);
|
||||
@ -199,6 +200,20 @@ BOOL isSelectable(JNIEnv *env, jobject axContext, jobject component)
|
||||
return selectable;
|
||||
}
|
||||
|
||||
BOOL isExpanded(JNIEnv *env, jobject axContext, jobject component)
|
||||
{
|
||||
GET_ACCESSIBLESTATE_CLASS_RETURN(NO);
|
||||
DECLARE_STATIC_FIELD_RETURN(jm_EXPANDED,
|
||||
sjc_AccessibleState,
|
||||
"EXPANDED",
|
||||
"Ljavax/accessibility/AccessibleState;", NO );
|
||||
jobject axExpandedState = (*env)->GetStaticObjectField(env, sjc_AccessibleState, jm_EXPANDED);
|
||||
CHECK_EXCEPTION_NULL_RETURN(axExpandedState, NO);
|
||||
BOOL expanded = containsAxState(env, axContext, axExpandedState, component);
|
||||
(*env)->DeleteLocalRef(env, axExpandedState);
|
||||
return expanded;
|
||||
}
|
||||
|
||||
NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
|
||||
{
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(NSZeroPoint);
|
||||
@ -348,6 +363,75 @@ static void JavaAccessibilityLogError(NSString *message)
|
||||
NSLog(@"!!! %@", message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns Object.equals for the two items
|
||||
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
|
||||
* and try to pass a component so the event happens on the correct thread.
|
||||
*/
|
||||
BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
|
||||
{
|
||||
DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", NO);
|
||||
DECLARE_METHOD_RETURN(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z", NO);
|
||||
|
||||
if ((a == NULL) && (b == NULL)) return YES;
|
||||
if ((a == NULL) || (b == NULL)) return NO;
|
||||
|
||||
if (pthread_main_np() != 0) {
|
||||
// If we are on the AppKit thread
|
||||
DECLARE_CLASS_RETURN(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit", NO);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_doEquals, sjc_LWCToolkit, "doEquals",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z", NO);
|
||||
return (*env)->CallStaticBooleanMethod(env, sjc_LWCToolkit, jm_doEquals, a, b, component);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
jboolean jb = (*env)->CallBooleanMethod(env, a, jm_equals, b);
|
||||
CHECK_EXCEPTION();
|
||||
return jb;
|
||||
}
|
||||
|
||||
/*
|
||||
* The java/lang/Number concrete class could be for any of the Java primitive
|
||||
* numerical types or some other subclass.
|
||||
* All existing A11Y code uses Integer so that is what we look for first
|
||||
* But all must be able to return a double and NSNumber accepts a double,
|
||||
* so that's the fall back.
|
||||
*/
|
||||
NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) {
|
||||
if (jnumber == NULL) {
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(jnumber_Class, "java/lang/Number", nil);
|
||||
DECLARE_CLASS_RETURN(jinteger_Class, "java/lang/Integer", nil);
|
||||
DECLARE_METHOD_RETURN(jm_intValue, jnumber_Class, "intValue", "()I", nil);
|
||||
DECLARE_METHOD_RETURN(jm_doubleValue, jnumber_Class, "doubleValue", "()D", nil);
|
||||
if ((*env)->IsInstanceOf(env, jnumber, jinteger_Class)) {
|
||||
jint i = (*env)->CallIntMethod(env, jnumber, jm_intValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithInteger:i];
|
||||
} else {
|
||||
jdouble d = (*env)->CallDoubleMethod(env, jnumber, jm_doubleValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithDouble:d];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts an int array to an NSRange wrapped inside an NSValue
|
||||
* takes [start, end] values and returns [start, end - start]
|
||||
*/
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
|
||||
jint *values = (*env)->GetIntArrayElements(env, array, 0);
|
||||
if (values == NULL) {
|
||||
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
|
||||
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
|
||||
return nil;
|
||||
};
|
||||
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
|
||||
(*env)->ReleaseIntArrayElements(env, array, values, 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
// end appKit copies
|
||||
|
||||
/*
|
||||
@ -417,13 +501,13 @@ void initializeRoles()
|
||||
[sRoles setObject:NSAccessibilitySplitGroupRole forKey:@"splitpane"];
|
||||
[sRoles setObject:NSAccessibilityValueIndicatorRole forKey:@"statusbar"];
|
||||
[sRoles setObject:NSAccessibilityGroupRole forKey:@"swingcomponent"];
|
||||
[sRoles setObject:NSAccessibilityGridRole forKey:@"table"];
|
||||
[sRoles setObject:NSAccessibilityTableRole forKey:@"table"];
|
||||
[sRoles setObject:NSAccessibilityTextFieldRole forKey:@"text"];
|
||||
[sRoles setObject:NSAccessibilityTextAreaRole forKey:@"textarea"]; // supports top/bottom of document notifications: CAccessability.getAccessibleRole()
|
||||
[sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"togglebutton"];
|
||||
[sRoles setObject:NSAccessibilityToolbarRole forKey:@"toolbar"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"tooltip"];
|
||||
[sRoles setObject:NSAccessibilityBrowserRole forKey:@"tree"];
|
||||
[sRoles setObject:NSAccessibilityOutlineRole forKey:@"tree"];
|
||||
[sRoles setObject:NSAccessibilityUnknownRole forKey:@"unknown"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"viewport"];
|
||||
[sRoles setObject:JavaAccessibilityIgnore forKey:@"window"];
|
||||
|
@ -29,7 +29,6 @@
|
||||
// <https://www.ibm.com/able/guidelines/java/snsjavagjfc.html>
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#import "a11y/CommonComponentAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
@ -45,6 +44,12 @@
|
||||
#import "JNIUtilities.h"
|
||||
#import "AWTView.h"
|
||||
|
||||
// these constants are duplicated in CAccessibility.java
|
||||
#define JAVA_AX_ALL_CHILDREN (-1)
|
||||
#define JAVA_AX_SELECTED_CHILDREN (-2)
|
||||
#define JAVA_AX_VISIBLE_CHILDREN (-3)
|
||||
// If the value is >=0, it's an index
|
||||
|
||||
// GET* macros defined in JavaAccessibilityUtilities.h, so they can be shared.
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
@ -82,7 +87,7 @@ static jclass sjc_CAccessible = NULL;
|
||||
static NSMutableDictionary *sAttributeNamesForRoleCache = nil;
|
||||
static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
@interface TabGroupAccessibility : JavaComponentAccessibility {
|
||||
@interface TabGroupLegacyAccessibility : JavaComponentAccessibility {
|
||||
NSInteger _numTabs;
|
||||
}
|
||||
|
||||
@ -112,7 +117,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
- (id)accessibilityValueAttribute;
|
||||
@end
|
||||
|
||||
@interface TableAccessibility : JavaComponentAccessibility {
|
||||
@interface TableLegacyAccessibility : JavaComponentAccessibility {
|
||||
|
||||
}
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
|
||||
@ -362,21 +367,18 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
|
||||
// otherwise, create a new instance
|
||||
JavaComponentAccessibility *newChild = nil;
|
||||
newChild = [CommonComponentAccessibility getComponentAccessibility:javaRole];
|
||||
if (newChild == nil) {
|
||||
if ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"table"]) {
|
||||
newChild = [TableAccessibility alloc];
|
||||
if ([javaRole isEqualToString:@"pagetablist"]) {
|
||||
newChild = [TabGroupLegacyAccessibility alloc];
|
||||
} else if ([javaRole isEqualToString:@"table"]) {
|
||||
newChild = [TableLegacyAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextAreaRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility alloc];
|
||||
} else {
|
||||
NSString *nsRole = [sRoles objectForKey:javaRole];
|
||||
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextAreaRole] ||
|
||||
[nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
|
||||
newChild = [JavaTextAccessibility alloc];
|
||||
} else {
|
||||
newChild = [JavaComponentAccessibility alloc];
|
||||
}
|
||||
newChild = [JavaComponentAccessibility alloc];
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +389,7 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
// This is the only way to know if the menu is opening; visible state change
|
||||
// can't be caught because the listeners are not set up in time.
|
||||
if ( [javaRole isEqualToString:@"popupmenu"] &&
|
||||
![[parent javaRole] isEqualToString:@"combobox"] ) {
|
||||
![[parent javaRole] isEqualToString:@"combobox"] ) {
|
||||
[newChild postMenuOpened];
|
||||
}
|
||||
|
||||
@ -904,32 +906,6 @@ static NSObject *sAttributeNamesLOCK = nil;
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* The java/lang/Number concrete class could be for any of the Java primitive
|
||||
* numerical types or some other subclass.
|
||||
* All existing A11Y code uses Integer so that is what we look for first
|
||||
* But all must be able to return a double and NSNumber accepts a double,
|
||||
* so that's the fall back.
|
||||
*/
|
||||
static NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) {
|
||||
if (jnumber == NULL) {
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(jnumber_Class, "java/lang/Number", nil);
|
||||
DECLARE_CLASS_RETURN(jinteger_Class, "java/lang/Integer", nil);
|
||||
DECLARE_METHOD_RETURN(jm_intValue, jnumber_Class, "intValue", "()I", nil);
|
||||
DECLARE_METHOD_RETURN(jm_doubleValue, jnumber_Class, "doubleValue", "()D", nil);
|
||||
if ((*env)->IsInstanceOf(env, jnumber, jinteger_Class)) {
|
||||
jint i = (*env)->CallIntMethod(env, jnumber, jm_intValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithInteger:i];
|
||||
} else {
|
||||
jdouble d = (*env)->CallDoubleMethod(env, jnumber, jm_doubleValue);
|
||||
CHECK_EXCEPTION();
|
||||
return [NSNumber numberWithDouble:d];
|
||||
}
|
||||
}
|
||||
|
||||
// Element's maximum value (id)
|
||||
- (id)accessibilityMaxValueAttribute
|
||||
{
|
||||
@ -1600,7 +1576,7 @@ JNI_COCOA_ENTER(env);
|
||||
JNI_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
@implementation TabGroupAccessibility
|
||||
@implementation TabGroupLegacyAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
@ -1802,9 +1778,6 @@ JNI_COCOA_EXIT(env);
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
|
||||
@implementation TabGroupControlAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
@ -1873,7 +1846,7 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
#define JAVA_AX_ROWS (1)
|
||||
#define JAVA_AX_COLS (2)
|
||||
|
||||
@implementation TableAccessibility
|
||||
@implementation TableLegacyAccessibility
|
||||
|
||||
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
|
||||
{
|
||||
@ -1907,30 +1880,3 @@ static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
|
||||
return [self getTableInfo:JAVA_AX_COLS];
|
||||
}
|
||||
@end
|
||||
|
||||
/*
|
||||
* Returns Object.equals for the two items
|
||||
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
|
||||
* and try to pass a component so the event happens on the correct thread.
|
||||
*/
|
||||
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
|
||||
{
|
||||
DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", NO);
|
||||
DECLARE_METHOD_RETURN(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z", NO);
|
||||
|
||||
if ((a == NULL) && (b == NULL)) return YES;
|
||||
if ((a == NULL) || (b == NULL)) return NO;
|
||||
|
||||
if (pthread_main_np() != 0) {
|
||||
// If we are on the AppKit thread
|
||||
DECLARE_CLASS_RETURN(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit", NO);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_doEquals, sjc_LWCToolkit, "doEquals",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z", NO);
|
||||
return (*env)->CallStaticBooleanMethod(env, sjc_LWCToolkit, jm_doEquals, a, b, component);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
jboolean jb = (*env)->CallBooleanMethod(env, a, jm_equals, b);
|
||||
CHECK_EXCEPTION();
|
||||
return jb;
|
||||
}
|
||||
|
@ -53,23 +53,6 @@ static jmethodID sjm_getAccessibleEditableText = NULL;
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;", ret);
|
||||
|
||||
|
||||
/*
|
||||
* Converts an int array to an NSRange wrapped inside an NSValue
|
||||
* takes [start, end] values and returns [start, end - start]
|
||||
*/
|
||||
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
|
||||
jint *values = (*env)->GetIntArrayElements(env, array, 0);
|
||||
if (values == NULL) {
|
||||
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
|
||||
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
|
||||
return nil;
|
||||
};
|
||||
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
|
||||
(*env)->ReleaseIntArrayElements(env, array, values, 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
@implementation JavaTextAccessibility
|
||||
|
||||
// based strongly upon NSTextViewAccessibility:accessibilityAttributeNames
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress
|
||||
@ -44,4 +44,14 @@
|
||||
return [self performAccessibleAction:0];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface CellAccessibility : CommonComponentAccessibility
|
||||
@end
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
|
||||
@implementation CellAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityCellRole;;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
NSString *javaRole = [self javaRole];
|
||||
CommonComponentAccessibility *newChild = [CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:javaRole
|
||||
index:self->fIndex
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:self->fView
|
||||
isWrapped:NO];
|
||||
return [NSArray arrayWithObject:newChild];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRowIndexRange {
|
||||
NSInteger location = -1;
|
||||
if ([[(CommonComponentAccessibility *)fParent accessibilityParent] isKindOfClass:[TableAccessibility class]]) {
|
||||
TableAccessibility *table = [(CommonComponentAccessibility *)fParent accessibilityParent];
|
||||
location = [table accessibleRowAtIndex:fIndex];
|
||||
}
|
||||
|
||||
return NSMakeRange(location, 1);
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityColumnIndexRange {
|
||||
NSInteger location = -1;
|
||||
if ([[(CommonComponentAccessibility *)fParent accessibilityParent] isKindOfClass:[TableAccessibility class]]) {
|
||||
TableAccessibility *table = [(CommonComponentAccessibility *)fParent accessibilityParent];
|
||||
location = [table accessibleColumnAtIndex:fIndex];
|
||||
}
|
||||
|
||||
return NSMakeRange(location, 1);
|
||||
}
|
||||
|
||||
@end
|
@ -39,7 +39,7 @@
|
||||
- (id _Nonnull) accessibilityValue
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ColumnAccessibility : CommonComponentAccessibility
|
||||
|
||||
@property(readonly) NSUInteger columnNumberInTable;
|
||||
|
||||
@end
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ColumnAccessibility.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation ColumnAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityColumnRole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
CommonComponentAccessibility *parent = [self accessibilityParent];
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
parent->fAccessible, parent->fComponent, sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN, NO);
|
||||
CHECK_EXCEPTION();
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = fIndex;
|
||||
|
||||
int inc = [(TableAccessibility *)[self accessibilityParent] accessibilityRowCount] * 2;
|
||||
NSInteger i = childIndex * 2;
|
||||
for(i; i < arrayLen; i += inc)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jchildJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
childJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
CellAccessibility *child = [[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:self->fView
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[[child retain] autorelease]];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex += (inc / 2);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return fIndex;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ComboBoxAccessibility : CommonComponentAccessibility
|
||||
@end
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "ComboBoxAccessibility.h"
|
||||
#import "../JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_getAccessibleName = NULL;
|
||||
#define GET_ACCESSIBLENAME_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", ret);
|
||||
|
||||
@implementation ComboBoxAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (id)accessibilityValue {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return nil;
|
||||
jclass axContextClass = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleSelection, axContextClass, "getAccessibleSelection", "(I)Ljavax/accessibility/Accessible;", nil);
|
||||
jobject axSelectedChild = (*env)->CallObjectMethod(env, axContext, jm_getAccessibleSelection, 0);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
if (axSelectedChild == NULL) {
|
||||
return nil;
|
||||
}
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
GET_ACCESSIBLENAME_METHOD_RETURN(nil);
|
||||
jobject childName = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleName, axSelectedChild, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (childName == NULL) {
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
return nil;
|
||||
}
|
||||
NSString *selectedText = JavaStringToNSString(env, childName);
|
||||
(*env)->DeleteLocalRef(env, axSelectedChild);
|
||||
(*env)->DeleteLocalRef(env, childName);
|
||||
return selectedText;
|
||||
}
|
||||
|
||||
@end
|
@ -26,23 +26,83 @@
|
||||
#ifndef JAVA_COMPONENT_ACCESSIBILITY
|
||||
#define JAVA_COMPONENT_ACCESSIBILITY
|
||||
|
||||
#import "JavaComponentAccessibility.h"
|
||||
#include "jni.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
|
||||
// these constants are duplicated in CAccessibility.java
|
||||
#define JAVA_AX_ALL_CHILDREN (-1)
|
||||
#define JAVA_AX_SELECTED_CHILDREN (-2)
|
||||
#define JAVA_AX_VISIBLE_CHILDREN (-3)
|
||||
// If the value is >=0, it's an index
|
||||
@interface CommonComponentAccessibility : NSAccessibilityElement {
|
||||
NSView *fView;
|
||||
NSObject *fParent;
|
||||
|
||||
@interface CommonComponentAccessibility : JavaComponentAccessibility <NSAccessibilityElement> {
|
||||
NSString *fNSRole;
|
||||
NSString *fJavaRole;
|
||||
|
||||
jint fIndex;
|
||||
jobject fAccessible;
|
||||
jobject fComponent;
|
||||
|
||||
NSMutableDictionary *fActions;
|
||||
NSMutableArray *fActionSelectors;
|
||||
NSObject *fActionsLOCK;
|
||||
}
|
||||
|
||||
@property(nonnull, readonly) NSArray *actionSelectors;
|
||||
|
||||
- (id _Nonnull)initWithParent:(NSObject* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withAccessible:(jobject _Nullable)accessible withIndex:(jint)index withView:(NSView* _Nonnull)view withJavaRole:(NSString* _Nullable)javaRole;
|
||||
- (void)unregisterFromCocoaAXSystem;
|
||||
- (void)postValueChanged;
|
||||
- (void)postSelectedTextChanged;
|
||||
- (void)postSelectionChanged;
|
||||
- (void)postTitleChanged;
|
||||
- (void)postTreeNodeExpanded;
|
||||
- (void)postTreeNodeCollapsed;
|
||||
- (BOOL)isEqual:(nonnull id)anObject;
|
||||
- (BOOL)isAccessibleWithEnv:(JNIEnv _Nonnull * _Nonnull)env forAccessible:(nonnull jobject)accessible;
|
||||
|
||||
+ (void)postFocusChanged:(nullable id)message;
|
||||
|
||||
+ (void) initializeRolesMap;
|
||||
+ (JavaComponentAccessibility * _Nullable) getComponentAccessibility:(NSString * _Nonnull)role;
|
||||
|
||||
+ (CommonComponentAccessibility* _Nullable) getComponentAccessibility:(NSString* _Nonnull)role;
|
||||
+ (CommonComponentAccessibility * _Nullable) getComponentAccessibility:(NSString * _Nonnull)role andParent:(CommonComponentAccessibility * _Nonnull)parent;
|
||||
|
||||
+ (NSArray* _Nullable)childrenOfParent:(CommonComponentAccessibility* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored;
|
||||
+ (NSArray* _Nullable)childrenOfParent:(CommonComponentAccessibility* _Nonnull)parent withEnv:(JNIEnv _Nonnull * _Nonnull)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored recursive:(BOOL)recursive;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithParent:(CommonComponentAccessibility* _Nullable)parent accessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)javaRole index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)role index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view;
|
||||
|
||||
// If the isWraped parameter is true, then the object passed as a parent was created based on the same java component,
|
||||
// but performs a different NSAccessibilityRole of a table cell, or a list row, or tree row,
|
||||
// and we need to create an element whose role corresponds to the role in Java.
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithParent:(CommonComponentAccessibility* _Nullable)parent accessible:(jobject _Nonnull)jaccessible role:(NSString* _Nonnull)javaRole index:(jint)index withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view isWrapped:(BOOL)wrapped;
|
||||
|
||||
// The current parameter is used to bypass the check for an item's index on the parent so that the item is created. This is necessary,
|
||||
// for example, for AccessibleJTreeNode, whose currentComponent has index -1
|
||||
+ (CommonComponentAccessibility* _Nullable) createWithAccessible:(jobject _Nonnull)jaccessible withEnv:(JNIEnv _Nonnull * _Nonnull)env withView:(NSView* _Nonnull)view isCurrent:(BOOL)current;
|
||||
|
||||
- (jobject _Nullable)axContextWithEnv:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (NSView* _Nonnull)view;
|
||||
- (NSWindow* _Nonnull)window;
|
||||
- (id _Nonnull)parent;
|
||||
- (NSString* _Nonnull)javaRole;
|
||||
|
||||
- (BOOL)isMenu;
|
||||
- (BOOL)isSelected:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)isSelectable:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)isVisible:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
|
||||
- (NSArray* _Nullable)accessibleChildrenWithChildCode:(NSInteger)childCode;
|
||||
|
||||
- (NSDictionary* _Nullable)getActions:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (void)getActionsWithEnv:(JNIEnv _Nonnull * _Nonnull)env;
|
||||
- (BOOL)accessiblePerformAction:(NSAccessibilityActionName _Nonnull)actionName;
|
||||
|
||||
- (BOOL)performAccessibleAction:(int)index;
|
||||
|
||||
- (NSRect)accessibilityFrame;
|
||||
- (id _Nullable)accessibilityParent;
|
||||
- (BOOL)performAccessibleAction:(int)index;
|
||||
- (BOOL)isAccessibilityElement;
|
||||
@end
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -70,7 +70,7 @@ static NSRange javaIntArrayToNSRange(JNIEnv* env, jintArray array) {
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
if ([[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
if ([[self accessibilityRole] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
jobject axName = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleName, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
|
@ -26,6 +26,7 @@
|
||||
#import "GroupAccessibility.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
/*
|
||||
* This is the protocol for the components that contain children.
|
||||
* Basic logic of accessibilityChildren might be overridden in the specific implementing
|
||||
@ -43,9 +44,9 @@
|
||||
- (NSArray *)accessibilityChildren {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self
|
||||
withEnv:env
|
||||
withChildrenCode:JAVA_AX_ALL_CHILDREN
|
||||
withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN
|
||||
allowIgnored:NO];
|
||||
|
||||
if ([children count] == 0) {
|
||||
@ -55,4 +56,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -36,7 +36,17 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ListAccessibility : CommonComponentAccessibility <NSAccessibilityList>
|
||||
@end
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "ListAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation ListAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilityRows
|
||||
{
|
||||
return [self accessibilityChildren];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
return [self accessibilitySelectedChildren];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [super accessibilityLabel] == NULL ? @"list" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
// to avoid warning (why?): method in protocol 'NSAccessibilityElement' not implemented
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
// to avoid warning (why?): method in protocol 'NSAccessibilityElement' not implemented
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface ListRowAccessibility : CommonComponentAccessibility <NSAccessibilityRow>
|
||||
@end
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "ListRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ListAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
|
||||
@implementation ListRowAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == NULL) {
|
||||
|
||||
// Since the row element has already been created, we should no create it again, but just retrieve it by a pointer, that's why isWrapped is set to YES.
|
||||
CommonComponentAccessibility *newChild = [CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:self->fJavaRole
|
||||
index:self->fIndex
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withView:self->fView
|
||||
isWrapped:YES];
|
||||
return [NSArray arrayWithObject:newChild];
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return [[self accessibilityParent] accessibilityIndexOfChild:self];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface NavigableTextAccessibility : CommonComponentAccessibility <NSAccessibilityNavigableStaticText>
|
||||
|
||||
@property(readonly) BOOL accessibleIsPasswordText;
|
||||
|
||||
@end
|
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "NavigableTextAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
#define GET_CACCESSIBLITY_CLASS() \
|
||||
GET_CLASS(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility");
|
||||
#define GET_CACCESSIBLITY_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility", ret);
|
||||
|
||||
static jmethodID sjm_getAccessibleText = NULL;
|
||||
#define GET_ACCESSIBLETEXT_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBLITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;", ret);
|
||||
|
||||
static jclass sjc_CAccessibleText = NULL;
|
||||
#define GET_CACCESSIBLETEXT_CLASS() \
|
||||
GET_CLASS(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
|
||||
#define GET_CACCESSIBLETEXT_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText", ret);
|
||||
|
||||
static jmethodID sjm_getAccessibleEditableText = NULL;
|
||||
#define GET_ACCESSIBLEEDITABLETEXT_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;", ret);
|
||||
|
||||
|
||||
@implementation NavigableTextAccessibility
|
||||
|
||||
- (BOOL)accessibleIsPasswordText {
|
||||
return [fJavaRole isEqualToString:@"passwordtext"];
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSRect)accessibilityFrameForRange:(NSRange)range
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSMakeRect(0, 0, 0, 0));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D", NSMakeRect(0, 0, 0, 0));
|
||||
jdoubleArray axBounds = (jdoubleArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getBoundsForRange,
|
||||
fAccessible, fComponent, range.location, range.length);
|
||||
CHECK_EXCEPTION();
|
||||
if (axBounds == NULL) return NSMakeRect(0, 0, 0, 0);
|
||||
|
||||
// We cheat because we know that the array is 4 elements long (x, y, width, height)
|
||||
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
|
||||
CHECK_EXCEPTION();
|
||||
|
||||
NSRect bounds;
|
||||
bounds.origin.x = values[0];
|
||||
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
|
||||
bounds.size.width = values[2];
|
||||
bounds.size.height = values[3];
|
||||
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityLineForIndex:(NSInteger)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(-1);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I", -1);
|
||||
jint row = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText, jm_getLineNumberForIndex,
|
||||
fAccessible, fComponent, index);
|
||||
CHECK_EXCEPTION();
|
||||
if (row < 0) return -1;
|
||||
return row;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForLine:(NSInteger)line
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (jintArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
jm_getRangeForLine, fAccessible, fComponent, line);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
NSRange range = [javaIntArrayToNSRangeValue(env,axTextRange) rangeValue];
|
||||
(*env)->DeleteLocalRef(env, axTextRange);
|
||||
return range;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityStringForRange:(NSRange)range
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;", nil);
|
||||
jstring jstringForRange = (jstring)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getStringForRange,
|
||||
fAccessible, fComponent, range.location, range.length);
|
||||
CHECK_EXCEPTION();
|
||||
if (jstringForRange == NULL) return @"";
|
||||
NSString* str = JavaStringToNSString(env, jstringForRange);
|
||||
(*env)->DeleteLocalRef(env, jstringForRange);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
|
||||
GET_ACCESSIBLETEXT_METHOD_RETURN(@"");
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axText == NULL) return nil;
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
|
||||
GET_ACCESSIBLEEDITABLETEXT_METHOD_RETURN(nil);
|
||||
jobject axEditableText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
sjm_getAccessibleEditableText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axEditableText == NULL) return nil;
|
||||
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTextRange, sjc_CAccessibleText, "getTextRange",
|
||||
"(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;", nil);
|
||||
jobject jrange = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getTextRange,
|
||||
axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
NSString *string = JavaStringToNSString(env, jrange);
|
||||
|
||||
(*env)->DeleteLocalRef(env, jrange);
|
||||
(*env)->DeleteLocalRef(env, axEditableText);
|
||||
|
||||
if (string == nil) string = @"";
|
||||
return string;
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
if ([self accessibleIsPasswordText]) {
|
||||
return NSAccessibilitySecureTextFieldSubrole;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForIndex:(NSInteger)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (jintArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getRangeForIndex,
|
||||
fAccessible, fComponent, index);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
return [javaIntArrayToNSRangeValue(env, axTextRange) rangeValue];
|
||||
}
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole {
|
||||
return [sRoles objectForKey:self.javaRole];
|
||||
}
|
||||
|
||||
- (NSRange)accessibilityRangeForPosition:(NSPoint)point
|
||||
{
|
||||
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I", NSRangeFromString(@""));
|
||||
jint charIndex = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText, jm_getCharacterIndexAtPosition,
|
||||
fAccessible, fComponent, point.x, point.y);
|
||||
CHECK_EXCEPTION();
|
||||
if (charIndex == -1) return NSRangeFromString(@"");
|
||||
|
||||
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
|
||||
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
|
||||
return range;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilitySelectedText
|
||||
{
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", nil);
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText, jm_getSelectedText,
|
||||
fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axText == NULL) return @"";
|
||||
NSString* str = JavaStringToNSString(env, axText);
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSRange)accessibilitySelectedTextRange
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(NSRangeFromString(@""));
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I", NSRangeFromString(@""));
|
||||
jintArray axTextRange = (*env)->CallStaticObjectMethod(env, sjc_CAccessibleText,
|
||||
jm_getSelectedTextRange, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
if (axTextRange == NULL) return NSRangeFromString(@"");
|
||||
|
||||
return [javaIntArrayToNSRangeValue(env, axTextRange) rangeValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityNumberOfCharacters
|
||||
{
|
||||
// cmcnote: should coalesce these two calls - radr://3951923
|
||||
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_ACCESSIBLETEXT_METHOD_RETURN(0);
|
||||
jobject axText = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility,
|
||||
sjm_getAccessibleText, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
NSInteger num = getAxTextCharCount(env, axText, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axText);
|
||||
return num;
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityInsertionPointLineNumber
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS_RETURN(0);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText,
|
||||
"getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I", 0);
|
||||
jint row = (*env)->CallStaticIntMethod(env, sjc_CAccessibleText,
|
||||
jm_getLineNumberForInsertionPoint, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
return row >= 0 ? row : 0;
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jstring jstringValue = NSStringToJavaString(env, accessibilitySelectedText);
|
||||
GET_CACCESSIBLETEXT_CLASS();
|
||||
DECLARE_STATIC_METHOD(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
|
||||
(*env)->CallStaticVoidMethod(env, sjc_CAccessibleText, jm_setSelectedText,
|
||||
fAccessible, fComponent, jstringValue);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange
|
||||
{
|
||||
jint startIndex = accessibilitySelectedTextRange.location;
|
||||
jint endIndex = startIndex + accessibilitySelectedTextRange.length;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBLETEXT_CLASS();
|
||||
DECLARE_STATIC_METHOD(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
|
||||
(*env)->CallStaticVoidMethod(env, sjc_CAccessibleText, jm_setSelectedTextRange,
|
||||
fAccessible, fComponent, startIndex, endIndex);
|
||||
CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEdited {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityEnabled {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
/*
|
||||
* Other text methods
|
||||
- (NSRange)accessibilitySharedCharacterRange;
|
||||
- (NSArray *)accessibilitySharedTextUIElements;
|
||||
- (NSData *)accessibilityRTFForRange:(NSRange)range;
|
||||
- (NSRange)accessibilityStyleRangeForIndex:(NSInteger)index;
|
||||
*/
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "ListAccessibility.h"
|
||||
|
||||
// This is a tree representation. See: https://developer.apple.com/documentation/appkit/nsoutlineview
|
||||
|
||||
@interface OutlineAccessibility : ListAccessibility <NSAccessibilityOutline>
|
||||
|
||||
@property(readonly) BOOL isTreeRootVisible;
|
||||
|
||||
@end
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "OutlineAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_isTreeRootVisible = NULL;
|
||||
#define GET_ISTREEROOTVISIBLE_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_isTreeRootVisible, sjc_CAccessibility, "isTreeRootVisible", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Z", ret);
|
||||
|
||||
@implementation OutlineAccessibility
|
||||
|
||||
- (BOOL)isTreeRootVisible
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
GET_ISTREEROOTVISIBLE_METHOD_RETURN(NO);
|
||||
bool isTreeRootVisible = (*env)->CallStaticBooleanMethod(env, sjc_CAccessibility, sjm_isTreeRootVisible, fAccessible, fComponent);
|
||||
CHECK_EXCEPTION();
|
||||
return isTreeRootVisible;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [[super accessibilityLabel] isEqualToString:@"list"] ? @"tree" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "ListRowAccessibility.h"
|
||||
|
||||
@interface OutlineRowAccessibility : ListRowAccessibility
|
||||
|
||||
@property(readwrite) int accessibleLevel;
|
||||
|
||||
- (jobject)currentAccessibleWithENV:(JNIEnv *)env;
|
||||
|
||||
@end
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "OutlineRowAccessibility.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "OutlineAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessible = NULL;
|
||||
#define GET_CACCESSIBLE_CLASS_RETURN(ret) \
|
||||
GET_CLASS_RETURN(sjc_CAccessible, "sun/lwawt/macosx/CAccessible", ret);
|
||||
|
||||
@implementation OutlineRowAccessibility
|
||||
|
||||
@synthesize accessibleLevel;
|
||||
|
||||
- (jobject)currentAccessibleWithENV:(JNIEnv *)env
|
||||
{
|
||||
jobject jAxContext = getAxContext(env, fAccessible, fComponent);
|
||||
if (jAxContext == NULL) return NULL;
|
||||
jclass axContextClass = (*env)->GetObjectClass(env, jAxContext);
|
||||
DECLARE_METHOD_RETURN(jm_getCurrentComponent, axContextClass, "getCurrentComponent", "()Ljava/awt/Component;", NULL);
|
||||
jobject newComponent = (*env)->CallObjectMethod(env, jAxContext, jm_getCurrentComponent);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, jAxContext);
|
||||
if (newComponent != NULL) {
|
||||
GET_CACCESSIBLE_CLASS_RETURN(NULL);
|
||||
DECLARE_STATIC_METHOD_RETURN(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;", NULL);
|
||||
jobject currentAccessible = (*env)->CallStaticObjectMethod(env, sjc_CAccessible, sjm_getCAccessible, newComponent);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, newComponent);
|
||||
return currentAccessible;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject currentAccessible = [self currentAccessibleWithENV:env];
|
||||
if (currentAccessible != NULL) {
|
||||
CommonComponentAccessibility *currentElement = [CommonComponentAccessibility createWithAccessible:currentAccessible withEnv:env withView:self->fView isCurrent:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:currentElement withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] != 0) {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
return [NSArray arrayWithObject:[CommonComponentAccessibility createWithParent:self
|
||||
accessible:self->fAccessible
|
||||
role:self->fJavaRole
|
||||
index:self->fIndex
|
||||
withEnv:env
|
||||
withView:self->fView
|
||||
isWrapped:YES]];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityDisclosureLevel
|
||||
{
|
||||
int level = [self accessibleLevel];
|
||||
return [(OutlineAccessibility *)[self accessibilityParent] isTreeRootVisible] ? level - 1 : level;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilityDisclosed
|
||||
{
|
||||
return isExpanded([ThreadUtilities getJNIEnv], [self axContextWithEnv:[ThreadUtilities getJNIEnv]], self->fComponent);
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
return NSAccessibilityOutlineRowSubrole;;
|
||||
}
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessibilitySelected
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
@ -39,7 +39,7 @@
|
||||
- (id _Nonnull) accessibilityValue
|
||||
{
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -26,6 +26,7 @@
|
||||
#import "ScrollAreaAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
/*
|
||||
* Implementation of the accessibility peer for the ScrollArea role
|
||||
@ -35,16 +36,16 @@
|
||||
- (NSArray * _Nullable)accessibilityContentsAttribute
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
|
||||
if ([children count] <= 0) return nil;
|
||||
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
|
||||
|
||||
// The scroll bars are in the children. children less the scroll bars is the contents
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
JavaComponentAccessibility *aElement;
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
CommonComponentAccessibility *aElement;
|
||||
while ((aElement = (CommonComponentAccessibility *)[enumerator nextObject])) {
|
||||
if (![[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
// no scroll bars in contents
|
||||
[(NSMutableArray *)contents addObject:aElement];
|
||||
}
|
||||
@ -56,14 +57,14 @@
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
NSArray *children = [CommonComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:YES];
|
||||
if ([children count] <= 0) return nil;
|
||||
|
||||
// The scroll bars are in the children.
|
||||
JavaComponentAccessibility *aElement;
|
||||
CommonComponentAccessibility *aElement;
|
||||
NSEnumerator *enumerator = [children objectEnumerator];
|
||||
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
|
||||
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
while ((aElement = (CommonComponentAccessibility *)[enumerator nextObject])) {
|
||||
if ([[aElement accessibilityRole] isEqualToString:NSAccessibilityScrollBarRole]) {
|
||||
jobject elementAxContext = [aElement axContextWithEnv:env];
|
||||
if (orientation == NSAccessibilityOrientationHorizontal) {
|
||||
if (isHorizontal(env, elementAxContext, fComponent)) {
|
||||
|
@ -39,12 +39,12 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (id _Nullable)accessibilityValue
|
||||
{
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformIncrement
|
||||
@ -57,4 +57,14 @@
|
||||
return [self performAccessibleAction:DECREMENT];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -39,12 +39,12 @@
|
||||
|
||||
- (NSString * _Nullable)accessibilityLabel
|
||||
{
|
||||
return [self accessibilityTitleAttribute];
|
||||
return [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (id _Nullable)accessibilityValue
|
||||
{
|
||||
return [self accessibilityValueAttribute];
|
||||
return [super accessibilityValue];
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformIncrement
|
||||
@ -58,4 +58,14 @@
|
||||
return [self performAccessibleAction:DECREMENT];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -47,4 +47,14 @@
|
||||
return [self accessibilityVisibleCharacterRangeAttribute];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TabButtonAccessibility : CommonComponentAccessibility {
|
||||
jobject fTabGroupAxContext;
|
||||
}
|
||||
|
||||
@property(readonly) jobject tabGroup;
|
||||
|
||||
// from TabGroup controller
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
|
||||
- (void)performPressAction;
|
||||
|
||||
@end
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "TabButtonAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
@implementation TabButtonAccessibility
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
|
||||
if (self) {
|
||||
if (tabGroup != NULL) {
|
||||
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroup);
|
||||
CHECK_EXCEPTION();
|
||||
} else {
|
||||
fTabGroupAxContext = NULL;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||
|
||||
if (fTabGroupAxContext != NULL) {
|
||||
(*env)->DeleteWeakGlobalRef(env, fTabGroupAxContext);
|
||||
fTabGroupAxContext = NULL;
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (jobject)tabGroup
|
||||
{
|
||||
if (fTabGroupAxContext == NULL) {
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
jobject tabGroupAxContext = [(CommonComponentAccessibility *)[self parent] axContextWithEnv:env];
|
||||
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, tabGroupAxContext);
|
||||
}
|
||||
return fTabGroupAxContext;
|
||||
}
|
||||
|
||||
- (void)performPressAction {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
|
||||
[action perform];
|
||||
[action release];
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
if (@available(macOS 10.13, *)) {
|
||||
return NSAccessibilityTabButtonSubrole;
|
||||
}
|
||||
return NSAccessibilityUnknownSubrole;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
|
||||
|
||||
// Returns the current selection of the page tab list
|
||||
id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
|
||||
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityPerformPress {
|
||||
[self performPressAction];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TabGroupAccessibility : CommonComponentAccessibility {
|
||||
NSInteger _numTabs;
|
||||
}
|
||||
|
||||
@property(readonly) NSInteger numTabs;
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
|
||||
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
|
||||
|
||||
@end
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "TabGroupAccessibility.h"
|
||||
#import "TabButtonAccessibility.h"
|
||||
#import "../JavaAccessibilityUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation TabGroupAccessibility
|
||||
|
||||
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext
|
||||
{
|
||||
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
|
||||
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
|
||||
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
|
||||
if (selAccessible == NULL) return nil;
|
||||
|
||||
// Go through the tabs and find selAccessible
|
||||
_numTabs = [tabs count];
|
||||
CommonComponentAccessibility *aTab;
|
||||
NSInteger i;
|
||||
for (i = 0; i < _numTabs; i++) {
|
||||
aTab = (CommonComponentAccessibility *)[tabs objectAtIndex:i];
|
||||
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return aTab;
|
||||
}
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selAccessible);
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jtabsAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
fAccessible, fComponent, whichTabs, allowIgnored);
|
||||
CHECK_EXCEPTION();
|
||||
if(jtabsAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
|
||||
if (arrayLen == 0) {
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return nil;
|
||||
}
|
||||
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
|
||||
|
||||
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
|
||||
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
|
||||
if (jtabJavaRole == NULL) {
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return nil;
|
||||
}
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jtabJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
NSString *tabJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
|
||||
NSInteger i;
|
||||
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
|
||||
for(i = 0; i < arrayLen; i+=2) {
|
||||
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
|
||||
CommonComponentAccessibility *tab = [[[TabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
|
||||
(*env)->DeleteLocalRef(env, jtab);
|
||||
[tabs addObject:tab];
|
||||
tabIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jtabsAndRoles);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
|
||||
{
|
||||
// Contents are the children of the selected tab.
|
||||
id currentTab = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
if (currentTab == nil) return nil;
|
||||
|
||||
NSArray *contents = [CommonComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
|
||||
if ([contents count] <= 0) return nil;
|
||||
return contents;
|
||||
}
|
||||
|
||||
- (NSInteger)numTabs
|
||||
{
|
||||
if (_numTabs == -1) {
|
||||
_numTabs = [[self accessibilityTabsAttribute] count];
|
||||
}
|
||||
return _numTabs;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityTabs
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityContents
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN allowIgnored:NO];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return cont;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
id val = [self currentTabWithEnv:env withAxContext:axContext];
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return val;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
//children = AXTabs + AXContents
|
||||
NSArray *tabs = [self accessibilityTabs];
|
||||
NSArray *contents = [self accessibilityContents];
|
||||
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
|
||||
[children addObjectsFromArray:tabs];
|
||||
[children addObjectsFromArray:contents];
|
||||
|
||||
return (NSArray *)children;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityArrayAttributeValues:(NSAccessibilityAttributeName)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
|
||||
{
|
||||
NSArray *result = nil;
|
||||
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
|
||||
//children = AXTabs + AXContents
|
||||
NSArray *children = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:index allowIgnored:NO]; // first look at the tabs
|
||||
if ([children count] > 0) {
|
||||
result = children;
|
||||
} else {
|
||||
children= [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:(index-[self numTabs]) allowIgnored:NO];
|
||||
if ([children count] > 0) {
|
||||
result = children;
|
||||
}
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
} else {
|
||||
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setAccessibilityValue:(id)accessibilityValue
|
||||
{
|
||||
// set the current tab
|
||||
NSNumber *number = (NSNumber *)accessibilityValue;
|
||||
if (![number boolValue]) return;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
setAxContextSelection(env, axContext, fIndex, fComponent);
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TableAccessibility : CommonComponentAccessibility <NSAccessibilityTable>
|
||||
|
||||
- (BOOL)isAccessibleChildSelectedFromIndex:(int)index;
|
||||
- (int) accessibleRowAtIndex:(int)index;
|
||||
- (int) accessibleColumnAtIndex:(int)index;
|
||||
|
||||
@end
|
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#import "TableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ColumnAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID sjm_getAccessibleName = NULL;
|
||||
#define GET_ACCESSIBLENAME_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", \
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;", ret);
|
||||
|
||||
@implementation TableAccessibility
|
||||
|
||||
- (id)getTableInfo:(jint)info
|
||||
{
|
||||
if (fAccessible == NULL) return 0;
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTableInfo, sjc_CAccessibility, "getTableInfo",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I", nil);
|
||||
jint count = (*env)->CallStaticIntMethod(env, sjc_CAccessibility, jm_getTableInfo, fAccessible,
|
||||
fComponent, info);
|
||||
CHECK_EXCEPTION();
|
||||
NSNumber *index = [NSNumber numberWithInt:count];
|
||||
return index;
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)getTableSelectedInfo:(jint)info
|
||||
{
|
||||
if (fAccessible == NULL) return 0;
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(nil);
|
||||
DECLARE_STATIC_METHOD_RETURN(jm_getTableSelectedInfo, sjc_CAccessibility, "getTableSelectedInfo",
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I", nil);
|
||||
jintArray selected = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getTableSelectedInfo, fAccessible,
|
||||
fComponent, info);
|
||||
CHECK_EXCEPTION();
|
||||
if (selected == NULL) {
|
||||
return nil;
|
||||
}
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, selected);
|
||||
jint *indexsis = (*env)->GetIntArrayElements(env, selected, 0);
|
||||
NSMutableArray<NSNumber *> *nsArraySelected = [NSMutableArray<NSNumber *> arrayWithCapacity:arrayLen];
|
||||
for (int i = 0; i < arrayLen; i++) {
|
||||
[nsArraySelected addObject:[NSNumber numberWithInt:indexsis[i]]];
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, selected);
|
||||
return [NSArray<NSNumber *> arrayWithArray:nsArraySelected];
|
||||
}
|
||||
|
||||
- (int)accessibleRowAtIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return 0;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleRowAtIndex, clsInfo, "getAccessibleRowAtIndex", "(I)I", -1);
|
||||
jint rowAtIndex = (*env)->CallIntMethod(env, axContext, jm_getAccessibleRowAtIndex, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return (int)rowAtIndex;
|
||||
}
|
||||
|
||||
- (int)accessibleColumnAtIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return 0;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_getAccessibleColumnAtIndex, clsInfo, "getAccessibleColumnAtIndex", "(I)I", -1);
|
||||
jint columnAtIndex = (*env)->CallIntMethod(env, axContext, jm_getAccessibleColumnAtIndex, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return (int)columnAtIndex;
|
||||
}
|
||||
|
||||
- (BOOL) isAccessibleChildSelectedFromIndex:(int)index
|
||||
{
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject axContext = [self axContextWithEnv:env];
|
||||
if (axContext == NULL) return NO;
|
||||
jclass clsInfo = (*env)->GetObjectClass(env, axContext);
|
||||
DECLARE_METHOD_RETURN(jm_isAccessibleChildSelected, clsInfo, "isAccessibleChildSelected", "(I)Z", NO);
|
||||
jboolean isAccessibleChildSelected = (*env)->CallIntMethod(env, axContext, jm_isAccessibleChildSelected, (jint)index);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return isAccessibleChildSelected;
|
||||
}
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
return [self accessibilityRows];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilitySelectedChildren
|
||||
{
|
||||
return [self accessibilitySelectedRows];
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityRows
|
||||
{
|
||||
int rowCount = [self accessibilityRowCount];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:rowCount];
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
[children addObject:[[TableRowAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:[self view]
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
}
|
||||
|
||||
- (nullable NSArray<id<NSAccessibilityRow>> *)accessibilitySelectedRows
|
||||
{
|
||||
NSArray<NSNumber *> *selectedRowIndexses = [self getTableSelectedInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_ROWS];
|
||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[selectedRowIndexses count]];
|
||||
for (NSNumber *index in selectedRowIndexses) {
|
||||
[children addObject:[[TableRowAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:index.unsignedIntValue
|
||||
withView:[self view]
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:children];
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
return [super accessibilityLabel] == NULL ? @"table" : [super accessibilityLabel];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilityColumns
|
||||
{
|
||||
int colCount = [self accessibilityColumnCount];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:colCount];
|
||||
for (int i = 0; i < colCount; i++) {
|
||||
[columns addObject:[[ColumnAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i
|
||||
withView:self->fView
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedColumns
|
||||
{
|
||||
NSArray<NSNumber *> *indexes = [self getTableSelectedInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_COLS];
|
||||
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:[indexes count]];
|
||||
for (NSNumber *i in indexes) {
|
||||
[columns addObject:[[ColumnAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:NULL
|
||||
withIndex:i.unsignedIntValue
|
||||
withView:self->fView
|
||||
withJavaRole:JavaAccessibilityIgnore]];
|
||||
}
|
||||
return [NSArray arrayWithArray:columns];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityRowCount
|
||||
{
|
||||
return [[self getTableInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_ROWS] integerValue];
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityColumnCount
|
||||
{
|
||||
return [[self getTableInfo:sun_lwawt_macosx_CAccessibility_JAVA_AX_COLS] integerValue];
|
||||
}
|
||||
|
||||
- (nullable NSArray *)accessibilitySelectedCells
|
||||
{
|
||||
NSArray *children = [super accessibilitySelectedChildren];
|
||||
NSMutableArray *cells = [NSMutableArray arrayWithCapacity:[children count]];
|
||||
for (CommonComponentAccessibility *child in children) {
|
||||
[cells addObject:[[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:[ThreadUtilities getJNIEnv]
|
||||
withAccessible:child->fAccessible
|
||||
withIndex:child->fIndex
|
||||
withView:fView
|
||||
withJavaRole:child->fJavaRole]];
|
||||
}
|
||||
return [NSArray arrayWithArray:cells];
|
||||
}
|
||||
|
||||
- (id)accessibilityCellForColumn:(NSInteger)column row:(NSInteger)row {
|
||||
return [[(TableRowAccessibility *)[[self accessibilityRows] objectAtIndex:row] accessibilityChildren] objectAtIndex:column];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "CommonComponentAccessibility.h"
|
||||
|
||||
@interface TableRowAccessibility : CommonComponentAccessibility <NSAccessibilityRow>
|
||||
|
||||
@property(readonly) NSUInteger rowNumberInTable;
|
||||
|
||||
@end
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "TableRowAccessibility.h"
|
||||
#import "JavaAccessibilityAction.h"
|
||||
#import "JavaAccessibilityUtilities.h"
|
||||
#import "TableAccessibility.h"
|
||||
#import "CellAccessibility.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "JNIUtilities.h"
|
||||
#import "sun_lwawt_macosx_CAccessibility.h"
|
||||
|
||||
static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
static jmethodID jm_getChildrenAndRoles = NULL;
|
||||
#define GET_CHILDRENANDROLES_METHOD_RETURN(ret) \
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(ret); \
|
||||
GET_STATIC_METHOD_RETURN(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles",\
|
||||
"(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;", ret);
|
||||
|
||||
@implementation TableRowAccessibility
|
||||
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilityRole)accessibilityRole
|
||||
{
|
||||
return NSAccessibilityRowRole;
|
||||
}
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole
|
||||
{
|
||||
return NSAccessibilityTableRowSubrole;
|
||||
}
|
||||
|
||||
- (NSArray *)accessibilityChildren
|
||||
{
|
||||
NSArray *children = [super accessibilityChildren];
|
||||
if (children == nil) {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
CommonComponentAccessibility *parent = [self accessibilityParent];
|
||||
if (parent->fAccessible == NULL) return nil;
|
||||
GET_CHILDRENANDROLES_METHOD_RETURN(nil);
|
||||
jobjectArray jchildrenAndRoles = (jobjectArray)(*env)->CallStaticObjectMethod(env, sjc_CAccessibility, jm_getChildrenAndRoles,
|
||||
parent->fAccessible, parent->fComponent, sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN, NO);
|
||||
CHECK_EXCEPTION();
|
||||
if (jchildrenAndRoles == NULL) return nil;
|
||||
|
||||
jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = fIndex * [(TableAccessibility *)parent accessibilityColumnCount];
|
||||
NSInteger i = childIndex * 2;
|
||||
NSInteger n = (fIndex + 1) * [(TableAccessibility *)parent accessibilityColumnCount] * 2;
|
||||
for(i; i < n; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
NSString *childJavaRole = nil;
|
||||
if (jchildJavaRole != NULL) {
|
||||
DECLARE_CLASS_RETURN(sjc_AccessibleRole, "javax/accessibility/AccessibleRole", nil);
|
||||
DECLARE_FIELD_RETURN(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;", nil);
|
||||
jobject jkey = (*env)->GetObjectField(env, jchildJavaRole, sjf_key);
|
||||
CHECK_EXCEPTION();
|
||||
childJavaRole = JavaStringToNSString(env, jkey);
|
||||
(*env)->DeleteLocalRef(env, jkey);
|
||||
}
|
||||
|
||||
CellAccessibility *child = [[CellAccessibility alloc] initWithParent:self
|
||||
withEnv:env
|
||||
withAccessible:jchild
|
||||
withIndex:childIndex
|
||||
withView:self->fView
|
||||
withJavaRole:childJavaRole];
|
||||
[childrenCells addObject:[[child retain] autorelease]];
|
||||
|
||||
(*env)->DeleteLocalRef(env, jchild);
|
||||
(*env)->DeleteLocalRef(env, jchildJavaRole);
|
||||
|
||||
childIndex++;
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jchildrenAndRoles);
|
||||
return childrenCells;
|
||||
} else {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)accessibilityIndex
|
||||
{
|
||||
return self->fIndex;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel
|
||||
{
|
||||
NSString *accessibilityName = @"";
|
||||
NSArray *children = [self accessibilityChildren];
|
||||
for (id cell in children) {
|
||||
if ([accessibilityName isEqualToString:@""]) {
|
||||
accessibilityName = [cell accessibilityLabel];
|
||||
} else {
|
||||
accessibilityName = [accessibilityName stringByAppendingFormat:@", %@", [cell accessibilityLabel]];
|
||||
}
|
||||
}
|
||||
return accessibilityName;
|
||||
}
|
||||
|
||||
- (id)accessibilityParent
|
||||
{
|
||||
return [super accessibilityParent];
|
||||
}
|
||||
|
||||
- (NSRect)accessibilityFrame
|
||||
{
|
||||
int height = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].size.height;
|
||||
int width = 0;
|
||||
NSPoint point = [[[self accessibilityChildren] objectAtIndex:0] accessibilityFrame].origin;
|
||||
for (id cell in [self accessibilityChildren]) {
|
||||
width += [cell accessibilityFrame].size.width;
|
||||
}
|
||||
return NSMakeRect(point.x, point.y, width, height);
|
||||
}
|
||||
|
||||
@end
|
119
test/jdk/java/awt/a11y/AccessibleComponentTest.java
Normal file
119
test/jdk/java/awt/a11y/AccessibleComponentTest.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.security.PublicKey;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.GridBagLayout;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JButton;
|
||||
|
||||
public abstract class AccessibleComponentTest {
|
||||
|
||||
protected static volatile boolean testResult = true;
|
||||
protected static volatile CountDownLatch countDownLatch;
|
||||
protected static String INSTRUCTIONS;
|
||||
protected static String exceptionString;
|
||||
protected JFrame mainFrame;
|
||||
protected static AccessibleComponentTest a11yTest;
|
||||
|
||||
public abstract CountDownLatch createCountDownLatch();
|
||||
|
||||
public void createUI(JPanel component, String testName) {
|
||||
mainFrame = new JFrame(testName);
|
||||
GridBagLayout layout = new GridBagLayout();
|
||||
JPanel mainControlPanel = new JPanel(layout);
|
||||
JPanel resultButtonPanel = new JPanel(layout);
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
|
||||
JTextArea instructionTextArea = new JTextArea();
|
||||
instructionTextArea.setText(INSTRUCTIONS);
|
||||
instructionTextArea.setEditable(false);
|
||||
instructionTextArea.setBackground(Color.white);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
mainControlPanel.add(instructionTextArea, gbc);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
mainControlPanel.add(component);
|
||||
|
||||
JButton passButton = new JButton("Pass");
|
||||
passButton.setActionCommand("Pass");
|
||||
passButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
JButton failButton = new JButton("Fail");
|
||||
failButton.setActionCommand("Fail");
|
||||
failButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
testResult = false;
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
resultButtonPanel.add(passButton, gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = 0;
|
||||
resultButtonPanel.add(failButton, gbc);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
mainControlPanel.add(resultButtonPanel, gbc);
|
||||
|
||||
mainFrame.add(mainControlPanel);
|
||||
mainFrame.pack();
|
||||
|
||||
mainFrame.addWindowListener(new WindowAdapter() {
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
mainFrame.dispose();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
}
|
80
test/jdk/java/awt/a11y/AccessibleJComboboxTest.java
Normal file
80
test/jdk/java/awt/a11y/AccessibleJComboboxTest.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264287
|
||||
* @summary Test implementation of NSAccessibilityComboBox protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJComboboxTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AccessibleJComboboxTest extends AccessibleComponentTest {
|
||||
|
||||
@java.lang.Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
void createCombobox() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JCombobox.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the combobox.\n\n"
|
||||
+ "If you can hear combobox selected item tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
String[] NAMES = {"One", "Two", "Three", "Four", "Five"};
|
||||
JComboBox<String> combo = new JComboBox<>(NAMES);
|
||||
|
||||
JLabel label = new JLabel("This is combobox:");
|
||||
label.setLabelFor(combo);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(label);
|
||||
frame.add(combo);
|
||||
exceptionString = "AccessibleJCombobox test failed!";
|
||||
super.createUI(frame, "AccessibleJComboboxTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJComboboxTest test = new AccessibleJComboboxTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(test::createCombobox);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
330
test/jdk/java/awt/a11y/AccessibleJListTest.java
Normal file
330
test/jdk/java/awt/a11y/AccessibleJListTest.java
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264292
|
||||
* @summary Test implementation of NSAccessibilityList protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJListTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Window;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJListTest extends AccessibleComponentTest {
|
||||
|
||||
private static final String[] NAMES = {"One", "Two", "Three", "Four", "Five"};
|
||||
static JWindow window;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
a11yTest = new AccessibleJListTest();
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleList);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleListRenderer);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createSimpleListNamed);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createCombobox);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createPushButton);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = a11yTest.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(((AccessibleJListTest) a11yTest)::createPushButtonHeavyWeight);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createSimpleList() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
exceptionString = "Accessible JList simple list test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createSimpleListRenderer() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList with renderer.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
list.setCellRenderer(new AccessibleJListTestRenderer());
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
exceptionString = "Accessible JList with renderer simple list test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createSimpleListNamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JList.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the list.\n"
|
||||
+ "Press the tab button to move to second list.\n\n"
|
||||
+ "If you can hear second list name: \"second list\" - tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JList<String> list = new JList<>(NAMES);
|
||||
JList<String> secondList = new JList<>(NAMES);
|
||||
secondList.getAccessibleContext().setAccessibleName("Second list");
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(list);
|
||||
frame.add(secondList);
|
||||
exceptionString = "Accessible JList simple list named test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
|
||||
public void createCombobox() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a combobox.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the combobox.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear combobox items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JComboBox<String> combo = new JComboBox<>(NAMES);
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(combo);
|
||||
exceptionString = "Accessible JList combobox test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createPushButton() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a popup in a simple window.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the show button and press space.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear popup menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JButton button = new JButton("show");
|
||||
button.setPreferredSize(new Dimension(100, 35));
|
||||
|
||||
button.addActionListener(new ActionListener() {
|
||||
|
||||
final Runnable dispose = () -> {
|
||||
window.dispose();
|
||||
window = null;
|
||||
button.setText("show");
|
||||
};
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (window == null) {
|
||||
Rectangle bounds = frame.getBounds();
|
||||
window = new JWindow(mainFrame);
|
||||
JList<String> winList = new JList<>(NAMES);
|
||||
winList.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
window.add(winList);
|
||||
window.setLocation(bounds.x + bounds.width + 20, bounds.y);
|
||||
window.pack();
|
||||
window.setVisible(true);
|
||||
button.setText("hide (ESC)");
|
||||
} else {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(button);
|
||||
exceptionString = "Accessible JList push button with simple window test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public void createPushButtonHeavyWeight() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JList in a popup in a heavy weight window.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the show button and press space.\n"
|
||||
+ "Press the up and down arrow buttons to move through the list.\n\n"
|
||||
+ "If you can hear popup menu items tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JPanel frame = new JPanel();
|
||||
|
||||
JButton button = new JButton("show");
|
||||
button.setPreferredSize(new Dimension(100, 35));
|
||||
|
||||
button.addActionListener(new ActionListener() {
|
||||
private Popup popup = null;
|
||||
|
||||
final Runnable dispose = () -> {
|
||||
popup.hide();
|
||||
popup = null;
|
||||
button.requestFocus();
|
||||
button.setText("show");
|
||||
};
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (popup == null) {
|
||||
Rectangle bounds = frame.getBounds();
|
||||
PopupFactory factory = PopupFactory.getSharedInstance();
|
||||
JList<String> winList = new JList<>(NAMES);
|
||||
winList.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
popup = factory.getPopup(frame, winList, bounds.x + bounds.width + 20, bounds.y);
|
||||
Window c = SwingUtilities.getWindowAncestor(winList);
|
||||
if (c != null) {
|
||||
c.setAutoRequestFocus(true);
|
||||
c.setFocusableWindowState(true);
|
||||
}
|
||||
popup.show();
|
||||
button.setText("hide (ESC)");
|
||||
} else {
|
||||
dispose.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(button);
|
||||
exceptionString = "Accessible JList push button with heavy weight window test failed!";
|
||||
super.createUI(frame, "Accessible JList test");
|
||||
}
|
||||
|
||||
public static class AccessibleJListTestRenderer extends JPanel implements ListCellRenderer {
|
||||
private JLabel labelAJT = new JLabel("AJL");
|
||||
private JLabel itemName = new JLabel();
|
||||
|
||||
AccessibleJListTestRenderer() {
|
||||
super(new FlowLayout());
|
||||
setFocusable(false);
|
||||
layoutComponents();
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
add(labelAJT);
|
||||
add(itemName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
return new Dimension(Math.min(size.width, 245), size.height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
itemName.setText(((String) value));
|
||||
|
||||
getAccessibleContext().setAccessibleName(labelAJT.getText() + ", " + itemName.getText());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
93
test/jdk/java/awt/a11y/AccessibleJTabbedPaneTest.java
Normal file
93
test/jdk/java/awt/a11y/AccessibleJTabbedPaneTest.java
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8264303
|
||||
* @summary Test implementation of NSAccessibilityTabPanel protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTabbedPaneTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AccessibleJTabbedPaneTest extends AccessibleComponentTest {
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
void createTabPane() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTabbedPane.\n\n"
|
||||
+ "Turn screen reader on, and tab to the JTabbedPane.\n"
|
||||
+ "Use page up and page down arrow buttons to move through the tabs.\n\n"
|
||||
+ "If you can hear selected tab names tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTabbedPane tabbedPane = new JTabbedPane();
|
||||
|
||||
JPanel panel1 = new JPanel();
|
||||
String[] names = {"One", "Two", "Three", "Four", "Five"};
|
||||
JList list = new JList(names);
|
||||
JLabel fieldName = new JLabel("Text field:");
|
||||
JTextField textField = new JTextField("some text");
|
||||
fieldName.setLabelFor(textField);
|
||||
panel1.add(fieldName);
|
||||
panel1.add(textField);
|
||||
panel1.add(list);
|
||||
tabbedPane.addTab("Tab 1", panel1);
|
||||
JPanel panel2 = new JPanel();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
panel2.add(new JCheckBox("CheckBox " + String.valueOf(i + 1)));
|
||||
}
|
||||
tabbedPane.addTab("tab 2", panel2);
|
||||
JPanel panel = new JPanel();
|
||||
panel.add(tabbedPane);
|
||||
|
||||
exceptionString = "AccessibleJTabbedPane test failed!";
|
||||
createUI(panel, "AccessibleJTabbedPaneTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTabbedPaneTest test = new AccessibleJTabbedPaneTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeLater(test::createTabPane);
|
||||
countDownLatch.await();
|
||||
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(a11yTest.exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
114
test/jdk/java/awt/a11y/AccessibleJTableTest.java
Normal file
114
test/jdk/java/awt/a11y/AccessibleJTableTest.java
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267388
|
||||
* @summary Test implementation of NSAccessibilityTable protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTableTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJTableTest extends AccessibleComponentTest {
|
||||
private static final String[] columnNames = {"One", "Two", "Three"};
|
||||
private static final String[][] data = {
|
||||
{"One1", "Two1", "Three1"},
|
||||
{"One2", "Two2", "Three2"},
|
||||
{"One3", "Two3", "Three3"},
|
||||
{"One4", "Two4", "Three4"},
|
||||
{"One5", "Two5", "Three5"}
|
||||
};
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createUI() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTable.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the table.\n"
|
||||
+ "On Windows press the arrow buttons to move through the table.\n\n"
|
||||
+ "On MacOS, use the up and down arrow buttons to move through rows, and VoiceOver fast navigation to move through columns.\n\n"
|
||||
+ "If you can hear table cells ctrl+tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTable table = new JTable(data, columnNames);
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTable test failed!";
|
||||
super.createUI(panel, "AccessibleJTableTest");
|
||||
}
|
||||
|
||||
public void createUINamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTable.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the table.\n"
|
||||
+ "Press the ctrl+tab button to move to second table.\n\n"
|
||||
+ "If you can hear second table name: \"second table\" - ctrl+tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
JTable table = new JTable(data, columnNames);
|
||||
JTable secondTable = new JTable(data, columnNames);
|
||||
secondTable.getAccessibleContext().setAccessibleName("Second table");
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
JScrollPane secondScrollPane = new JScrollPane(secondTable);
|
||||
panel.add(scrollPane);
|
||||
panel.add(secondScrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTable test failed!";
|
||||
super.createUI(panel, "AccessibleJTableTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTableTest test = new AccessibleJTableTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createUI);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createUINamed);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
239
test/jdk/java/awt/a11y/AccessibleJTreeTest.java
Normal file
239
test/jdk/java/awt/a11y/AccessibleJTreeTest.java
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8267387
|
||||
* @summary Test implementation of NSAccessibilityOutLine protocol peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleJTreeTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.Hashtable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleJTreeTest extends AccessibleComponentTest {
|
||||
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void createSampleTree() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
tree.setRootVisible(true);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree sample item test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public void createSampleTreeUnvisableRoot() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree with invisible root.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree sample item invisible root test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public void createSampleTreeNamed() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTree.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the tab button to move to second tree.\\n\n"
|
||||
+ "If you can hear second tree name: \"second tree\" - tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
JTree secondTree = new JTree(data);
|
||||
secondTree.getAccessibleContext().setAccessibleName("Second tree");
|
||||
tree.setRootVisible(true);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
JScrollPane secondScrollPane = new JScrollPane(secondTree);
|
||||
panel.add(scrollPane);
|
||||
panel.add(secondScrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree named test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
|
||||
public void createRendererTree() {
|
||||
INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTree using renderer.\n\n"
|
||||
+ "Turn screen reader on, and Tab to the tree.\n"
|
||||
+ "Press the arrow buttons to move through the tree.\n\n"
|
||||
+ "If you can hear tree components tab further and press PASS, otherwise press FAIL.\n";
|
||||
|
||||
String root = "Root";
|
||||
String[] nodes = new String[] {"One node", "Two node"};
|
||||
String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"},
|
||||
{"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}};
|
||||
|
||||
Hashtable<String, String[]> data = new Hashtable<String, String[]>();
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
data.put(nodes[i], leafs[i]);
|
||||
}
|
||||
|
||||
JTree tree = new JTree(data);
|
||||
tree.setRootVisible(true);
|
||||
tree.setCellRenderer(new AccessibleJTreeTestRenderer());
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
JScrollPane scrollPane = new JScrollPane(tree);
|
||||
panel.add(scrollPane);
|
||||
panel.setFocusable(false);
|
||||
exceptionString = "AccessibleJTree renderer item test failed!";
|
||||
super.createUI(panel, "AccessibleJTreeTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleJTreeTest test = new AccessibleJTreeTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTree);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTreeNamed);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSampleTreeUnvisableRoot);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createRendererTree);
|
||||
countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(AccessibleComponentTest.exceptionString);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccessibleJTreeTestRenderer extends JPanel implements TreeCellRenderer {
|
||||
private JLabel labelAJT = new JLabel("AJT");
|
||||
private JLabel itemName = new JLabel();
|
||||
|
||||
AccessibleJTreeTestRenderer() {
|
||||
super(new FlowLayout());
|
||||
setFocusable(false);
|
||||
layoutComponents();
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
add(labelAJT);
|
||||
add(itemName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
itemName.setText((String) (((DefaultMutableTreeNode) value).getUserObject()));
|
||||
|
||||
getAccessibleContext().setAccessibleName(labelAJT.getText() + ", " + itemName.getText());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
return new Dimension(Math.min(size.width, 245), size.height);
|
||||
}
|
||||
}
|
||||
}
|
293
test/jdk/java/awt/a11y/AccessibleTextTest.java
Normal file
293
test/jdk/java/awt/a11y/AccessibleTextTest.java
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8262031
|
||||
* @summary Test implementation of NSAccessibilityNavigableStaticTest and NSAccessibilityStaticText protocols peer
|
||||
* @author Artem.Semenov@jetbrains.com
|
||||
* @run main/manual AccessibleTextTest
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
*/
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AccessibleTextTest extends AccessibleComponentTest {
|
||||
@Override
|
||||
public CountDownLatch createCountDownLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
private void createSimpleLabel() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JLabel.\n\n"
|
||||
+ "Turn screen reader on.\n"
|
||||
+ "On MacOS, use the VO navigation keys to read the label text;\n"
|
||||
+ "ON Windows with JAWS, use window virtualization (insert+alt+w and arrows) to read the label text;\n"
|
||||
+ "ON Windows with NVDA, use the browse cursor (insert+num4 or insert+num6) to read the label text;\n\n"
|
||||
+ "If you can hear text from label tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JLabel label = new JLabel("this is a label");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(label);
|
||||
exceptionString = "Simple label test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createOneLineTexField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTextField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text field and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextField textField = new JTextField("some text to edit");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textField);
|
||||
exceptionString = "Simple text field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createPassField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JPasswordField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the password field and type some characters.\n\n"
|
||||
+ "If you can hear sounds specific to your screen reader when interacting with password fields, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPasswordField passwordField = new JPasswordField("12345678");
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(passwordField);
|
||||
exceptionString = "Simple passfield field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createNamedTextField() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of named JTextField.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text field.\n\n"
|
||||
+ "If you can hear in addition to the fact that this text field is also the names of these fields, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextField textField = new JTextField("some text 1");
|
||||
textField.getAccessibleContext().setAccessibleName("This is the first text field:");
|
||||
|
||||
JLabel label = new JLabel("This is the second text field:");
|
||||
JTextField secondTextField = new JTextField("some text 2");
|
||||
label.setLabelFor(secondTextField);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textField);
|
||||
panel.add(label);
|
||||
panel.add(secondTextField);
|
||||
exceptionString = "Named text field test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createTextArea() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of JTextArea.\n\n"
|
||||
+ "Turn screen reader on and press the arrow keys.\n\n"
|
||||
+ "If you can hear this instructions, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
exceptionString = "Simple text area test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createEditableTextArea() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of editable JTextArea.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text area and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextArea textArea = new JTextArea("some text to edit");
|
||||
JLabel label = new JLabel(textArea.getText().length() + " chars");
|
||||
label.setLabelFor(textArea);
|
||||
textArea.setEditable(true);
|
||||
textArea.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
label.setText(String.valueOf(textArea.getText().length()) + " chars");
|
||||
}
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textArea);
|
||||
panel.add(label);
|
||||
exceptionString = "Editable text area test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of text in JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and press the arrow keys.\n\n"
|
||||
+ "If you can hear text, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
String str = "Line 1\nLine 2\nLine 3";
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setEditable(false);
|
||||
textPane.setText(str);
|
||||
JTextArea textArea = new JTextArea();
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
exceptionString = "Simple text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createHTMLTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of html text in JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and press the arrow keys.\n\n"
|
||||
+ "If you can hear text, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
String str = "<html><h1>Header</h1><ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul></html>";
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setEditable(false);
|
||||
textPane.setContentType("text/html");
|
||||
textPane.setText(str);
|
||||
JTextArea textArea = new JTextArea();
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
exceptionString = "HTML text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
private void createEditableTextPane() {
|
||||
AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n"
|
||||
+ "Check a11y of editable JTextPane.\n\n"
|
||||
+ "Turn screen reader on and press Tab to move to the text pane and type some characters.\n\n"
|
||||
+ "If you can hear input results according to your screen reader settings, tab further and press PASS, otherwise press FAIL.";
|
||||
|
||||
JTextPane textPane = new JTextPane();
|
||||
textPane.setText("some text to edit");
|
||||
JLabel label = new JLabel(textPane.getText().length() + " chars");
|
||||
label.setLabelFor(textPane);
|
||||
textPane.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
label.setText(String.valueOf(textPane.getText().length()) + " chars");
|
||||
}
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new FlowLayout());
|
||||
panel.add(textPane);
|
||||
panel.add(label);
|
||||
exceptionString = "Editable text pane test failed!";
|
||||
super.createUI(panel, "AccessibleTextTest");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AccessibleTextTest test = new AccessibleTextTest();
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createSimpleLabel);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createOneLineTexField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createPassField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createNamedTextField);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createTextArea);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createEditableTextArea);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createHTMLTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
|
||||
countDownLatch = test.createCountDownLatch();
|
||||
SwingUtilities.invokeAndWait(test::createEditableTextPane);
|
||||
AccessibleComponentTest.countDownLatch.await(15, TimeUnit.MINUTES);
|
||||
if (!testResult) {
|
||||
throw new RuntimeException(exceptionString);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user