/src/windows/classes/com/sun/java/accessibility/AccessBridge.java
Java | 7272 lines | 5033 code | 542 blank | 1697 comment | 1558 complexity | 5abad8fd491d1ea5c2f6e8dec052be8b MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-3.0
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
- package com.sun.java.accessibility;
- import java.awt.*;
- import java.awt.event.*;
- import java.util.*;
- import java.lang.*;
- import java.lang.reflect.*;
- import java.beans.*;
- import javax.swing.*;
- import javax.swing.event.*;
- import javax.swing.text.*;
- import javax.swing.tree.*;
- import javax.swing.table.*;
- import javax.swing.plaf.TreeUI;
- import javax.accessibility.*;
- import com.sun.java.accessibility.util.*;
- import sun.awt.AWTAccessor;
- import sun.awt.AppContext;
- import sun.awt.SunToolkit;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.CountDownLatch;
- /*
- * Note: This class has to be public. It's loaded from the VM like this:
- * Class.forName(atName).newInstance();
- */
- @jdk.Exported(false)
- final public class AccessBridge extends AccessBridgeLoader {
- private final String AccessBridgeVersion =
- "AccessBridge 2.0.4";
- private static AccessBridge theAccessBridge;
- private ObjectReferences references;
- private EventHandler eventHandler;
- private boolean runningOnJDK1_4 = false;
- private boolean runningOnJDK1_5 = false;
- // Maps AccessibleRoles strings to AccessibleRoles.
- private ConcurrentHashMap<String,AccessibleRole> accessibleRoleMap = new ConcurrentHashMap<>();
- /**
- If the object's role is in the following array getVirtualAccessibleName
- will use the extended search algorithm.
- */
- private ArrayList<AccessibleRole> extendedVirtualNameSearchRoles = new ArrayList<>();
- /**
- If the role of the object's parent is in the following array
- getVirtualAccessibleName will NOT use the extended search
- algorithm even if the object's role is in the
- extendedVirtualNameSearchRoles array.
- */
- private ArrayList<AccessibleRole> noExtendedVirtualNameSearchParentRoles = new ArrayList<>();
- /**
- * AccessBridge constructor
- *
- * Note: This constructor has to be public. It's called from the VM like this:
- * Class.forName(atName).newInstance();
- */
- public AccessBridge() {
- super();
- theAccessBridge = this;
- references = new ObjectReferences();
- // initialize shutdown hook
- Runtime runTime = Runtime.getRuntime();
- shutdownHook hook = new shutdownHook();
- runTime.addShutdownHook(new Thread(hook));
- // initialize AccessibleRole map
- initAccessibleRoleMap();
- // determine which version of the JDK is running
- String version = getJavaVersionProperty();
- debugString("JDK version = "+version);
- runningOnJDK1_4 = (version.compareTo("1.4") >= 0);
- runningOnJDK1_5 = (version.compareTo("1.5") >= 0);
- // initialize the methods that map HWNDs and Java top-level
- // windows
- if (initHWNDcalls() == true) {
- // is this a JVM we can use?
- // install JDK 1.2 and later Swing ToolKit listener
- EventQueueMonitor.isGUIInitialized();
- // start the Java event handler
- eventHandler = new EventHandler(this);
- // register for menu selection events
- if (runningOnJDK1_4) {
- MenuSelectionManager.defaultManager().addChangeListener(eventHandler);
- }
- // register as a NativeWindowHandler
- addNativeWindowHandler(new DefaultNativeWindowHandler());
- // start in a new thread
- Thread abthread = new Thread(new dllRunner());
- abthread.setDaemon(true);
- abthread.start();
- debugString("AccessBridge started");
- }
- }
- /*
- * adaptor to run the AccessBridge DLL
- */
- private class dllRunner implements Runnable {
- public void run() {
- runDLL();
- }
- }
- /*
- * shutdown hook
- */
- private class shutdownHook implements Runnable {
- public void run() {
- debugString("***** shutdownHook: shutting down...");
- javaShutdown();
- }
- }
- /*
- * Initialize the hashtable that maps Strings to AccessibleRoles.
- */
- private void initAccessibleRoleMap() {
- /*
- * Initialize the AccessibleRoles map. This code uses methods in
- * java.lang.reflect.* to build the map.
- */
- try {
- Class<?> clAccessibleRole = Class.forName ("javax.accessibility.AccessibleRole");
- if (null != clAccessibleRole) {
- AccessibleRole roleUnknown = AccessibleRole.UNKNOWN;
- Field [] fields = clAccessibleRole.getFields ();
- int i = 0;
- for (i = 0; i < fields.length; i ++) {
- Field f = fields [i];
- if (javax.accessibility.AccessibleRole.class == f.getType ()) {
- AccessibleRole nextRole = (AccessibleRole) (f.get (roleUnknown));
- String nextRoleString = nextRole.toDisplayString (Locale.US);
- accessibleRoleMap.put (nextRoleString, nextRole);
- }
- }
- }
- } catch (Exception e) {}
- /*
- Build the extendedVirtualNameSearchRoles array list. I chose this method
- because some of the Accessible Roles that need to be added to it are not
- available in all versions of the J2SE that we want to support.
- */
- extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX);
- try {
- /*
- Added in J2SE 1.4
- */
- extendedVirtualNameSearchRoles.add (AccessibleRole.DATE_EDITOR);
- } catch (NoSuchFieldError e) {}
- extendedVirtualNameSearchRoles.add (AccessibleRole.LIST);
- extendedVirtualNameSearchRoles.add (AccessibleRole.PASSWORD_TEXT);
- extendedVirtualNameSearchRoles.add (AccessibleRole.SLIDER);
- try {
- /*
- Added in J2SE 1.3
- */
- extendedVirtualNameSearchRoles.add (AccessibleRole.SPIN_BOX);
- } catch (NoSuchFieldError e) {}
- extendedVirtualNameSearchRoles.add (AccessibleRole.TABLE);
- extendedVirtualNameSearchRoles.add (AccessibleRole.TEXT);
- extendedVirtualNameSearchRoles.add (AccessibleRole.UNKNOWN);
- noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TABLE);
- noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TOOL_BAR);
- }
- /**
- * start the AccessBridge DLL running in its own thread
- */
- private native void runDLL();
- /**
- * debugging output (goes to OutputDebugStr())
- */
- private native void sendDebugString(String debugStr);
- /**
- * debugging output (goes to OutputDebugStr())
- */
- private void debugString(String debugStr) {
- sendDebugString(debugStr);
- }
- /* ===== utility methods ===== */
- /**
- * decrement the reference to the object (called by native code)
- */
- private void decrementReference(Object o) {
- references.decrement(o);
- }
- /**
- * get the java.version property from the JVM
- */
- private String getJavaVersionProperty() {
- String s = System.getProperty("java.version");
- if (s != null) {
- references.increment(s);
- return s;
- }
- return null;
- }
- /**
- * get the java.version property from the JVM
- */
- private String getAccessBridgeVersion() {
- String s = new String(AccessBridgeVersion);
- references.increment(s);
- return s;
- }
- /* ===== HWND/Java window mapping methods ===== */
- // Java toolkit methods for mapping HWNDs to Java components
- private Method javaGetComponentFromNativeWindowHandleMethod;
- private Method javaGetNativeWindowHandleFromComponentMethod;
- // native jawt methods for mapping HWNDs to Java components
- private native int isJAWTInstalled();
- private native int jawtGetNativeWindowHandleFromComponent(Component comp);
- private native Component jawtGetComponentFromNativeWindowHandle(int handle);
- Toolkit toolkit;
- /**
- * map an HWND to an AWT Component
- */
- private boolean initHWNDcalls() {
- Class<?> integerParemter[] = new Class<?>[1];
- integerParemter[0] = Integer.TYPE;
- Class<?> componentParemter[] = new Class<?>[1];
- try {
- componentParemter[0] = Class.forName("java.awt.Component");
- } catch (ClassNotFoundException e) {
- debugString("Exception: " + e.toString());
- }
- Object[] args = new Object[1];
- Component c;
- boolean returnVal = false;
- toolkit = Toolkit.getDefaultToolkit();
- if (useJAWT_DLL) {
- returnVal = true;
- } else {
- // verify javaGetComponentFromNativeWindowHandle() method
- // is present if JAWT.DLL is not installed
- try {
- javaGetComponentFromNativeWindowHandleMethod =
- toolkit.getClass().getMethod(
- "getComponentFromNativeWindowHandle", integerParemter);
- if (javaGetComponentFromNativeWindowHandleMethod != null) {
- try {
- args[0] = new Integer(1);
- c = (Component) javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args);
- returnVal = true;
- } catch (InvocationTargetException e) {
- debugString("Exception: " + e.toString());
- } catch (IllegalAccessException e) {
- debugString("Exception: " + e.toString());
- }
- }
- } catch (NoSuchMethodException e) {
- debugString("Exception: " + e.toString());
- } catch (SecurityException e) {
- debugString("Exception: " + e.toString());
- }
- // verify getComponentFromNativeWindowHandle() method
- // is present if JAWT.DLL is not installed
- try {
- javaGetNativeWindowHandleFromComponentMethod =
- toolkit.getClass().getMethod(
- "getNativeWindowHandleFromComponent", componentParemter);
- if (javaGetNativeWindowHandleFromComponentMethod != null) {
- try {
- args[0] = new Button("OK"); // need some Component...
- Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args);
- returnVal = true;
- } catch (InvocationTargetException e) {
- debugString("Exception: " + e.toString());
- } catch (IllegalAccessException e) {
- debugString("Exception: " + e.toString());
- } catch (Exception e) {
- debugString("Exception: " + e.toString());
- }
- }
- } catch (NoSuchMethodException e) {
- debugString("Exception: " + e.toString());
- } catch (SecurityException e) {
- debugString("Exception: " + e.toString());
- }
- }
- return returnVal;
- }
- // native window handler interface
- private interface NativeWindowHandler {
- public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle);
- }
- // hash table of native window handle to AccessibleContext mappings
- static private ConcurrentHashMap<Integer,AccessibleContext> windowHandleToContextMap = new ConcurrentHashMap<>();
- // hash table of AccessibleContext to native window handle mappings
- static private ConcurrentHashMap<AccessibleContext,Integer> contextToWindowHandleMap = new ConcurrentHashMap<>();
- /*
- * adds a virtual window handler to our hash tables
- */
- static private void registerVirtualFrame(final Accessible a,
- Integer nativeWindowHandle ) {
- if (a != null) {
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return a.getAccessibleContext();
- }
- }, a);
- windowHandleToContextMap.put(nativeWindowHandle, ac);
- contextToWindowHandleMap.put(ac, nativeWindowHandle);
- }
- }
- /*
- * removes a virtual window handler to our hash tables
- */
- static private void revokeVirtualFrame(final Accessible a,
- Integer nativeWindowHandle ) {
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return a.getAccessibleContext();
- }
- }, a);
- windowHandleToContextMap.remove(nativeWindowHandle);
- contextToWindowHandleMap.remove(ac);
- }
- // vector of native window handlers
- private static Vector<NativeWindowHandler> nativeWindowHandlers = new Vector<>();
- /*
- * adds a native window handler to our list
- */
- private static void addNativeWindowHandler(NativeWindowHandler handler) {
- if (handler == null) {
- throw new IllegalArgumentException();
- }
- nativeWindowHandlers.addElement(handler);
- }
- /*
- * removes a native window handler to our list
- */
- private static boolean removeNativeWindowHandler(NativeWindowHandler handler) {
- if (handler == null) {
- throw new IllegalArgumentException();
- }
- return nativeWindowHandlers.removeElement(handler);
- }
- /**
- * verifies that a native window handle is a Java window
- */
- private boolean isJavaWindow(int nativeHandle) {
- AccessibleContext ac = getContextFromNativeWindowHandle(nativeHandle);
- if (ac != null) {
- saveContextToWindowHandleMapping(ac, nativeHandle);
- return true;
- }
- return false;
- }
- /*
- * saves the mapping between an AccessibleContext and a window handle
- */
- private void saveContextToWindowHandleMapping(AccessibleContext ac,
- int nativeHandle) {
- debugString("saveContextToWindowHandleMapping...");
- if (ac == null) {
- return;
- }
- if (! contextToWindowHandleMap.containsKey(ac)) {
- debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle);
- contextToWindowHandleMap.put(ac, nativeHandle);
- }
- }
- /**
- * maps a native window handle to an Accessible Context
- */
- private AccessibleContext getContextFromNativeWindowHandle(int nativeHandle) {
- // First, look for the Accessible in our hash table of
- // virtual window handles.
- AccessibleContext ac = windowHandleToContextMap.get(nativeHandle);
- if(ac!=null) {
- saveContextToWindowHandleMapping(ac, nativeHandle);
- return ac;
- }
- // Next, look for the native window handle in our vector
- // of native window handles.
- int numHandlers = nativeWindowHandlers.size();
- for (int i = 0; i < numHandlers; i++) {
- NativeWindowHandler nextHandler = nativeWindowHandlers.elementAt(i);
- final Accessible a = nextHandler.getAccessibleFromNativeWindowHandle(nativeHandle);
- if (a != null) {
- ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return a.getAccessibleContext();
- }
- }, a);
- saveContextToWindowHandleMapping(ac, nativeHandle);
- return ac;
- }
- }
- // Not found.
- return null;
- }
- /**
- * maps an AccessibleContext to a native window handle
- * returns 0 on error
- */
- private int getNativeWindowHandleFromContext(AccessibleContext ac) {
- debugString("getNativeWindowHandleFromContext: ac = "+ac);
- try {
- return contextToWindowHandleMap.get(ac);
- } catch (Exception ex) {
- return 0;
- }
- }
- private class DefaultNativeWindowHandler implements NativeWindowHandler {
- /*
- * returns the Accessible associated with a native window
- */
- public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle) {
- final Component c = getComponentFromNativeWindowHandle(nativeHandle);
- if (c instanceof Accessible) {
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return c.getAccessibleContext();
- }
- }, c);
- saveContextToWindowHandleMapping(ac, nativeHandle);
- return (Accessible)c;
- } else {
- return null;
- }
- }
- /**
- * map an HWND to an AWT Component
- */
- private Component getComponentFromNativeWindowHandle(int nativeHandle) {
- if (useJAWT_DLL) {
- debugString("*** calling jawtGetComponentFromNativeWindowHandle");
- return jawtGetComponentFromNativeWindowHandle(nativeHandle);
- } else {
- debugString("*** calling javaGetComponentFromNativeWindowHandle");
- Object[] args = new Object[1];
- if (javaGetComponentFromNativeWindowHandleMethod != null) {
- try {
- args[0] = nativeHandle;
- Object o = javaGetComponentFromNativeWindowHandleMethod.invoke(toolkit, args);
- if (o instanceof Accessible) {
- final Accessible acc=(Accessible)o;
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return acc.getAccessibleContext();
- }
- }, (Component)o);
- saveContextToWindowHandleMapping(ac,nativeHandle);
- }
- return (Component)o;
- } catch (InvocationTargetException | IllegalAccessException e) {
- debugString("Exception: " + e.toString());
- }
- }
- }
- return null;
- }
- }
- /**
- * map an AWT Component to an HWND
- */
- private int getNativeWindowHandleFromComponent(final Component target) {
- if (useJAWT_DLL) {
- debugString("*** calling jawtGetNativeWindowHandleFromComponent");
- return jawtGetNativeWindowHandleFromComponent(target);
- } else {
- Object[] args = new Object[1];
- debugString("*** calling javaGetNativeWindowHandleFromComponent");
- if (javaGetNativeWindowHandleFromComponentMethod != null) {
- try {
- args[0] = target;
- Integer i = (Integer) javaGetNativeWindowHandleFromComponentMethod.invoke(toolkit, args);
- // cache the mapping
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return target.getAccessibleContext();
- }
- }, target);
- contextToWindowHandleMap.put(ac, i);
- return i.intValue();
- } catch (InvocationTargetException e) {
- debugString("Exception: " + e.toString());
- } catch (IllegalAccessException e) {
- debugString("Exception: " + e.toString());
- }
- }
- }
- return -1;
- }
- /* ===== AccessibleContext methods =====*/
- /*
- * returns the inner-most AccessibleContext in parent at Point(x, y)
- */
- private AccessibleContext getAccessibleContextAt(int x, int y,
- AccessibleContext parent) {
- if (parent == null) {
- return null;
- }
- if (windowHandleToContextMap != null &&
- windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
- // Path for applications that register their top-level
- // windows with the AccessBridge (e.g., StarOffice 6.1)
- return getAccessibleContextAt_1(x, y, parent);
- } else {
- // Path for applications that do not register
- // their top-level windows with the AccessBridge
- // (e.g., Swing/AWT applications)
- return getAccessibleContextAt_2(x, y, parent);
- }
- }
- /*
- * returns the root accessible context
- */
- private AccessibleContext getRootAccessibleContext(final AccessibleContext ac) {
- if (ac == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible parent = ac.getAccessibleParent();
- if (parent == null) {
- return ac;
- }
- Accessible tmp = parent.getAccessibleContext().getAccessibleParent();
- while (tmp != null) {
- parent = tmp;
- tmp = parent.getAccessibleContext().getAccessibleParent();
- }
- return parent.getAccessibleContext();
- }
- }, ac);
- }
- /*
- * StarOffice version that does not use the EventQueueMonitor
- */
- private AccessibleContext getAccessibleContextAt_1(final int x, final int y,
- final AccessibleContext parent) {
- debugString(" : getAccessibleContextAt_1 called");
- debugString(" -> x = " + x + " y = " + y + " parent = " + parent);
- if (parent == null) return null;
- final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable<AccessibleComponent>() {
- @Override
- public AccessibleComponent call() throws Exception {
- return parent.getAccessibleComponent();
- }
- }, parent);
- if (acmp!=null) {
- final Point loc = InvocationUtils.invokeAndWait(new Callable<Point>() {
- @Override
- public Point call() throws Exception {
- return acmp.getLocation();
- }
- }, parent);
- final Accessible a = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
- @Override
- public Accessible call() throws Exception {
- return acmp.getAccessibleAt(new Point(x - loc.x, y - loc.y));
- }
- }, parent);
- if (a != null) {
- AccessibleContext foundAC = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return a.getAccessibleContext();
- }
- }, parent);
- if (foundAC != null) {
- if (foundAC != parent) {
- // recurse down into the child
- return getAccessibleContextAt_1(x - loc.x, y - loc.y,
- foundAC);
- } else
- return foundAC;
- }
- }
- }
- return parent;
- }
- /*
- * AWT/Swing version
- */
- private AccessibleContext getAccessibleContextAt_2(final int x, final int y,
- AccessibleContext parent) {
- debugString("getAccessibleContextAt_2 called");
- debugString(" -> x = " + x + " y = " + y + " parent = " + parent);
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = EventQueueMonitor.getAccessibleAt(new Point(x, y));
- if (a != null) {
- AccessibleContext childAC = a.getAccessibleContext();
- if (childAC != null) {
- debugString(" returning childAC = " + childAC);
- return childAC;
- }
- }
- return null;
- }
- }, parent);
- }
- /**
- * returns the Accessible that has focus
- */
- private AccessibleContext getAccessibleContextWithFocus() {
- Component c = AWTEventMonitor.getComponentWithFocus();
- if (c != null) {
- final Accessible a = Translator.getAccessible(c);
- if (a != null) {
- AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return a.getAccessibleContext();
- }
- }, c);
- if (ac != null) {
- return ac;
- }
- }
- }
- return null;
- }
- /**
- * returns the AccessibleName from an AccessibleContext
- */
- private String getAccessibleNameFromContext(final AccessibleContext ac) {
- debugString("***** ac = "+ac.getClass());
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleName();
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- debugString("Returning AccessibleName from Context: " + s);
- return s;
- } else {
- return null;
- }
- } else {
- debugString("getAccessibleNameFromContext; ac = null!");
- return null;
- }
- }
- /**
- * Returns an AccessibleName for a component using an algorithm optimized
- * for the JAWS screen reader. This method is only intended for JAWS. All
- * other uses are entirely optional.
- */
- private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) {
- if (null != ac) {
- /*
- Step 1:
- =======
- Determine if we can obtain the Virtual Accessible Name from the
- Accessible Name or Accessible Description of the object.
- */
- String nameString = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleName();
- }
- }, ac);
- if ( ( null != nameString ) && ( 0 != nameString.length () ) ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
- references.increment (nameString);
- return nameString;
- }
- String descriptionString = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleDescription();
- }
- }, ac);
- if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
- references.increment (descriptionString);
- return descriptionString;
- }
- debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
- /*
- Step 2:
- =======
- Decide whether the extended name search algorithm should be
- used for this object.
- */
- boolean bExtendedSearch = false;
- AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return ac.getAccessibleRole();
- }
- }, ac);
- AccessibleContext parentContext = null;
- AccessibleRole parentRole = AccessibleRole.UNKNOWN;
- if ( extendedVirtualNameSearchRoles.contains (role) ) {
- parentContext = getAccessibleParentFromContext (ac);
- if ( null != parentContext ) {
- final AccessibleContext parentContextInnerTemp = parentContext;
- parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return parentContextInnerTemp.getAccessibleRole();
- }
- }, ac);
- if ( AccessibleRole.UNKNOWN != parentRole ) {
- bExtendedSearch = true;
- if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) {
- bExtendedSearch = false;
- }
- }
- }
- }
- if (false == bExtendedSearch) {
- debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + role.toDisplayString (Locale.US) );
- /*
- Step 3:
- =======
- We have determined that we should not use the extended name
- search algorithm for this object (we must obtain the name of
- the object from the object itself and not from neighboring
- objects). However the object name cannot be obtained from
- the Accessible Name or Accessible Description of the object.
- Handle several special cases here that might yield a value for
- the Virtual Accessible Name. Return null if the object does
- not match the criteria for any of these special cases.
- */
- if (AccessibleRole.LABEL == role) {
- /*
- Does the label support the Accessible Text Interface?
- */
- final AccessibleText at = InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
- @Override
- public AccessibleText call() throws Exception {
- return ac.getAccessibleText();
- }
- }, ac);
- if (null != at) {
- int charCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getCharCount();
- }
- }, ac);
- String text = getAccessibleTextRangeFromContext (ac, 0, charCount);
- if (null != text) {
- debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
- references.increment (text);
- return text;
- }
- }
- /*
- Does the label support the Accessible Icon Interface?
- */
- debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
- final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
- @Override
- public AccessibleIcon[] call() throws Exception {
- return ac.getAccessibleIcon();
- }
- }, ac);
- if ( (null != ai) && (ai.length > 0) ) {
- String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ai[0].getAccessibleIconDescription();
- }
- }, ac);
- if (iconDescription != null){
- debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
- references.increment (iconDescription);
- return iconDescription;
- }
- } else {
- parentContext = getAccessibleParentFromContext (ac);
- if ( null != parentContext ) {
- final AccessibleContext parentContextInnerTemp = parentContext;
- parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return parentContextInnerTemp.getAccessibleRole();
- }
- }, ac);
- if ( AccessibleRole.TABLE == parentRole ) {
- int indexInParent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac.getAccessibleIndexInParent();
- }
- }, ac);
- final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent);
- debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
- if (acTableCell != null) {
- final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
- @Override
- public AccessibleIcon[] call() throws Exception {
- return acTableCell.getAccessibleIcon();
- }
- }, ac);
- if ( (null != aiRet) && (aiRet.length > 0) ) {
- String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- public String call() {
- return aiRet[0].getAccessibleIconDescription ();
- }
- }, ac);
- if (iconDescription != null){
- debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
- references.increment (iconDescription);
- return iconDescription;
- }
- }
- }
- }
- }
- }
- } else if ( (AccessibleRole.TOGGLE_BUTTON == role) ||
- (AccessibleRole.PUSH_BUTTON == role) ) {
- /*
- Does the button support the Accessible Icon Interface?
- */
- debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
- final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon []>() {
- public AccessibleIcon [] call() {
- return ac.getAccessibleIcon ();
- }
- }, ac);
- if ( (null != ai) && (ai.length > 0) ) {
- String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- public String call() {
- return ai[0].getAccessibleIconDescription ();
- }
- }, ac);
- if (iconDescription != null){
- debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
- references.increment (iconDescription);
- return iconDescription;
- }
- }
- } else if ( AccessibleRole.CHECK_BOX == role ) {
- /*
- NOTE: The only case I know of in which a check box does not
- have a name is when that check box is contained in a table.
- In this case it would be appropriate to use the display string
- of the check box object as the name (in US English the display
- string is typically either "true" or "false").
- I am using the AccessibleValue interface to obtain the display
- string of the check box. If the Accessible Value is 1, I am
- returning Boolean.TRUE.toString (), If the Accessible Value is
- 0, I am returning Boolean.FALSE.toString (). If the Accessible
- Value is some other number, I will return the display string of
- the current numerical value of the check box.
- */
- final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
- @Override
- public AccessibleValue call() throws Exception {
- return ac.getAccessibleValue();
- }
- }, ac);
- if ( null != av ) {
- nameString = null;
- Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
- @Override
- public Number call() throws Exception {
- return av.getCurrentAccessibleValue();
- }
- }, ac);
- if ( null != value ) {
- if ( 1 == value.intValue () ) {
- nameString = Boolean.TRUE.toString ();
- } else if ( 0 == value.intValue () ) {
- nameString = Boolean.FALSE.toString ();
- } else {
- nameString = value.toString ();
- }
- if ( null != nameString ) {
- references.increment (nameString);
- return nameString;
- }
- }
- }
- }
- return null;
- }
- /*
- +
- Beginning of the extended name search
- +
- */
- final AccessibleContext parentContextOuterTemp = parentContext;
- String parentName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return parentContextOuterTemp.getAccessibleName();
- }
- }, ac);
- String parentDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return parentContextOuterTemp.getAccessibleDescription();
- }
- }, ac);
- /*
- Step 4:
- =======
- Special case for Slider Bar objects.
- */
- if ( (AccessibleRole.SLIDER == role) &&
- (AccessibleRole.PANEL == parentRole) &&
- (null != parentName) ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
- references.increment (parentName);
- return parentName;
- }
- boolean bIsEditCombo = false;
- AccessibleContext testContext = ac;
- /*
- Step 5:
- =======
- Special case for Edit Combo Boxes
- */
- if ( (AccessibleRole.TEXT == role) &&
- (AccessibleRole.COMBO_BOX == parentRole) ) {
- bIsEditCombo = true;
- if (null != parentName) {
- debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
- references.increment (parentName);
- return parentName;
- } else if (null != parentDescription) {
- debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
- references.increment (parentDescription);
- return parentDescription;
- }
- testContext = parentContext;
- parentRole = AccessibleRole.UNKNOWN;
- parentContext = getAccessibleParentFromContext (testContext);
- if ( null != parentContext ) {
- final AccessibleContext parentContextInnerTemp = parentContext;
- parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return parentContextInnerTemp.getAccessibleRole();
- }
- }, ac);
- }
- }
- /*
- Step 6:
- =======
- Attempt to get the Virtual Accessible Name of the object using the
- Accessible Relation Set Info (the LABELED_BY Accessible Relation).
- */
- String version = getJavaVersionProperty ();
- if ( (null != version) && (version.compareTo ("1.3") >= 0) ) {
- final AccessibleContext parentContextTempInner = parentContext;
- AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
- @Override
- public AccessibleRelationSet call() throws Exception {
- return parentContextTempInner.getAccessibleRelationSet();
- }
- }, ac);
- if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) {
- AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY);
- if (labeledByRelation != null) {
- Object [] targets = labeledByRelation.getTarget ();
- Object o = targets [0];
- if (o instanceof Accessible) {
- AccessibleContext labelContext = ((Accessible)o).getAccessibleContext ();
- if (labelContext != null) {
- String labelName = labelContext.getAccessibleName ();
- String labelDescription = labelContext.getAccessibleDescription ();
- if (null != labelName) {
- debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
- references.increment (labelName);
- return labelName;
- } else if (null != labelDescription) {
- debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
- references.increment (labelDescription);
- return labelDescription;
- }
- }
- }
- }
- }
- } else {
- debugString ("bk -- This version of Java does not support AccessibleContext::getAccessibleRelationSet.");
- }
- //Note: add AccessibleContext to use InvocationUtils.invokeAndWait
- /*
- Step 7:
- =======
- Search for a label object that is positioned either just to the left
- or just above the object and get the Accessible Name of the Label
- object.
- */
- int testIndexMax = 0;
- int testX = 0;
- int testY = 0;
- int testWidth = 0;
- int testHeight = 0;
- int targetX = 0;
- int targetY = 0;
- final AccessibleContext tempContext = testContext;
- int testIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return tempContext.getAccessibleIndexInParent();
- }
- }, ac);
- if ( null != parentContext ) {
- final AccessibleContext parentContextInnerTemp = parentContext;
- testIndexMax = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return parentContextInnerTemp.getAccessibleChildrenCount() - 1;
- }
- }, ac);
- }
- testX = getAccessibleXcoordFromContext (testContext);
- testY = getAccessibleYcoordFromContext (testContext);
- testWidth = getAccessibleWidthFromContext (testContext);
- testHeight = getAccessibleHeightFromContext (testContext);
- targetX = testX + 2;
- targetY = testY + 2;
- int childIndex = testIndex - 1;
- /*Accessible child = null;
- AccessibleContext childContext = null;
- AccessibleRole childRole = AccessibleRole.UNKNOWN;*/
- int childX = 0;
- int childY = 0;
- int childWidth = 0;
- int childHeight = 0;
- String childName = null;
- String childDescription = null;
- while (childIndex >= 0) {
- final int childIndexTemp = childIndex;
- final AccessibleContext parentContextInnerTemp = parentContext;
- final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
- @Override
- public Accessible call() throws Exception {
- return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
- }
- }, ac);
- if ( null != child ) {
- final AccessibleContext childContext = InvocationUt…
Large files files are truncated, but you can click here to view the full file