8051626: Rework security restrictions of Java Access Bridge and related Utilities
Summary: Move non-public code to internal directories; restrict those directories
Reviewed-by: mchung, prr, mullan, serb
Contributed-by: peter.brunet@oracle.com
--- a/jdk/src/java.base/share/conf/security/java.security Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/java.base/share/conf/security/java.security Fri Aug 14 13:59:40 2015 -0500
@@ -246,6 +246,10 @@
jdk.nashorn.tools.,\
jdk.tools.jimage.,\
com.sun.activation.registries.,\
+ com.sun.java.accessibility.util.internal.,\
+#ifdef windows
+ com.sun.java.accessibility.internal.,\
+#endif
#ifdef macosx
apple.,\
#endif
@@ -297,6 +301,10 @@
jdk.nashorn.tools.,\
jdk.tools.jimage.,\
com.sun.activation.registries.,\
+ com.sun.java.accessibility.util.internal.,\
+#ifdef windows
+ com.sun.java.accessibility.internal.,\
+#endif
#ifdef macosx
apple.,\
#endif
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java Fri Aug 14 13:59:40 2015 -0500
@@ -78,8 +78,8 @@
return null;
}
try {
- t = Class.forName("com.sun.java.accessibility.util."
- + c.getName()
+ t = Class.forName("com.sun.java.accessibility.util.internal"
+ + c.getSimpleName()
+ "Translator");
return t;
} catch (Exception e) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/internal/ButtonTranslator.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002, 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.util.internal;
+
+import java.lang.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+import javax.accessibility.*;
+import com.sun.java.accessibility.util.*;
+
+/**
+ * <p>The Translator class provides a translation to interface Accessible
+ * for objects that do not implement interface Accessible. Assistive
+ * technologies can use the 'getAccessible' class method of Translator to
+ * obtain an object that implements interface Accessible. If the object
+ * passed in already implements interface Accessible, getAccessible merely
+ * returns the object.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>This class extends the Translator class to provide specific support
+ * for the Button class. Translator.getAccessible() will automatically
+ * load this class when an assistive technology asks for an accessible
+ * translator for Button.
+ *
+ */
+public class ButtonTranslator extends Translator {
+
+ /**
+ * Get the name of this object.
+ * @return the name of the object -- can be null if this object does
+ * not have a name
+ */
+ public String getAccessibleName() {
+ return ((Button) source).getLabel();
+ }
+
+ /**
+ * Set the name of this object.
+ */
+ public void setAccessibleName(String s) {
+ ((Button) source).setLabel(s);
+ }
+
+ public AccessibleRole getAccessibleRole() {
+ return AccessibleRole.PUSH_BUTTON;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/internal/CheckboxTranslator.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002, 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.util.internal;
+
+import java.lang.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+import javax.accessibility.*;
+import com.sun.java.accessibility.util.*;
+
+/**
+ * <p>The Translator class provides a translation to interface Accessible
+ * for objects that do not implement interface Accessible. Assistive
+ * technologies can use the 'getAccessible' class method of Translator to
+ * obtain an object that implements interface Accessible. If the object
+ * passed in already implements interface Accessible, getAccessible merely
+ * returns the object.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>This class extends the Translator class to provide specific support
+ * for the Checkbox class. Translator.getAccessible() will automatically
+ * load this class when an assistive technology asks for an accessible
+ * translator for Checkbox.
+ *
+ */
+public class CheckboxTranslator extends Translator {
+
+ /**
+ * Get the state of this object.
+ * @return an instance of AccessibleState containing the current state of the object
+ * @see AccessibleState
+ */
+ public AccessibleStateSet getAccessibleStateSet() {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (((Checkbox) source).getState()) {
+ states.add(AccessibleState.CHECKED);
+ }
+ return states;
+ }
+
+ /**
+ * Get the name of this object.
+ * @return the name of the object -- can be null if this object does
+ * not have a name
+ */
+ public String getAccessibleName() {
+ return ((Checkbox) source).getLabel();
+ }
+
+ /**
+ * Set the name of this object.
+ */
+ public void setAccessibleName(String s) {
+ ((Checkbox) source).setLabel(s);
+ }
+
+ public AccessibleRole getAccessibleRole() {
+ return AccessibleRole.CHECK_BOX;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/internal/LabelTranslator.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002, 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.util.internal;
+
+import java.lang.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+import javax.accessibility.*;
+import com.sun.java.accessibility.util.*;
+
+/**
+ * <p>The Translator class provides a translation to interface Accessible
+ * for objects that do not implement interface Accessible. Assistive
+ * technologies can use the 'getAccessible' class method of Translator to
+ * obtain an object that implements interface Accessible. If the object
+ * passed in already implements interface Accessible, getAccessible merely
+ * returns the object.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>This class extends the Translator class to provide specific support
+ * for the Label class. Translator.getAccessible() will automatically
+ * load this class when an assistive technology asks for an accessible
+ * translator for Label.
+ *
+ */
+public class LabelTranslator extends Translator {
+
+ public String getAccessibleName() {
+ return ((Label) source).getText();
+ }
+
+ /**
+ * Set the name of this object.
+ */
+ public void setAccessibleName(String s) {
+ ((Label) source).setText(s);
+ }
+
+ public AccessibleRole getAccessibleRole() {
+ return AccessibleRole.LABEL;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/internal/ListTranslator.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002, 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.util.internal;
+
+import java.lang.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+import javax.accessibility.*;
+import com.sun.java.accessibility.util.*;
+
+/**
+ * <p>The Translator class provides a translation to interface Accessible
+ * for objects that do not implement interface Accessible. Assistive
+ * technologies can use the 'getAccessible' class method of Translator to
+ * obtain an object that implements interface Accessible. If the object
+ * passed in already implements interface Accessible, getAccessible merely
+ * returns the object.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>This class extends the Translator class to provide specific support
+ * for the List class. Translator.getAccessible() will automatically
+ * load this class when an assistive technology asks for an accessible
+ * translator for List.
+ *
+ */
+public class ListTranslator extends Translator {
+
+ /**
+ * Get the state of this object.
+ * @return an instance of AccessibleState containing the current state of the object
+ * @see AccessibleState
+ */
+ public AccessibleStateSet getAccessibleStateSet() {
+ AccessibleStateSet states = super.getAccessibleStateSet();
+ if (((java.awt.List) source).isMultipleMode()) {
+ states.add(AccessibleState.MULTISELECTABLE);
+ }
+ if (((java.awt.List) source).getSelectedItems().length > 0) {
+ states.add(AccessibleState.SELECTED);
+ }
+ return states;
+ }
+
+ public AccessibleRole getAccessibleRole() {
+ return AccessibleRole.LIST;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/internal/TextComponentTranslator.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002, 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.util.internal;
+
+import java.lang.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+import javax.accessibility.*;
+import com.sun.java.accessibility.util.*;
+
+/**
+ * <p>The Translator class provides a translation to interface Accessible
+ * for objects that do not implement interface Accessible. Assistive
+ * technologies can use the 'getAccessible' class method of Translator to
+ * obtain an object that implements interface Accessible. If the object
+ * passed in already implements interface Accessible, getAccessible merely
+ * returns the object.
+ *
+ * <p>An example of how an assistive technology might use the Translator
+ * class is as follows:
+ *
+ * <PRE>
+ * Accessible accessible = Translator.getAccessible(someObj);
+ * // obtain information from the 'accessible' object.
+ * </PRE>
+ *
+ * <P>This class extends the Translator class to provide specific support
+ * for the TextComponent class. Translator.getAccessible() will automatically
+ * load this class when an assistive technology asks for an accessible
+ * translator for TextComponent.
+ *
+ */
+public class TextComponentTranslator extends Translator {
+
+ public AccessibleRole getAccessibleRole() {
+ return AccessibleRole.TEXT;
+ }
+}
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2002, 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.util.java.awt;
-
-import java.lang.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-import javax.accessibility.*;
-import com.sun.java.accessibility.util.*;
-
-/**
- * <p>The Translator class provides a translation to interface Accessible
- * for objects that do not implement interface Accessible. Assistive
- * technologies can use the 'getAccessible' class method of Translator to
- * obtain an object that implements interface Accessible. If the object
- * passed in already implements interface Accessible, getAccessible merely
- * returns the object.
- *
- * <p>An example of how an assistive technology might use the Translator
- * class is as follows:
- *
- * <PRE>
- * Accessible accessible = Translator.getAccessible(someObj);
- * // obtain information from the 'accessible' object.
- * </PRE>
- *
- * <P>This class extends the Translator class to provide specific support
- * for the Button class. Translator.getAccessible() will automatically
- * load this class when an assistive technology asks for an accessible
- * translator for Button.
- *
- */
-public class ButtonTranslator extends Translator {
-
- /**
- * Get the name of this object.
- * @return the name of the object -- can be null if this object does
- * not have a name
- */
- public String getAccessibleName() {
- return ((Button) source).getLabel();
- }
-
- /**
- * Set the name of this object.
- */
- public void setAccessibleName(String s) {
- ((Button) source).setLabel(s);
- }
-
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.PUSH_BUTTON;
- }
-}
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2002, 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.util.java.awt;
-
-import java.lang.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-import javax.accessibility.*;
-import com.sun.java.accessibility.util.*;
-
-/**
- * <p>The Translator class provides a translation to interface Accessible
- * for objects that do not implement interface Accessible. Assistive
- * technologies can use the 'getAccessible' class method of Translator to
- * obtain an object that implements interface Accessible. If the object
- * passed in already implements interface Accessible, getAccessible merely
- * returns the object.
- *
- * <p>An example of how an assistive technology might use the Translator
- * class is as follows:
- *
- * <PRE>
- * Accessible accessible = Translator.getAccessible(someObj);
- * // obtain information from the 'accessible' object.
- * </PRE>
- *
- * <P>This class extends the Translator class to provide specific support
- * for the Checkbox class. Translator.getAccessible() will automatically
- * load this class when an assistive technology asks for an accessible
- * translator for Checkbox.
- *
- */
-public class CheckboxTranslator extends Translator {
-
- /**
- * Get the state of this object.
- * @return an instance of AccessibleState containing the current state of the object
- * @see AccessibleState
- */
- public AccessibleStateSet getAccessibleStateSet() {
- AccessibleStateSet states = super.getAccessibleStateSet();
- if (((Checkbox) source).getState()) {
- states.add(AccessibleState.CHECKED);
- }
- return states;
- }
-
- /**
- * Get the name of this object.
- * @return the name of the object -- can be null if this object does
- * not have a name
- */
- public String getAccessibleName() {
- return ((Checkbox) source).getLabel();
- }
-
- /**
- * Set the name of this object.
- */
- public void setAccessibleName(String s) {
- ((Checkbox) source).setLabel(s);
- }
-
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.CHECK_BOX;
- }
-}
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2002, 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.util.java.awt;
-
-import java.lang.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-import javax.accessibility.*;
-import com.sun.java.accessibility.util.*;
-
-/**
- * <p>The Translator class provides a translation to interface Accessible
- * for objects that do not implement interface Accessible. Assistive
- * technologies can use the 'getAccessible' class method of Translator to
- * obtain an object that implements interface Accessible. If the object
- * passed in already implements interface Accessible, getAccessible merely
- * returns the object.
- *
- * <p>An example of how an assistive technology might use the Translator
- * class is as follows:
- *
- * <PRE>
- * Accessible accessible = Translator.getAccessible(someObj);
- * // obtain information from the 'accessible' object.
- * </PRE>
- *
- * <P>This class extends the Translator class to provide specific support
- * for the Label class. Translator.getAccessible() will automatically
- * load this class when an assistive technology asks for an accessible
- * translator for Label.
- *
- */
-public class LabelTranslator extends Translator {
-
- public String getAccessibleName() {
- return ((Label) source).getText();
- }
-
- /**
- * Set the name of this object.
- */
- public void setAccessibleName(String s) {
- ((Label) source).setText(s);
- }
-
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.LABEL;
- }
-}
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2002, 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.util.java.awt;
-
-import java.lang.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-import javax.accessibility.*;
-import com.sun.java.accessibility.util.*;
-
-/**
- * <p>The Translator class provides a translation to interface Accessible
- * for objects that do not implement interface Accessible. Assistive
- * technologies can use the 'getAccessible' class method of Translator to
- * obtain an object that implements interface Accessible. If the object
- * passed in already implements interface Accessible, getAccessible merely
- * returns the object.
- *
- * <p>An example of how an assistive technology might use the Translator
- * class is as follows:
- *
- * <PRE>
- * Accessible accessible = Translator.getAccessible(someObj);
- * // obtain information from the 'accessible' object.
- * </PRE>
- *
- * <P>This class extends the Translator class to provide specific support
- * for the List class. Translator.getAccessible() will automatically
- * load this class when an assistive technology asks for an accessible
- * translator for List.
- *
- */
-public class ListTranslator extends Translator {
-
- /**
- * Get the state of this object.
- * @return an instance of AccessibleState containing the current state of the object
- * @see AccessibleState
- */
- public AccessibleStateSet getAccessibleStateSet() {
- AccessibleStateSet states = super.getAccessibleStateSet();
- if (((java.awt.List) source).isMultipleMode()) {
- states.add(AccessibleState.MULTISELECTABLE);
- }
- if (((java.awt.List) source).getSelectedItems().length > 0) {
- states.add(AccessibleState.SELECTED);
- }
- return states;
- }
-
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.LIST;
- }
-}
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2002, 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.util.java.awt;
-
-import java.lang.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-import javax.accessibility.*;
-import com.sun.java.accessibility.util.*;
-
-/**
- * <p>The Translator class provides a translation to interface Accessible
- * for objects that do not implement interface Accessible. Assistive
- * technologies can use the 'getAccessible' class method of Translator to
- * obtain an object that implements interface Accessible. If the object
- * passed in already implements interface Accessible, getAccessible merely
- * returns the object.
- *
- * <p>An example of how an assistive technology might use the Translator
- * class is as follows:
- *
- * <PRE>
- * Accessible accessible = Translator.getAccessible(someObj);
- * // obtain information from the 'accessible' object.
- * </PRE>
- *
- * <P>This class extends the Translator class to provide specific support
- * for the TextComponent class. Translator.getAccessible() will automatically
- * load this class when an assistive technology asks for an accessible
- * translator for TextComponent.
- *
- */
-public class TextComponentTranslator extends Translator {
-
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.TEXT;
- }
-}
--- a/jdk/src/jdk.accessibility/windows/classes/META-INF/services/javax.accessibility.AccessibilityProvider Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/jdk.accessibility/windows/classes/META-INF/services/javax.accessibility.AccessibilityProvider Fri Aug 14 13:59:40 2015 -0500
@@ -22,5 +22,5 @@
# questions.
-com.sun.java.accessibility.ProviderImpl
+com.sun.java.accessibility.internal.ProviderImpl
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/AccessBridge.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7170 +0,0 @@
-/*
- * 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 {
-
- private static AccessBridge theAccessBridge;
- private ObjectReferences references;
- private EventHandler eventHandler;
-
- // 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<>();
-
- private static native boolean isSysWow();
-
-
- /**
- * Load DLLs
- */
- static {
- // Load the appropriate DLLs
- boolean is32on64 = false;
- if (System.getProperty("os.arch").equals("x86")) {
- // 32 bit JRE
- // Load jabsysinfo.dll so can determine Win bitness
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("jabsysinfo");
- return null;
- }
- }, null, new java.lang.RuntimePermission("loadLibrary.jabsysinfo")
- );
- if (isSysWow()) {
- // 32 bit JRE on 64 bit OS
- is32on64 = true;
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("javaaccessbridge-32");
- return null;
- }
- }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge-32")
- );
- }
- }
- if (!is32on64) {
- // 32 bit JRE on 32 bit OS or 64 bit JRE on 64 bit OS
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("javaaccessbridge");
- return null;
- }
- }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge")
- );
- }
- }
-
- /**
- * AccessBridge constructor
- *
- * Note: This constructor has to be public. It's called from the VM like this:
- * Class.forName(atName).newInstance();
- */
- public AccessBridge() {
- 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);
-
- // initialize the methods that map HWNDs and Java top-level
- // windows
- initHWNDcalls();
-
- // 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
- 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;
- }
-
- /* ===== 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 jawtGetNativeWindowHandleFromComponent(Component comp);
-
- private native Component jawtGetComponentFromNativeWindowHandle(int handle);
-
- Toolkit toolkit;
-
- /**
- * map an HWND to an AWT Component
- */
- private void 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());
- }
- toolkit = Toolkit.getDefaultToolkit();
- return;
- }
-
- // 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 = jawtGetComponentFromNativeWindowHandle(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;
- }
- }
- }
-
- /* ===== 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>() {
- @Override
- public String call() throws Exception {
- 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[]>() {
- @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 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).
- */
- {
- 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;
- }
- }
- }
- }
- }
- }
-
- //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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return child.getAccessibleContext();
- }
- }, ac);
- if ( null != childContext ) {
- AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return childContext.getAccessibleRole();
- }
- }, ac);
- if ( AccessibleRole.LABEL == childRole ) {
- childX = getAccessibleXcoordFromContext (childContext);
- childY = getAccessibleYcoordFromContext (childContext);
- childWidth = getAccessibleWidthFromContext (childContext);
- childHeight = getAccessibleHeightFromContext (childContext);
- if ( (childX < testX) &&
- ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
- references.increment (childDescription);
- return childDescription;
- }
- } else if ( (childY < targetY) &&
- ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
- references.increment (childDescription);
- return childDescription;
- }
- }
- }
- }
- }
- childIndex --;
- }
- childIndex = testIndex + 1;
- while (childIndex <= testIndexMax) {
- 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return child.getAccessibleContext();
- }
- }, ac);
- if ( null != childContext ) {
- AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return childContext.getAccessibleRole();
- }
- }, ac);
- if ( AccessibleRole.LABEL == childRole ) {
- childX = getAccessibleXcoordFromContext (childContext);
- childY = getAccessibleYcoordFromContext (childContext);
- childWidth = getAccessibleWidthFromContext (childContext);
- childHeight = getAccessibleHeightFromContext (childContext);
- if ( (childX < testX) &&
- ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
- references.increment (childDescription);
- return childDescription;
- }
- } else if ( (childY < targetY) &&
- ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
- references.increment (childDescription);
- return childDescription;
- }
- }
- }
- }
- }
- childIndex ++;
- }
- /*
- Step 8:
- =======
- Special case for combo boxes and text objects, based on a
- similar special case I found in some of our internal JAWS code.
-
- Search for a button object that is positioned either just to the left
- or just above the object and get the Accessible Name of the button
- object.
- */
- if ( (AccessibleRole.TEXT == role) ||
- (AccessibleRole.COMBO_BOX == role) ||
- (bIsEditCombo) ) {
- childIndex = testIndex - 1;
- 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return child.getAccessibleContext();
- }
- }, ac);
- if ( null != childContext ) {
- AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return childContext.getAccessibleRole();
- }
- }, ac);
- if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
- ( AccessibleRole.TOGGLE_BUTTON == childRole )) {
- childX = getAccessibleXcoordFromContext (childContext);
- childY = getAccessibleYcoordFromContext (childContext);
- childWidth = getAccessibleWidthFromContext (childContext);
- childHeight = getAccessibleHeightFromContext (childContext);
- if ( (childX < testX) &&
- ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
- references.increment (childDescription);
- return childDescription;
- }
- }
- }
- }
- }
- childIndex --;
- }
- childIndex = testIndex + 1;
- while (childIndex <= testIndexMax) {
- 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return child.getAccessibleContext();
- }
- }, ac);
- if ( null != childContext ) {
- AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return childContext.getAccessibleRole();
- }
- }, ac);
- if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
- ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) {
- childX = getAccessibleXcoordFromContext (childContext);
- childY = getAccessibleYcoordFromContext (childContext);
- childWidth = getAccessibleWidthFromContext (childContext);
- childHeight = getAccessibleHeightFromContext (childContext);
- if ( (childX < testX) &&
- ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
- childName = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleName();
- }
- }, ac);
- if ( null != childName ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
- references.increment (childName);
- return childName;
- }
- childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return childContext.getAccessibleDescription();
- }
- }, ac);
- if ( null != childDescription ) {
- debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
- references.increment (childDescription);
- return childDescription;
- }
- }
- }
- }
- }
- childIndex ++;
- }
- }
- return null;
- } else {
- debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
- return null;
- }
- }
-
- /**
- * returns the AccessibleDescription from an AccessibleContext
- */
- private String getAccessibleDescriptionFromContext(final AccessibleContext ac) {
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleDescription();
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- debugString("Returning AccessibleDescription from Context: " + s);
- return s;
- }
- } else {
- debugString("getAccessibleDescriptionFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * returns the AccessibleRole from an AccessibleContext
- */
- private String getAccessibleRoleStringFromContext(final AccessibleContext ac) {
- if (ac != null) {
- AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
- @Override
- public AccessibleRole call() throws Exception {
- return ac.getAccessibleRole();
- }
- }, ac);
- if (role != null) {
- String s = role.toDisplayString(Locale.US);
- if (s != null) {
- references.increment(s);
- debugString("Returning AccessibleRole from Context: " + s);
- return s;
- }
- }
- } else {
- debugString("getAccessibleRoleStringFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the AccessibleRole from an AccessibleContext in the en_US locale
- */
- private String getAccessibleRoleStringFromContext_en_US(final AccessibleContext ac) {
- return getAccessibleRoleStringFromContext(ac);
- }
-
- /**
- * return the AccessibleStates from an AccessibleContext
- */
- private String getAccessibleStatesStringFromContext(final AccessibleContext ac) {
- if (ac != null) {
- AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
- @Override
- public AccessibleStateSet call() throws Exception {
- return ac.getAccessibleStateSet();
- }
- }, ac);
- if (stateSet != null) {
- String s = stateSet.toString();
- if (s != null &&
- s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
- // Indicate whether this component manages its own
- // children
- AccessibleRole role = ac.getAccessibleRole();
- if (role == AccessibleRole.LIST ||
- role == AccessibleRole.TABLE ||
- role == AccessibleRole.TREE) {
- s += ",";
- s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US);
- }
- references.increment(s);
- debugString("Returning AccessibleStateSet from Context: " + s);
- return s;
- }
- }
- } else {
- debugString("getAccessibleStatesStringFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * returns the AccessibleStates from an AccessibleContext in the en_US locale
- */
- private String getAccessibleStatesStringFromContext_en_US(final AccessibleContext ac) {
- if (ac != null) {
- AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
- @Override
- public AccessibleStateSet call() throws Exception {
- return ac.getAccessibleStateSet();
- }
- }, ac);
- if (stateSet != null) {
- String s = "";
- AccessibleState[] states = stateSet.toArray();
- if (states != null && states.length > 0) {
- s = states[0].toDisplayString(Locale.US);
- for (int i = 1; i < states.length; i++) {
- s = s + "," + states[i].toDisplayString(Locale.US);
- }
- }
- references.increment(s);
- debugString("Returning AccessibleStateSet en_US from Context: " + s);
- return s;
- }
- }
- debugString("getAccessibleStatesStringFromContext; ac = null");
- return null;
- }
-
- /**
- * returns the AccessibleParent from an AccessibleContext
- */
- private AccessibleContext getAccessibleParentFromContext(final AccessibleContext ac) {
- if (ac==null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = ac.getAccessibleParent();
- if (a != null) {
- AccessibleContext apc = a.getAccessibleContext();
- if (apc != null) {
- return apc;
- }
- }
- return null;
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleIndexInParent from an AccessibleContext
- */
- private int getAccessibleIndexInParentFromContext(final AccessibleContext ac) {
- if (ac==null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac.getAccessibleIndexInParent();
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleChild count from an AccessibleContext
- */
- private int getAccessibleChildrenCountFromContext(final AccessibleContext ac) {
- if (ac==null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac.getAccessibleChildrenCount();
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleChild Context from an AccessibleContext
- */
- private AccessibleContext getAccessibleChildFromContext(final AccessibleContext ac, final int index) {
-
- if (ac == null) {
- return null;
- }
-
- final JTable table = InvocationUtils.invokeAndWait(new Callable<JTable>() {
- @Override
- public JTable call() throws Exception {
- // work-around for AccessibleJTable.getCurrentAccessibleContext returning
- // wrong renderer component when cell contains more than one component
- Accessible parent = ac.getAccessibleParent();
- if (parent != null) {
- int indexInParent = ac.getAccessibleIndexInParent();
- Accessible child =
- parent.getAccessibleContext().getAccessibleChild(indexInParent);
- if (child instanceof JTable) {
- return (JTable) child;
- }
- }
- return null;
- }
- }, ac);
-
- if (table == null) {
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = ac.getAccessibleChild(index);
- if (a != null) {
- return a.getAccessibleContext();
- }
- return null;
- }
- }, ac);
- }
-
- final AccessibleTable at = getAccessibleTableFromContext(ac);
-
- final int row = getAccessibleTableRow(at, index);
- final int column = getAccessibleTableColumn(at, index);
-
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- TableCellRenderer renderer = table.getCellRenderer(row, column);
- if (renderer == null) {
- Class<?> columnClass = table.getColumnClass(column);
- renderer = table.getDefaultRenderer(columnClass);
- }
- Component component =
- renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
- false, false, row, column);
- if (component instanceof Accessible) {
- return component.getAccessibleContext();
- }
- return null;
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleComponent bounds on screen from an AccessibleContext
- */
- private Rectangle getAccessibleBoundsOnScreenFromContext(final AccessibleContext ac) {
- if(ac==null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
- @Override
- public Rectangle call() throws Exception {
- AccessibleComponent acmp = ac.getAccessibleComponent();
- if (acmp != null) {
- Rectangle r = acmp.getBounds();
- if (r != null) {
- try {
- Point p = acmp.getLocationOnScreen();
- if (p != null) {
- r.x = p.x;
- r.y = p.y;
- return r;
- }
- } catch (Exception e) {
- return null;
- }
- }
- }
- return null;
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleComponent x-coord from an AccessibleContext
- */
- private int getAccessibleXcoordFromContext(AccessibleContext ac) {
- if (ac != null) {
- Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
- if (r != null) {
- debugString(" - Returning Accessible x coord from Context: " + r.x);
- return r.x;
- }
- } else {
- debugString("getAccessibleXcoordFromContext ac = null");
- }
- return -1;
- }
-
- /**
- * returns the AccessibleComponent y-coord from an AccessibleContext
- */
- private int getAccessibleYcoordFromContext(AccessibleContext ac) {
- debugString("getAccessibleYcoordFromContext() called");
- if (ac != null) {
- Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
- if (r != null) {
- return r.y;
- }
- } else {
- debugString("getAccessibleYcoordFromContext; ac = null");
- }
- return -1;
- }
-
- /**
- * returns the AccessibleComponent height from an AccessibleContext
- */
- private int getAccessibleHeightFromContext(AccessibleContext ac) {
- if (ac != null) {
- Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
- if (r != null) {
- return r.height;
- }
- } else {
- debugString("getAccessibleHeightFromContext; ac = null");
- }
- return -1;
- }
-
- /**
- * returns the AccessibleComponent width from an AccessibleContext
- */
- private int getAccessibleWidthFromContext(AccessibleContext ac) {
- if (ac != null) {
- Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
- if (r != null) {
- return r.width;
- }
- } else {
- debugString("getAccessibleWidthFromContext; ac = null");
- }
- return -1;
- }
-
-
- /**
- * returns the AccessibleComponent from an AccessibleContext
- */
- private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
- if (ac != null) {
- AccessibleComponent acmp = ac.getAccessibleComponent();
- if (acmp != null) {
- debugString("Returning AccessibleComponent Context");
- return acmp;
- }
- } else {
- debugString("getAccessibleComponentFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * returns the AccessibleAction from an AccessibleContext
- */
- private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) {
- debugString("Returning AccessibleAction Context");
- return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleAction>() {
- @Override
- public AccessibleAction call() throws Exception {
- return ac.getAccessibleAction();
- }
- }, ac);
- }
-
- /**
- * returns the AccessibleSelection from an AccessibleContext
- */
- private AccessibleSelection getAccessibleSelectionFromContext(final AccessibleContext ac) {
- return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleSelection>() {
- @Override
- public AccessibleSelection call() throws Exception {
- return ac.getAccessibleSelection();
- }
- }, ac);
- }
-
- /**
- * return the AccessibleText from an AccessibleContext
- */
- private AccessibleText getAccessibleTextFromContext(final AccessibleContext ac) {
- return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
- @Override
- public AccessibleText call() throws Exception {
- return ac.getAccessibleText();
- }
- }, ac);
- }
-
- /**
- * return the AccessibleComponent from an AccessibleContext
- */
- private AccessibleValue getAccessibleValueFromContext(final AccessibleContext ac) {
- return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
- @Override
- public AccessibleValue call() throws Exception {
- return ac.getAccessibleValue();
- }
- }, ac);
- }
-
- /* ===== AccessibleText methods ===== */
-
- /**
- * returns the bounding rectangle for the text cursor
- * XXX
- */
- private Rectangle getCaretLocation(final AccessibleContext ac) {
- debugString("getCaretLocation");
- if (ac==null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
- @Override
- public Rectangle call() throws Exception {
- // workaround for JAAPI not returning cursor bounding rectangle
- Rectangle r = null;
- Accessible parent = ac.getAccessibleParent();
- if (parent instanceof Accessible) {
- int indexInParent = ac.getAccessibleIndexInParent();
- Accessible child =
- parent.getAccessibleContext().getAccessibleChild(indexInParent);
-
- if (child instanceof JTextComponent) {
- JTextComponent text = (JTextComponent) child;
- try {
- r = text.modelToView(text.getCaretPosition());
- if (r != null) {
- Point p = text.getLocationOnScreen();
- r.translate(p.x, p.y);
- }
- } catch (BadLocationException ble) {
- }
- }
- }
- return r;
- }
- }, ac);
- }
-
- /**
- * returns the x-coordinate for the text cursor rectangle
- */
- private int getCaretLocationX(AccessibleContext ac) {
- Rectangle r = getCaretLocation(ac);
- if (r != null) {
- return r.x;
- } else {
- return -1;
- }
- }
-
- /**
- * returns the y-coordinate for the text cursor rectangle
- */
- private int getCaretLocationY(AccessibleContext ac) {
- Rectangle r = getCaretLocation(ac);
- if (r != null) {
- return r.y;
- } else {
- return -1;
- }
- }
-
- /**
- * returns the height for the text cursor rectangle
- */
- private int getCaretLocationHeight(AccessibleContext ac) {
- Rectangle r = getCaretLocation(ac);
- if (r != null) {
- return r.height;
- } else {
- return -1;
- }
- }
-
- /**
- * returns the width for the text cursor rectangle
- */
- private int getCaretLocationWidth(AccessibleContext ac) {
- Rectangle r = getCaretLocation(ac);
- if (r != null) {
- return r.width;
- } else {
- return -1;
- }
- }
-
- /**
- * returns the character count from an AccessibleContext
- */
- private int getAccessibleCharCountFromContext(final AccessibleContext ac) {
- if (ac==null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- return at.getCharCount();
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * returns the caret position from an AccessibleContext
- */
- private int getAccessibleCaretPositionFromContext(final AccessibleContext ac) {
- if (ac==null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- return at.getCaretPosition();
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * Return the index at a specific point from an AccessibleContext
- * Point(x, y) is in screen coordinates.
- */
- private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac,
- final int x, final int y) {
- debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y);
- if (ac==null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- AccessibleComponent acomp = ac.getAccessibleComponent();
- if (at != null && acomp != null) {
- // Convert x and y from screen coordinates to
- // local coordinates.
- try {
- Point p = acomp.getLocationOnScreen();
- int x1, y1;
- if (p != null) {
- x1 = x - p.x;
- if (x1 < 0) {
- x1 = 0;
- }
- y1 = y - p.y;
- if (y1 < 0) {
- y1 = 0;
- }
-
- Point newPoint = new Point(x1, y1);
- int indexAtPoint = at.getIndexAtPoint(new Point(x1, y1));
- return indexAtPoint;
- }
- } catch (Exception e) {
- }
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * return the letter at a specific point from an AccessibleContext
- */
- private String getAccessibleLetterAtIndexFromContext(final AccessibleContext ac, final int index) {
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at == null) return null;
- return at.getAtIndex(AccessibleText.CHARACTER, index);
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getAccessibleLetterAtIndexFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the word at a specific point from an AccessibleContext
- */
- private String getAccessibleWordAtIndexFromContext(final AccessibleContext ac, final int index) {
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at == null) return null;
- return at.getAtIndex(AccessibleText.WORD, index);
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getAccessibleWordAtIndexFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the sentence at a specific point from an AccessibleContext
- */
- private String getAccessibleSentenceAtIndexFromContext(final AccessibleContext ac, final int index) {
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at == null) return null;
- return at.getAtIndex(AccessibleText.SENTENCE, index);
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getAccessibleSentenceAtIndexFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the text selection start from an AccessibleContext
- */
- private int getAccessibleTextSelectionStartFromContext(final AccessibleContext ac) {
- if (ac == null) return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- return at.getSelectionStart();
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * return the text selection end from an AccessibleContext
- */
- private int getAccessibleTextSelectionEndFromContext(final AccessibleContext ac) {
- if (ac == null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- return at.getSelectionEnd();
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * return the selected text from an AccessibleContext
- */
- private String getAccessibleTextSelectedTextFromContext(final AccessibleContext ac) {
- if (ac != null) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at == null) return null;
- return at.getSelectedText();
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getAccessibleTextSelectedTextFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the attribute string at a given index from an AccessibleContext
- */
- private String getAccessibleAttributesAtIndexFromContext(final AccessibleContext ac,
- final int index) {
- if (ac == null)
- return null;
- AttributeSet as = InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
- @Override
- public AttributeSet call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- return at.getCharacterAttribute(index);
- }
- return null;
- }
- }, ac);
- String s = expandStyleConstants(as);
- if (s != null) {
- references.increment(s);
- return s;
- }
- return null;
- }
-
- /**
- * Get line info: left index of line
- *
- * algorithm: cast back, doubling each time,
- * 'till find line boundaries
- *
- * return -1 if we can't get the info (e.g. index or at passed in
- * is bogus; etc.)
- */
- private int getAccessibleTextLineLeftBoundsFromContext(final AccessibleContext ac,
- final int index) {
- if (ac == null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- int lineStart;
- int offset;
- Rectangle charRect;
- Rectangle indexRect = at.getCharacterBounds(index);
- int textLen = at.getCharCount();
- if (indexRect == null) {
- return -1;
- }
- // find the start of the line
- //
- offset = 1;
- lineStart = index - offset < 0 ? 0 : index - offset;
- charRect = at.getCharacterBounds(lineStart);
- // slouch behind beginning of line
- while (charRect != null
- && charRect.y >= indexRect.y
- && lineStart > 0) {
- offset = offset << 1;
- lineStart = index - offset < 0 ? 0 : index - offset;
- charRect = at.getCharacterBounds(lineStart);
- }
- if (lineStart == 0) { // special case: we're on the first line!
- // we found it!
- } else {
- offset = offset >> 1; // know boundary within last expansion
- // ground forward to beginning of line
- while (offset > 0) {
- charRect = at.getCharacterBounds(lineStart + offset);
- if (charRect.y < indexRect.y) { // still before line
- lineStart += offset;
- } else {
- // leave lineStart alone, it's close!
- }
- offset = offset >> 1;
- }
- // subtract one 'cause we're already too far...
- lineStart += 1;
- }
- return lineStart;
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * Get line info: right index of line
- *
- * algorithm: cast back, doubling each time,
- * 'till find line boundaries
- *
- * return -1 if we can't get the info (e.g. index or at passed in
- * is bogus; etc.)
- */
- private int getAccessibleTextLineRightBoundsFromContext(final AccessibleContext ac, final int index) {
- if(ac == null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- int lineEnd;
- int offset;
- Rectangle charRect;
- Rectangle indexRect = at.getCharacterBounds(index);
- int textLen = at.getCharCount();
- if (indexRect == null) {
- return -1;
- }
- // find the end of the line
- //
- offset = 1;
- lineEnd = index + offset > textLen - 1
- ? textLen - 1 : index + offset;
- charRect = at.getCharacterBounds(lineEnd);
- // push past end of line
- while (charRect != null &&
- charRect.y <= indexRect.y &&
- lineEnd < textLen - 1) {
- offset = offset << 1;
- lineEnd = index + offset > textLen - 1
- ? textLen - 1 : index + offset;
- charRect = at.getCharacterBounds(lineEnd);
- }
- if (lineEnd == textLen - 1) { // special case: on the last line!
- // we found it!
- } else {
- offset = offset >> 1; // know boundary within last expansion
- // pull back to end of line
- while (offset > 0) {
- charRect = at.getCharacterBounds(lineEnd - offset);
- if (charRect.y > indexRect.y) { // still beyond line
- lineEnd -= offset;
- } else {
- // leave lineEnd alone, it's close!
- }
- offset = offset >> 1;
- }
- // subtract one 'cause we're already too far...
- lineEnd -= 1;
- }
- return lineEnd;
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * Get a range of text; null if indicies are bogus
- */
- private String getAccessibleTextRangeFromContext(final AccessibleContext ac,
- final int start, final int end) {
- String s = InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- if (ac != null) {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- // start - end is inclusive
- if (start > end) {
- return null;
- }
- if (end >= at.getCharCount()) {
- return null;
- }
- StringBuffer buf = new StringBuffer(end - start + 1);
- for (int i = start; i <= end; i++) {
- buf.append(at.getAtIndex(AccessibleText.CHARACTER, i));
- }
- return buf.toString();
- }
- }
- return null;
- }
- }, ac);
- if (s != null) {
- references.increment(s);
- return s;
- } else {
- return null;
- }
- }
-
- /**
- * return the AttributeSet object at a given index from an AccessibleContext
- */
- private AttributeSet getAccessibleAttributeSetAtIndexFromContext(final AccessibleContext ac,
- final int index) {
- return InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
- @Override
- public AttributeSet call() throws Exception {
- if (ac != null) {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- AttributeSet as = at.getCharacterAttribute(index);
- if (as != null) {
- AccessBridge.this.references.increment(as);
- return as;
- }
- }
- }
- return null;
- }
- }, ac);
- }
-
-
- /**
- * return the bounding rectangle at index from an AccessibleContext
- */
- private Rectangle getAccessibleTextRectAtIndexFromContext(final AccessibleContext ac,
- final int index) {
- // want to do this in global coords, so need to combine w/ac global coords
- Rectangle r = InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
- @Override
- public Rectangle call() throws Exception {
- // want to do this in global coords, so need to combine w/ac global coords
- if (ac != null) {
- AccessibleText at = ac.getAccessibleText();
- if (at != null) {
- Rectangle rect = at.getCharacterBounds(index);
- if (rect != null) {
- String s = at.getAtIndex(AccessibleText.CHARACTER, index);
- if (s != null && s.equals("\n")) {
- rect.width = 0;
- }
- return rect;
- }
- }
- }
- return null;
- }
- }, ac);
- Rectangle acRect = getAccessibleBoundsOnScreenFromContext(ac);
- if (r != null && acRect != null) {
- r.translate(acRect.x, acRect.y);
- return r;
- }
- return null;
- }
-
- /**
- * return the AccessibleText character x-coord at index from an AccessibleContext
- */
- private int getAccessibleXcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
- if (ac != null) {
- Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
- if (r != null) {
- return r.x;
- }
- } else {
- debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null");
- }
- return -1;
- }
-
- /**
- * return the AccessibleText character y-coord at index from an AccessibleContext
- */
- private int getAccessibleYcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
- if (ac != null) {
- Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
- if (r != null) {
- return r.y;
- }
- } else {
- debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null");
- }
- return -1;
- }
-
- /**
- * return the AccessibleText character height at index from an AccessibleContext
- */
- private int getAccessibleHeightTextRectAtIndexFromContext(AccessibleContext ac, int index) {
- if (ac != null) {
- Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
- if (r != null) {
- return r.height;
- }
- } else {
- debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null");
- }
- return -1;
- }
-
- /**
- * return the AccessibleText character width at index from an AccessibleContext
- */
- private int getAccessibleWidthTextRectAtIndexFromContext(AccessibleContext ac, int index) {
- if (ac != null) {
- Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
- if (r != null) {
- return r.width;
- }
- } else {
- debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null");
- }
- return -1;
- }
-
- /* ===== AttributeSet methods for AccessibleText ===== */
-
- /**
- * return the bold setting from an AttributeSet
- */
- private boolean getBoldFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isBold(as);
- } else {
- debugString("getBoldFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the italic setting from an AttributeSet
- */
- private boolean getItalicFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isItalic(as);
- } else {
- debugString("getItalicFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the underline setting from an AttributeSet
- */
- private boolean getUnderlineFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isUnderline(as);
- } else {
- debugString("getUnderlineFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the strikethrough setting from an AttributeSet
- */
- private boolean getStrikethroughFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isStrikeThrough(as);
- } else {
- debugString("getStrikethroughFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the superscript setting from an AttributeSet
- */
- private boolean getSuperscriptFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isSuperscript(as);
- } else {
- debugString("getSuperscriptFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the subscript setting from an AttributeSet
- */
- private boolean getSubscriptFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.isSubscript(as);
- } else {
- debugString("getSubscriptFromAttributeSet; as = null");
- }
- return false;
- }
-
- /**
- * return the background color from an AttributeSet
- */
- private String getBackgroundColorFromAttributeSet(AttributeSet as) {
- if (as != null) {
- String s = StyleConstants.getBackground(as).toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getBackgroundColorFromAttributeSet; as = null");
- }
- return null;
- }
-
- /**
- * return the foreground color from an AttributeSet
- */
- private String getForegroundColorFromAttributeSet(AttributeSet as) {
- if (as != null) {
- String s = StyleConstants.getForeground(as).toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getForegroundColorFromAttributeSet; as = null");
- }
- return null;
- }
-
- /**
- * return the font family from an AttributeSet
- */
- private String getFontFamilyFromAttributeSet(AttributeSet as) {
- if (as != null) {
- String s = StyleConstants.getFontFamily(as).toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- } else {
- debugString("getFontFamilyFromAttributeSet; as = null");
- }
- return null;
- }
-
- /**
- * return the font size from an AttributeSet
- */
- private int getFontSizeFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getFontSize(as);
- } else {
- debugString("getFontSizeFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the alignment from an AttributeSet
- */
- private int getAlignmentFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getAlignment(as);
- } else {
- debugString("getAlignmentFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the BiDi level from an AttributeSet
- */
- private int getBidiLevelFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getBidiLevel(as);
- } else {
- debugString("getBidiLevelFromAttributeSet; as = null");
- }
- return -1;
- }
-
-
- /**
- * return the first line indent from an AttributeSet
- */
- private float getFirstLineIndentFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getFirstLineIndent(as);
- } else {
- debugString("getFirstLineIndentFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the left indent from an AttributeSet
- */
- private float getLeftIndentFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getLeftIndent(as);
- } else {
- debugString("getLeftIndentFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the right indent from an AttributeSet
- */
- private float getRightIndentFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getRightIndent(as);
- } else {
- debugString("getRightIndentFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the line spacing from an AttributeSet
- */
- private float getLineSpacingFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getLineSpacing(as);
- } else {
- debugString("getLineSpacingFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the space above from an AttributeSet
- */
- private float getSpaceAboveFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getSpaceAbove(as);
- } else {
- debugString("getSpaceAboveFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * return the space below from an AttributeSet
- */
- private float getSpaceBelowFromAttributeSet(AttributeSet as) {
- if (as != null) {
- return StyleConstants.getSpaceBelow(as);
- } else {
- debugString("getSpaceBelowFromAttributeSet; as = null");
- }
- return -1;
- }
-
- /**
- * Enumerate all StyleConstants in the AttributeSet
- *
- * We need to check explicitly, 'cause of the HTML package conversion
- * mechanism (they may not be stored as StyleConstants, just translated
- * to them when asked).
- *
- * (Use convenience methods where they are defined...)
- *
- * Not checking the following (which the IBM SNS guidelines says
- * should be defined):
- * - ComponentElementName
- * - IconElementName
- * - NameAttribute
- * - ResolveAttribute
- */
- private String expandStyleConstants(AttributeSet as) {
- Color c;
- Object o;
- String attrString = "";
-
- // ---------- check for various Character Constants
-
- attrString += "BidiLevel = " + StyleConstants.getBidiLevel(as);
-
- final Component comp = StyleConstants.getComponent(as);
- if (comp != null) {
- if (comp instanceof Accessible) {
- final AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return comp.getAccessibleContext();
- }
- }, comp);
- if (ac != null) {
- attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleName();
- }
- }, ac);
- } else {
- attrString += "; Innaccessible Component = " + comp;
- }
- } else {
- attrString += "; Innaccessible Component = " + comp;
- }
- }
-
- Icon i = StyleConstants.getIcon(as);
- if (i != null) {
- if (i instanceof ImageIcon) {
- attrString += "; ImageIcon = " + ((ImageIcon) i).getDescription();
- } else {
- attrString += "; Icon = " + i;
- }
- }
-
- attrString += "; FontFamily = " + StyleConstants.getFontFamily(as);
-
- attrString += "; FontSize = " + StyleConstants.getFontSize(as);
-
- if (StyleConstants.isBold(as)) {
- attrString += "; bold";
- }
-
- if (StyleConstants.isItalic(as)) {
- attrString += "; italic";
- }
-
- if (StyleConstants.isUnderline(as)) {
- attrString += "; underline";
- }
-
- if (StyleConstants.isStrikeThrough(as)) {
- attrString += "; strikethrough";
- }
-
- if (StyleConstants.isSuperscript(as)) {
- attrString += "; superscript";
- }
-
- if (StyleConstants.isSubscript(as)) {
- attrString += "; subscript";
- }
-
- c = StyleConstants.getForeground(as);
- if (c != null) {
- attrString += "; Foreground = " + c;
- }
-
- c = StyleConstants.getBackground(as);
- if (c != null) {
- attrString += "; Background = " + c;
- }
-
- attrString += "; FirstLineIndent = " + StyleConstants.getFirstLineIndent(as);
-
- attrString += "; RightIndent = " + StyleConstants.getRightIndent(as);
-
- attrString += "; LeftIndent = " + StyleConstants.getLeftIndent(as);
-
- attrString += "; LineSpacing = " + StyleConstants.getLineSpacing(as);
-
- attrString += "; SpaceAbove = " + StyleConstants.getSpaceAbove(as);
-
- attrString += "; SpaceBelow = " + StyleConstants.getSpaceBelow(as);
-
- attrString += "; Alignment = " + StyleConstants.getAlignment(as);
-
- TabSet ts = StyleConstants.getTabSet(as);
- if (ts != null) {
- attrString += "; TabSet = " + ts;
- }
-
- return attrString;
- }
-
-
- /* ===== AccessibleValue methods ===== */
-
- /**
- * return the AccessibleValue current value from an AccessibleContext
- * returned using a String 'cause the value is a java Number
- *
- */
- private String getCurrentAccessibleValueFromContext(final AccessibleContext ac) {
- if (ac != null) {
- final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
- @Override
- public Number call() throws Exception {
- AccessibleValue av = ac.getAccessibleValue();
- if (av == null) return null;
- return av.getCurrentAccessibleValue();
- }
- }, ac);
- if (value != null) {
- String s = value.toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- }
- } else {
- debugString("getCurrentAccessibleValueFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the AccessibleValue maximum value from an AccessibleContext
- * returned using a String 'cause the value is a java Number
- *
- */
- private String getMaximumAccessibleValueFromContext(final AccessibleContext ac) {
- if (ac != null) {
- final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
- @Override
- public Number call() throws Exception {
- AccessibleValue av = ac.getAccessibleValue();
- if (av == null) return null;
- return av.getMaximumAccessibleValue();
- }
- }, ac);
- if (value != null) {
- String s = value.toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- }
- } else {
- debugString("getMaximumAccessibleValueFromContext; ac = null");
- }
- return null;
- }
-
- /**
- * return the AccessibleValue minimum value from an AccessibleContext
- * returned using a String 'cause the value is a java Number
- *
- */
- private String getMinimumAccessibleValueFromContext(final AccessibleContext ac) {
- if (ac != null) {
- final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
- @Override
- public Number call() throws Exception {
- AccessibleValue av = ac.getAccessibleValue();
- if (av == null) return null;
- return av.getMinimumAccessibleValue();
- }
- }, ac);
- if (value != null) {
- String s = value.toString();
- if (s != null) {
- references.increment(s);
- return s;
- }
- }
- } else {
- debugString("getMinimumAccessibleValueFromContext; ac = null");
- }
- return null;
- }
-
-
- /* ===== AccessibleSelection methods ===== */
-
- /**
- * add to the AccessibleSelection of an AccessibleContext child i
- *
- */
- private void addAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
- try {
- InvocationUtils.invokeAndWait(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- as.addAccessibleSelection(i);
- }
- }
- return null;
- }
- }, ac);
- } catch(Exception e){}
- }
-
- /**
- * clear all of the AccessibleSelection of an AccessibleContex
- *
- */
- private void clearAccessibleSelectionFromContext(final AccessibleContext ac) {
- try {
- InvocationUtils.invokeAndWait(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- as.clearAccessibleSelection();
- }
- return null;
- }
- }, ac);
- } catch(Exception e){}
-
- }
-
- /**
- * get the AccessibleContext of the i-th AccessibleSelection of an AccessibleContext
- *
- */
- private AccessibleContext getAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- Accessible a = as.getAccessibleSelection(i);
- if (a == null)
- return null;
- else
- return a.getAccessibleContext();
- }
- }
- return null;
- }
- }, ac);
- }
-
- /**
- * get number of things selected in the AccessibleSelection of an AccessibleContext
- *
- */
- private int getAccessibleSelectionCountFromContext(final AccessibleContext ac) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- return as.getAccessibleSelectionCount();
- }
- }
- return -1;
- }
- }, ac);
- }
-
- /**
- * return true if the i-th child of the AccessibleSelection of an AccessibleContext is selected
- *
- */
- private boolean isAccessibleChildSelectedFromContext(final AccessibleContext ac, final int i) {
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- return as.isAccessibleChildSelected(i);
- }
- }
- return false;
- }
- }, ac);
- }
-
- /**
- * remove the i-th child from the AccessibleSelection of an AccessibleContext
- *
- */
- private void removeAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
- InvocationUtils.invokeAndWait(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- as.removeAccessibleSelection(i);
- }
- }
- return null;
- }
- }, ac);
- }
-
- /**
- * select all (if possible) of the children of the AccessibleSelection of an AccessibleContext
- *
- */
- private void selectAllAccessibleSelectionFromContext(final AccessibleContext ac) {
- InvocationUtils.invokeAndWait(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- if (ac != null) {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as != null) {
- as.selectAllAccessibleSelection();
- }
- }
- return null;
- }
- }, ac);
- }
-
- // ======== AccessibleTable ========
-
- ConcurrentHashMap<AccessibleTable,AccessibleContext> hashtab = new ConcurrentHashMap<>();
-
- /**
- * returns the AccessibleTable for an AccessibleContext
- */
- private AccessibleTable getAccessibleTableFromContext(final AccessibleContext ac) {
- return InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
- @Override
- public AccessibleTable call() throws Exception {
- if (ac != null) {
- AccessibleTable at = ac.getAccessibleTable();
- if (at != null) {
- AccessBridge.this.hashtab.put(at, ac);
- return at;
- }
- }
- return null;
- }
- }, ac);
- }
-
-
- /*
- * returns the AccessibleContext that contains an AccessibleTable
- */
- private AccessibleContext getContextFromAccessibleTable(AccessibleTable at) {
- return hashtab.get(at);
- }
-
- /*
- * returns the row count for an AccessibleTable
- */
- private int getAccessibleTableRowCount(final AccessibleContext ac) {
- debugString("##### getAccessibleTableRowCount");
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (ac != null) {
- AccessibleTable at = ac.getAccessibleTable();
- if (at != null) {
- return at.getAccessibleRowCount();
- }
- }
- return -1;
- }
- }, ac);
- }
-
- /*
- * returns the column count for an AccessibleTable
- */
- private int getAccessibleTableColumnCount(final AccessibleContext ac) {
- debugString("##### getAccessibleTableColumnCount");
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (ac != null) {
- AccessibleTable at = ac.getAccessibleTable();
- if (at != null) {
- return at.getAccessibleColumnCount();
- }
- }
- return -1;
- }
- }, ac);
- }
-
- /*
- * returns the AccessibleContext for an AccessibleTable cell
- */
- private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at,
- final int row, final int column) {
- debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass());
- if (at == null) return null;
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- if (!(at instanceof AccessibleContext)) {
- Accessible a = at.getAccessibleAt(row, column);
- if (a != null) {
- return a.getAccessibleContext();
- }
- } else {
- // work-around for AccessibleJTable.getCurrentAccessibleContext returning
- // wrong renderer component when cell contains more than one component
- AccessibleContext ac = (AccessibleContext) at;
- Accessible parent = ac.getAccessibleParent();
- if (parent != null) {
- int indexInParent = ac.getAccessibleIndexInParent();
- Accessible child =
- parent.getAccessibleContext().getAccessibleChild(indexInParent);
- if (child instanceof JTable) {
- JTable table = (JTable) child;
-
- TableCellRenderer renderer = table.getCellRenderer(row, column);
- if (renderer == null) {
- Class<?> columnClass = table.getColumnClass(column);
- renderer = table.getDefaultRenderer(columnClass);
- }
- Component component =
- renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
- false, false, row, column);
- if (component instanceof Accessible) {
- return component.getAccessibleContext();
- }
- }
- }
- }
- return null;
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns the index of a cell at a given row and column in an AccessibleTable
- */
- private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) {
- debugString("##### getAccessibleTableCellIndex: at="+at);
- if (at != null) {
- int cellIndex = row *
- InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleColumnCount();
- }
- }, getContextFromAccessibleTable(at)) +
- column;
- debugString(" ##### getAccessibleTableCellIndex="+cellIndex);
- return cellIndex;
- }
- debugString(" ##### getAccessibleTableCellIndex FAILED");
- return -1;
- }
-
- /*
- * returns the row extent of a cell at a given row and column in an AccessibleTable
- */
- private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) {
- debugString("##### getAccessibleTableCellRowExtent");
- if (at != null) {
- int rowExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleRowExtentAt(row, column);
- }
- },
- getContextFromAccessibleTable(at));
- debugString(" ##### getAccessibleTableCellRowExtent="+rowExtent);
- return rowExtent;
- }
- debugString(" ##### getAccessibleTableCellRowExtent FAILED");
- return -1;
- }
-
- /*
- * returns the column extent of a cell at a given row and column in an AccessibleTable
- */
- private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) {
- debugString("##### getAccessibleTableCellColumnExtent");
- if (at != null) {
- int columnExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleColumnExtentAt(row, column);
- }
- },
- getContextFromAccessibleTable(at));
- debugString(" ##### getAccessibleTableCellColumnExtent="+columnExtent);
- return columnExtent;
- }
- debugString(" ##### getAccessibleTableCellColumnExtent FAILED");
- return -1;
- }
-
- /*
- * returns whether a cell is selected at a given row and column in an AccessibleTable
- */
- private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row,
- final int column) {
- debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]");
- if (at == null)
- return false;
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- boolean isSelected = false;
- Accessible a = at.getAccessibleAt(row, column);
- if (a != null) {
- AccessibleContext ac = a.getAccessibleContext();
- if (ac == null)
- return false;
- AccessibleStateSet as = ac.getAccessibleStateSet();
- if (as != null) {
- isSelected = as.contains(AccessibleState.SELECTED);
- }
- }
- return isSelected;
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns an AccessibleTable that represents the row header in an
- * AccessibleTable
- */
- private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) {
- debugString(" ##### getAccessibleTableRowHeader called");
- AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
- @Override
- public AccessibleTable call() throws Exception {
- if (ac != null) {
- AccessibleTable at = ac.getAccessibleTable();
- if (at != null) {
- return at.getAccessibleRowHeader();
- }
- }
- return null;
- }
- }, ac);
- if (at != null) {
- hashtab.put(at, ac);
- }
- return at;
- }
-
- /*
- * returns an AccessibleTable that represents the column header in an
- * AccessibleTable
- */
- private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) {
- debugString("##### getAccessibleTableColumnHeader");
- if (ac == null)
- return null;
- AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
- @Override
- public AccessibleTable call() throws Exception {
- // workaround for getAccessibleColumnHeader NPE
- // when the table header is null
- Accessible parent = ac.getAccessibleParent();
- if (parent != null) {
- int indexInParent = ac.getAccessibleIndexInParent();
- Accessible child =
- parent.getAccessibleContext().getAccessibleChild(indexInParent);
- if (child instanceof JTable) {
- JTable table = (JTable) child;
- if (table.getTableHeader() == null) {
- return null;
- }
- }
- }
- AccessibleTable at = ac.getAccessibleTable();
- if (at != null) {
- return at.getAccessibleColumnHeader();
- }
- return null;
- }
- }, ac);
- if (at != null) {
- hashtab.put(at, ac);
- }
- return at;
- }
-
- /*
- * returns the number of row headers in an AccessibleTable that represents
- * the row header in an AccessibleTable
- */
- private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) {
-
- debugString(" ##### getAccessibleTableRowHeaderRowCount called");
- if (ac != null) {
- final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
- if (atRowHeader != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (atRowHeader != null) {
- return atRowHeader.getAccessibleRowCount();
- }
- return -1;
- }
- }, ac);
- }
- }
- return -1;
- }
-
- /*
- * returns the number of column headers in an AccessibleTable that represents
- * the row header in an AccessibleTable
- */
- private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) {
- debugString(" ##### getAccessibleTableRowHeaderColumnCount called");
- if (ac != null) {
- final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
- if (atRowHeader != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (atRowHeader != null) {
- return atRowHeader.getAccessibleColumnCount();
- }
- return -1;
- }
- }, ac);
- }
- }
- debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED");
- return -1;
- }
-
- /*
- * returns the number of row headers in an AccessibleTable that represents
- * the column header in an AccessibleTable
- */
- private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) {
-
- debugString("##### getAccessibleTableColumnHeaderRowCount");
- if (ac != null) {
- final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
- if (atColumnHeader != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (atColumnHeader != null) {
- return atColumnHeader.getAccessibleRowCount();
- }
- return -1;
- }
- }, ac);
- }
- }
- debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED");
- return -1;
- }
-
- /*
- * returns the number of column headers in an AccessibleTable that represents
- * the column header in an AccessibleTable
- */
- private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) {
-
- debugString("##### getAccessibleTableColumnHeaderColumnCount");
- if (ac != null) {
- final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
- if (atColumnHeader != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (atColumnHeader != null) {
- return atColumnHeader.getAccessibleColumnCount();
- }
- return -1;
- }
- }, ac);
- }
- }
- debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED");
- return -1;
- }
-
- /*
- * returns the description of a row header in an AccessibleTable
- */
- private AccessibleContext getAccessibleTableRowDescription(final AccessibleTable table,
- final int row) {
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- if (table != null) {
- Accessible a = table.getAccessibleRowDescription(row);
- if (a != null) {
- return a.getAccessibleContext();
- }
- }
- return null;
- }
- }, getContextFromAccessibleTable(table));
- }
-
- /*
- * returns the description of a column header in an AccessibleTable
- */
- private AccessibleContext getAccessibleTableColumnDescription(final AccessibleTable at,
- final int column) {
- if (at == null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = at.getAccessibleColumnDescription(column);
- if (a != null) {
- return a.getAccessibleContext();
- }
- return null;
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns the number of rows selected in an AccessibleTable
- */
- private int getAccessibleTableRowSelectionCount(final AccessibleTable at) {
- if (at != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- int[] selections = at.getSelectedAccessibleRows();
- if (selections != null)
- return selections.length;
- else
- return -1;
- }
- }, getContextFromAccessibleTable(at));
- }
- return -1;
- }
-
- /*
- * returns the row number of the i-th selected row in an AccessibleTable
- */
- private int getAccessibleTableRowSelections(final AccessibleTable at, final int i) {
- if (at != null) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- int[] selections = at.getSelectedAccessibleRows();
- if (selections.length > i) {
- return selections[i];
- }
- return -1;
- }
- }, getContextFromAccessibleTable(at));
- }
- return -1;
- }
-
- /*
- * returns whether a row is selected in an AccessibleTable
- */
- private boolean isAccessibleTableRowSelected(final AccessibleTable at,
- final int row) {
- if (at == null)
- return false;
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return at.isAccessibleRowSelected(row);
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns whether a column is selected in an AccessibleTable
- */
- private boolean isAccessibleTableColumnSelected(final AccessibleTable at,
- final int column) {
- if (at == null)
- return false;
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return at.isAccessibleColumnSelected(column);
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns the number of columns selected in an AccessibleTable
- */
- private int getAccessibleTableColumnSelectionCount(final AccessibleTable at) {
- if (at == null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- int[] selections = at.getSelectedAccessibleColumns();
- if (selections != null)
- return selections.length;
- else
- return -1;
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /*
- * returns the row number of the i-th selected row in an AccessibleTable
- */
- private int getAccessibleTableColumnSelections(final AccessibleTable at, final int i) {
- if (at == null)
- return -1;
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- int[] selections = at.getSelectedAccessibleColumns();
- if (selections != null && selections.length > i) {
- return selections[i];
- }
- return -1;
- }
- }, getContextFromAccessibleTable(at));
- }
-
- /* ===== AccessibleExtendedTable (since 1.4) ===== */
-
- /*
- * returns the row number for a cell at a given index in an AccessibleTable
- */
- private int getAccessibleTableRow(final AccessibleTable at, int index) {
- if (at == null)
- return -1;
- int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleColumnCount();
- }
- }, getContextFromAccessibleTable(at));
- return index / colCount;
- }
-
- /*
- * returns the column number for a cell at a given index in an AccessibleTable
- */
- private int getAccessibleTableColumn(final AccessibleTable at, int index) {
- if (at == null)
- return -1;
- int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleColumnCount();
- }
- }, getContextFromAccessibleTable(at));
- return index % colCount;
- }
-
- /*
- * returns the index for a cell at a given row and column in an
- * AccessibleTable
- */
- private int getAccessibleTableIndex(final AccessibleTable at, int row, int column) {
- if (at == null)
- return -1;
- int colCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return at.getAccessibleColumnCount();
- }
- }, getContextFromAccessibleTable(at));
- return row * colCount + column;
- }
-
- // ===== AccessibleRelationSet =====
-
- /*
- * returns the number of relations in the AccessibleContext's
- * AccessibleRelationSet
- */
- private int getAccessibleRelationCount(final AccessibleContext ac) {
- {
- if (ac != null) {
- AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
- @Override
- public AccessibleRelationSet call() throws Exception {
- return ac.getAccessibleRelationSet();
- }
- }, ac);
- if (ars != null)
- return ars.size();
- }
- }
- return 0;
- }
-
- /*
- * returns the ith relation key in the AccessibleContext's
- * AccessibleRelationSet
- */
- private String getAccessibleRelationKey(final AccessibleContext ac, final int i) {
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- if (ac != null) {
- AccessibleRelationSet ars = ac.getAccessibleRelationSet();
- if (ars != null) {
- AccessibleRelation[] relations = ars.toArray();
- if (relations != null && i >= 0 && i < relations.length) {
- return relations[i].getKey();
- }
- }
- }
- return null;
- }
- }, ac);
- }
-
- /*
- * returns the number of targets in a relation in the AccessibleContext's
- * AccessibleRelationSet
- */
- private int getAccessibleRelationTargetCount(final AccessibleContext ac, final int i) {
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- if (ac != null) {
- AccessibleRelationSet ars = ac.getAccessibleRelationSet();
- if (ars != null) {
- AccessibleRelation[] relations = ars.toArray();
- if (relations != null && i >= 0 && i < relations.length) {
- Object[] targets = relations[i].getTarget();
- return targets.length;
- }
- }
- }
- return -1;
- }
- }, ac);
- }
-
- /*
- * returns the jth target in the ith relation in the AccessibleContext's
- * AccessibleRelationSet
- */
- private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac,
- final int i, final int j) {
- debugString("***** getAccessibleRelationTarget");
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- if (ac != null) {
- AccessibleRelationSet ars = ac.getAccessibleRelationSet();
- if (ars != null) {
- AccessibleRelation[] relations = ars.toArray();
- if (relations != null && i >= 0 && i < relations.length) {
- Object[] targets = relations[i].getTarget();
- if (targets != null && j >= 0 & j < targets.length) {
- Object o = targets[j];
- if (o instanceof Accessible) {
- return ((Accessible) o).getAccessibleContext();
- }
- }
- }
- }
- }
- return null;
- }
- }, ac);
- }
-
- // ========= AccessibleHypertext =========
-
- private Map<AccessibleHypertext, AccessibleContext> hyperTextContextMap = new WeakHashMap<>();
- private Map<AccessibleHyperlink, AccessibleContext> hyperLinkContextMap = new WeakHashMap<>();
-
- /*
- * Returns the AccessibleHypertext
- */
- private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) {
- debugString("getAccessibleHyperlink");
- if (ac==null)
- return null;
- AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable<AccessibleHypertext>() {
- @Override
- public AccessibleHypertext call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (!(at instanceof AccessibleHypertext)) {
- return null;
- }
- return ((AccessibleHypertext) at);
- }
- }, ac);
- hyperTextContextMap.put(hypertext, ac);
- return hypertext;
- }
-
- /*
- * Returns the number of AccessibleHyperlinks
- */
- private int getAccessibleHyperlinkCount(AccessibleContext ac) {
- debugString("getAccessibleHyperlinkCount");
- if (ac == null) {
- return 0;
- }
- final AccessibleHypertext hypertext = getAccessibleHypertext(ac);
- if (hypertext == null) {
- return 0;
- }
- //return hypertext.getLinkCount();
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return hypertext.getLinkCount();
- }
- }, ac);
- }
-
- /*
- * Returns the hyperlink at the specified index
- */
- private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) {
- debugString("getAccessibleHyperlink");
- if (hypertext == null) {
- return null;
- }
- AccessibleContext ac = hyperTextContextMap.get(hypertext);
- if ( i < 0 || i >=
- InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return hypertext.getLinkCount();
- }
- }, ac) ) {
- return null;
- }
- AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable<AccessibleHyperlink>() {
- @Override
- public AccessibleHyperlink call() throws Exception {
- AccessibleHyperlink link = hypertext.getLink(i);
- if (link == null || (!link.isValid())) {
- return null;
- }
- return link;
- }
- }, ac);
- hyperLinkContextMap.put(acLink, ac);
- return acLink;
- }
-
- /*
- * Returns the hyperlink object description
- */
- private String getAccessibleHyperlinkText(final AccessibleHyperlink link) {
- debugString("getAccessibleHyperlinkText");
- if (link == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- Object o = link.getAccessibleActionDescription(0);
- if (o != null) {
- return o.toString();
- }
- return null;
- }
- }, hyperLinkContextMap.get(link));
- }
-
- /*
- * Returns the hyperlink URL
- */
- private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) {
- debugString("getAccessibleHyperlinkURL");
- if (link == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- Object o = link.getAccessibleActionObject(0);
- if (o != null) {
- return o.toString();
- } else {
- return null;
- }
- }
- }, hyperLinkContextMap.get(link));
- }
-
- /*
- * Returns the start index of the hyperlink text
- */
- private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) {
- debugString("getAccessibleHyperlinkStartIndex");
- if (link == null) {
- return -1;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return link.getStartIndex();
- }
- }, hyperLinkContextMap.get(link));
- }
-
- /*
- * Returns the end index of the hyperlink text
- */
- private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) {
- debugString("getAccessibleHyperlinkEndIndex");
- if (link == null) {
- return -1;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return link.getEndIndex();
- }
- }, hyperLinkContextMap.get(link));
- }
-
- /*
- * Returns the index into an array of hyperlinks that
- * is associated with this character index, or -1 if there
- * is no hyperlink associated with this index.
- */
- private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) {
- debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex);
- if (hypertext == null) {
- return -1;
- }
- int linkIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return hypertext.getLinkIndex(charIndex);
- }
- }, hyperTextContextMap.get(hypertext));
- debugString("getAccessibleHypertextLinkIndex returning "+linkIndex);
- return linkIndex;
- }
-
- /*
- * Actives the hyperlink
- */
- private boolean activateAccessibleHyperlink(final AccessibleContext ac,
- final AccessibleHyperlink link) {
- //debugString("activateAccessibleHyperlink: link = "+link.getClass());
- if (link == null) {
- return false;
- }
- boolean retval = InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return link.doAccessibleAction(0);
- }
- }, ac);
- debugString("activateAccessibleHyperlink: returning = "+retval);
- return retval;
- }
-
-
- // ============ AccessibleKeyBinding =============
-
- /*
- * returns the component mnemonic
- */
- private KeyStroke getMnemonic(final AccessibleContext ac) {
- if (ac == null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
- @Override
- public KeyStroke call() throws Exception {
- AccessibleComponent comp = ac.getAccessibleComponent();
- if (!(comp instanceof AccessibleExtendedComponent)) {
- return null;
- }
- AccessibleExtendedComponent aec = (AccessibleExtendedComponent) comp;
- if (aec != null) {
- AccessibleKeyBinding akb = aec.getAccessibleKeyBinding();
- if (akb != null) {
- Object o = akb.getAccessibleKeyBinding(0);
- if (o instanceof KeyStroke) {
- return (KeyStroke) o;
- }
- }
- }
- return null;
- }
- }, ac);
- }
-
- /*
- * returns the JMenuItem accelerator
- */
- private KeyStroke getAccelerator(final AccessibleContext ac) {
- // workaround for getAccessibleKeyBinding not returning the
- // JMenuItem accelerator
- if (ac == null)
- return null;
- return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
- @Override
- public KeyStroke call() throws Exception {
- Accessible parent = ac.getAccessibleParent();
- if (parent instanceof Accessible) {
- int indexInParent = ac.getAccessibleIndexInParent();
- Accessible child =
- parent.getAccessibleContext().getAccessibleChild(indexInParent);
- if (child instanceof JMenuItem) {
- JMenuItem menuItem = (JMenuItem) child;
- if (menuItem == null)
- return null;
- KeyStroke keyStroke = menuItem.getAccelerator();
- return keyStroke;
- }
- }
- return null;
- }
- }, ac);
- }
-
- /*
- * returns 1-24 to indicate which F key is being used for a shortcut or 0 otherwise
- */
- private int fKeyNumber(KeyStroke keyStroke) {
- if (keyStroke == null)
- return 0;
- int fKey = 0;
- String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
- if (keyText != null && (keyText.length() == 2 || keyText.length() == 3)) {
- String prefix = keyText.substring(0, 1);
- if (prefix.equals("F")) {
- try {
- int suffix = Integer.parseInt(keyText.substring(1));
- if (suffix >= 1 && suffix <= 24) {
- fKey = suffix;
- }
- } catch (Exception e) { // ignore NumberFormatException
- }
- }
- }
- return fKey;
- }
-
- /*
- * returns one of several important control characters or 0 otherwise
- */
- private int controlCode(KeyStroke keyStroke) {
- if (keyStroke == null)
- return 0;
- int code = keyStroke.getKeyCode();
- switch (code) {
- case KeyEvent.VK_BACK_SPACE:
- case KeyEvent.VK_DELETE:
- case KeyEvent.VK_DOWN:
- case KeyEvent.VK_END:
- case KeyEvent.VK_HOME:
- case KeyEvent.VK_INSERT:
- case KeyEvent.VK_KP_DOWN:
- case KeyEvent.VK_KP_LEFT:
- case KeyEvent.VK_KP_RIGHT:
- case KeyEvent.VK_KP_UP:
- case KeyEvent.VK_LEFT:
- case KeyEvent.VK_PAGE_DOWN:
- case KeyEvent.VK_PAGE_UP:
- case KeyEvent.VK_RIGHT:
- case KeyEvent.VK_UP:
- break;
- default:
- code = 0;
- break;
- }
- return code;
- }
-
- /*
- * returns the KeyStoke character
- */
- private char getKeyChar(KeyStroke keyStroke) {
- // If the shortcut is an FKey return 1-24
- if (keyStroke == null)
- return 0;
- int fKey = fKeyNumber(keyStroke);
- if (fKey != 0) {
- // return 0x00000001 through 0x00000018
- debugString(" Shortcut is: F" + fKey);
- return (char)fKey;
- }
- // If the accelerator is a control character, return it
- int keyCode = controlCode(keyStroke);
- if (keyCode != 0) {
- debugString(" Shortcut is control character: " + Integer.toHexString(keyCode));
- return (char)keyCode;
- }
- String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
- debugString(" Shortcut is: " + keyText);
- if (keyText != null || keyText.length() > 0) {
- CharSequence seq = keyText.subSequence(0, 1);
- if (seq != null || seq.length() > 0) {
- return seq.charAt(0);
- }
- }
- return 0;
- }
-
- /*
- * returns the KeyStroke modifiers as an int
- */
- private int getModifiers(KeyStroke keyStroke) {
- if (keyStroke == null)
- return 0;
- debugString("In AccessBridge.getModifiers");
- // modifiers is a bit strip where bits 0-7 indicate a traditional modifier
- // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates
- // a control code shortcut such as the delete key.
-
- int modifiers = 0;
- // Is the shortcut an FKey?
- if (fKeyNumber(keyStroke) != 0) {
- modifiers |= 1 << 8;
- }
- // Is the shortcut a control code?
- if (controlCode(keyStroke) != 0) {
- modifiers |= 1 << 9;
- }
- // The following is needed in order to handle translated modifiers.
- // getKeyModifiersText doesn't work because for example in German Strg is
- // returned for Ctrl.
-
- // There can be more than one modifier, e.g. if the modifier is ctrl + shift + B
- // the toString text is "shift ctrl pressed B". Need to parse through that.
- StringTokenizer st = new StringTokenizer(keyStroke.toString());
- while (st.hasMoreTokens()) {
- String text = st.nextToken();
- // Meta+Ctrl+Alt+Shift
- // 0-3 are shift, ctrl, meta, alt
- // 4-7 are for Solaris workstations (though not being used)
- if (text.startsWith("met")) {
- debugString(" found meta");
- modifiers |= ActionEvent.META_MASK;
- }
- if (text.startsWith("ctr")) {
- debugString(" found ctrl");
- modifiers |= ActionEvent.CTRL_MASK;
- }
- if (text.startsWith("alt")) {
- debugString(" found alt");
- modifiers |= ActionEvent.ALT_MASK;
- }
- if (text.startsWith("shi")) {
- debugString(" found shift");
- modifiers |= ActionEvent.SHIFT_MASK;
- }
- }
- debugString(" returning modifiers: 0x" + Integer.toHexString(modifiers));
- return modifiers;
- }
-
- /*
- * returns the number of key bindings associated with this context
- */
- private int getAccessibleKeyBindingsCount(AccessibleContext ac) {
- if (ac == null)
- return 0;
- int count = 0;
-
- if (getMnemonic(ac) != null) {
- count++;
- }
- if (getAccelerator(ac) != null) {
- count++;
- }
- return count;
- }
-
- /*
- * returns the key binding character at the specified index
- */
- private char getAccessibleKeyBindingChar(AccessibleContext ac, int index) {
- if (ac == null)
- return 0;
- if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
- KeyStroke keyStroke = getAccelerator(ac);
- if (keyStroke != null) {
- return getKeyChar(keyStroke);
- }
- }
- if (index == 0) { // mnemonic
- KeyStroke keyStroke = getMnemonic(ac);
- if (keyStroke != null) {
- return getKeyChar(keyStroke);
- }
- } else if (index == 1) { // accelerator
- KeyStroke keyStroke = getAccelerator(ac);
- if (keyStroke != null) {
- return getKeyChar(keyStroke);
- }
- }
- return 0;
- }
-
- /*
- * returns the key binding modifiers at the specified index
- */
- private int getAccessibleKeyBindingModifiers(AccessibleContext ac, int index) {
- if (ac == null)
- return 0;
- if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
- KeyStroke keyStroke = getAccelerator(ac);
- if (keyStroke != null) {
- return getModifiers(keyStroke);
- }
- }
- if (index == 0) { // mnemonic
- KeyStroke keyStroke = getMnemonic(ac);
- if (keyStroke != null) {
- return getModifiers(keyStroke);
- }
- } else if (index == 1) { // accelerator
- KeyStroke keyStroke = getAccelerator(ac);
- if (keyStroke != null) {
- return getModifiers(keyStroke);
- }
- }
- return 0;
- }
-
- // ========== AccessibleIcon ============
-
- /*
- * return the number of icons associated with this context
- */
- private int getAccessibleIconsCount(final AccessibleContext ac) {
- debugString("getAccessibleIconsCount");
- if (ac == null) {
- return 0;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleIcon[] ai = ac.getAccessibleIcon();
- if (ai == null) {
- return 0;
- }
- return ai.length;
- }
- }, ac);
- }
-
- /*
- * return icon description at the specified index
- */
- private String getAccessibleIconDescription(final AccessibleContext ac, final int index) {
- debugString("getAccessibleIconDescription: index = "+index);
- if (ac == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleIcon[] ai = ac.getAccessibleIcon();
- if (ai == null || index < 0 || index >= ai.length) {
- return null;
- }
- return ai[index].getAccessibleIconDescription();
- }
- }, ac);
- }
-
- /*
- * return icon height at the specified index
- */
- private int getAccessibleIconHeight(final AccessibleContext ac, final int index) {
- debugString("getAccessibleIconHeight: index = "+index);
- if (ac == null) {
- return 0;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleIcon[] ai = ac.getAccessibleIcon();
- if (ai == null || index < 0 || index >= ai.length) {
- return 0;
- }
- return ai[index].getAccessibleIconHeight();
- }
- }, ac);
- }
-
- /*
- * return icon width at the specified index
- */
- private int getAccessibleIconWidth(final AccessibleContext ac, final int index) {
- debugString("getAccessibleIconWidth: index = "+index);
- if (ac == null) {
- return 0;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleIcon[] ai = ac.getAccessibleIcon();
- if (ai == null || index < 0 || index >= ai.length) {
- return 0;
- }
- return ai[index].getAccessibleIconWidth();
- }
- }, ac);
- }
-
- // ========= AccessibleAction ===========
-
- /*
- * return the number of icons associated with this context
- */
- private int getAccessibleActionsCount(final AccessibleContext ac) {
- debugString("getAccessibleActionsCount");
- if (ac == null) {
- return 0;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa == null)
- return 0;
- return aa.getAccessibleActionCount();
- }
- }, ac);
- }
-
- /*
- * return icon description at the specified index
- */
- private String getAccessibleActionName(final AccessibleContext ac, final int index) {
- debugString("getAccessibleActionName: index = "+index);
- if (ac == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa == null) {
- return null;
- }
- return aa.getAccessibleActionDescription(index);
- }
- }, ac);
- }
- /*
- * return icon description at the specified index
- */
- private boolean doAccessibleActions(final AccessibleContext ac, final String name) {
- debugString("doAccessibleActions: action name = "+name);
- if (ac == null || name == null) {
- return false;
- }
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa == null) {
- return false;
- }
- int index = -1;
- int numActions = aa.getAccessibleActionCount();
- for (int i = 0; i < numActions; i++) {
- String actionName = aa.getAccessibleActionDescription(i);
- if (name.equals(actionName)) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- return false;
- }
- boolean retval = aa.doAccessibleAction(index);
- return retval;
- }
- }, ac);
- }
-
- /* ===== AT utility methods ===== */
-
- /**
- * Sets the contents of an AccessibleContext that
- * implements AccessibleEditableText with the
- * specified text string.
- * Returns whether successful.
- */
- private boolean setTextContents(final AccessibleContext ac, final String text) {
- debugString("setTextContents: ac = "+ac+"; text = "+text);
-
- if (! (ac instanceof AccessibleEditableText)) {
- debugString(" ac not instanceof AccessibleEditableText: "+ac);
- return false;
- }
- if (text == null) {
- debugString(" text is null");
- return false;
- }
-
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- // check whether the text field is editable
- AccessibleStateSet ass = ac.getAccessibleStateSet();
- if (!ass.contains(AccessibleState.ENABLED)) {
- return false;
- }
- ((AccessibleEditableText) ac).setTextContents(text);
- return true;
- }
- }, ac);
- }
-
- /**
- * Returns the Accessible Context of an Internal Frame object that is
- * the ancestor of a given object. If the object is an Internal Frame
- * object or an Internal Frame ancestor object was found, returns the
- * object's AccessibleContext.
- * If there is no ancestor object that has an Accessible Role of
- * Internal Frame, returns (AccessibleContext)0.
- */
- private AccessibleContext getInternalFrame (AccessibleContext ac) {
- return getParentWithRole(ac, AccessibleRole.INTERNAL_FRAME.toString());
- }
-
- /**
- * Returns the Accessible Context for the top level object in
- * a Java Window. This is same Accessible Context that is obtained
- * from GetAccessibleContextFromHWND for that window. Returns
- * (AccessibleContext)0 on error.
- */
- private AccessibleContext getTopLevelObject (final AccessibleContext ac) {
- debugString("getTopLevelObject; ac = "+ac);
- if (ac == null) {
- return null;
- }
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- if (ac.getAccessibleRole() == AccessibleRole.DIALOG) {
- // return the dialog, not the parent window
- return ac;
- }
-
- Accessible parent = ac.getAccessibleParent();
- if (parent == null) {
- return ac;
- }
- Accessible tmp = parent;
- while (tmp != null && tmp.getAccessibleContext() != null) {
- AccessibleContext ac2 = tmp.getAccessibleContext();
- if (ac2 != null && ac2.getAccessibleRole() == AccessibleRole.DIALOG) {
- // return the dialog, not the parent window
- return ac2;
- }
- parent = tmp;
- tmp = parent.getAccessibleContext().getAccessibleParent();
- }
- return parent.getAccessibleContext();
- }
- }, ac);
- }
-
- /**
- * Returns the parent AccessibleContext that has the specified AccessibleRole.
- * Returns null on error or if the AccessibleContext does not exist.
- */
- private AccessibleContext getParentWithRole (final AccessibleContext ac,
- final String roleName) {
- debugString("getParentWithRole; ac = "+ac);
- debugString("role = "+roleName);
- if (ac == null || roleName == null) {
- return null;
- }
-
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- AccessibleRole role = AccessBridge.this.accessibleRoleMap.get(roleName);
- if (role == null) {
- return ac;
- }
-
- Accessible parent = ac.getAccessibleParent();
- if (parent == null && ac.getAccessibleRole() == role) {
- return ac;
- }
-
- Accessible tmp = parent;
- AccessibleContext tmp_ac = null;
-
- while (tmp != null && (tmp_ac = tmp.getAccessibleContext()) != null) {
- AccessibleRole ar = tmp_ac.getAccessibleRole();
- if (ar == role) {
- // found
- return tmp_ac;
- }
- parent = tmp;
- tmp = parent.getAccessibleContext().getAccessibleParent();
- }
- // not found
- return null;
- }
- }, ac);
- }
-
- /**
- * Returns the parent AccessibleContext that has the specified AccessibleRole.
- * Otherwise, returns the top level object for the Java Window.
- * Returns (AccessibleContext)0 on error.
- */
- private AccessibleContext getParentWithRoleElseRoot (AccessibleContext ac,
- String roleName) {
- AccessibleContext retval = getParentWithRole(ac, roleName);
- if (retval == null) {
- retval = getTopLevelObject(ac);
- }
- return retval;
- }
-
- /**
- * Returns how deep in the object hierarchy a given object is.
- * The top most object in the object hierarchy has an object depth of 0.
- * Returns -1 on error.
- */
- private int getObjectDepth(final AccessibleContext ac) {
- debugString("getObjectDepth: ac = "+ac);
-
- if (ac == null) {
- return -1;
- }
- return InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- int count = 0;
- Accessible parent = ac.getAccessibleParent();
- if (parent == null) {
- return count;
- }
- Accessible tmp = parent;
- while (tmp != null && tmp.getAccessibleContext() != null) {
- parent = tmp;
- tmp = parent.getAccessibleContext().getAccessibleParent();
- count++;
- }
- return count;
- }
- }, ac);
- }
-
- /**
- * Returns the Accessible Context of the current ActiveDescendent of an object.
- * Returns (AccessibleContext)0 on error.
- */
- private AccessibleContext getActiveDescendent (final AccessibleContext ac) {
- debugString("getActiveDescendent: ac = "+ac);
- if (ac == null) {
- return null;
- }
- // workaround for JTree bug where the only possible active
- // descendent is the JTree root
- final Accessible parent = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
- @Override
- public Accessible call() throws Exception {
- return ac.getAccessibleParent();
- }
- }, ac);
-
- if (parent != null) {
- Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
- @Override
- public Accessible call() throws Exception {
- int indexInParent = ac.getAccessibleIndexInParent();
- return parent.getAccessibleContext().getAccessibleChild(indexInParent);
- }
- }, ac);
-
- if (child instanceof JTree) {
- // return the selected node
- final JTree tree = (JTree)child;
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- return new AccessibleJTreeNode(tree,
- tree.getSelectionPath(),
- null);
- }
- }, child);
- }
- }
-
- return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- AccessibleSelection as = ac.getAccessibleSelection();
- if (as == null) {
- return null;
- }
- // assume single selection
- if (as.getAccessibleSelectionCount() != 1) {
- return null;
- }
- Accessible a = as.getAccessibleSelection(0);
- if (a == null) {
- return null;
- }
- return a.getAccessibleContext();
- }
- }, ac);
- }
-
-
- /**
- * Additional methods for Teton
- */
-
- /**
- * Gets the AccessibleName for a component based upon the JAWS algorithm.
- * Returns whether successful.
- *
- * Bug ID 4916682 - Implement JAWS AccessibleName policy
- */
- private String getJAWSAccessibleName(final AccessibleContext ac) {
- debugString("getJAWSAccessibleName");
- if (ac == null) {
- return null;
- }
- // placeholder
- return InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return ac.getAccessibleName();
- }
- }, ac);
- }
-
- /**
- * Request focus for a component. Returns whether successful;
- *
- * Bug ID 4944757 - requestFocus method needed
- */
- private boolean requestFocus(final AccessibleContext ac) {
- debugString("requestFocus");
- if (ac == null) {
- return false;
- }
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- AccessibleComponent acomp = ac.getAccessibleComponent();
- if (acomp == null) {
- return false;
- }
- acomp.requestFocus();
- return ac.getAccessibleStateSet().contains(AccessibleState.FOCUSED);
- }
- }, ac);
- }
-
- /**
- * Selects text between two indices. Selection includes the
- * text at the start index and the text at the end index. Returns
- * whether successful;
- *
- * Bug ID 4944758 - selectTextRange method needed
- */
- private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) {
- debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex);
- if (ac == null) {
- return false;
- }
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (!(at instanceof AccessibleEditableText)) {
- return false;
- }
- ((AccessibleEditableText) at).selectText(startIndex, endIndex);
-
- boolean result = at.getSelectionStart() == startIndex &&
- at.getSelectionEnd() == endIndex;
- return result;
- }
- }, ac);
- }
-
- /**
- * Set the caret to a text position. Returns whether successful;
- *
- * Bug ID 4944770 - setCaretPosition method needed
- */
- private boolean setCaretPosition(final AccessibleContext ac, final int position) {
- debugString("setCaretPosition: position = "+position);
- if (ac == null) {
- return false;
- }
- return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- AccessibleText at = ac.getAccessibleText();
- if (!(at instanceof AccessibleEditableText)) {
- return false;
- }
- ((AccessibleEditableText) at).selectText(position, position);
- return at.getCaretPosition() == position;
- }
- }, ac);
- }
-
- /**
- * Gets the number of visible children of an AccessibleContext.
- *
- * Bug ID 4944762- getVisibleChildren for list-like components needed
- */
- private int _visibleChildrenCount;
- private AccessibleContext _visibleChild;
- private int _currentVisibleIndex;
- private boolean _foundVisibleChild;
-
- private int getVisibleChildrenCount(AccessibleContext ac) {
- debugString("getVisibleChildrenCount");
- if (ac == null) {
- return -1;
- }
- _visibleChildrenCount = 0;
- _getVisibleChildrenCount(ac);
- debugString(" _visibleChildrenCount = "+_visibleChildrenCount);
- return _visibleChildrenCount;
- }
-
- /*
- * Recursively descends AccessibleContext and gets the number
- * of visible children
- */
- private void _getVisibleChildrenCount(final AccessibleContext ac) {
- if (ac == null)
- return;
- int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac.getAccessibleChildrenCount();
- }
- }, ac);
- for (int i = 0; i < numChildren; i++) {
- final int idx = i;
- final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = ac.getAccessibleChild(idx);
- if (a != null)
- return a.getAccessibleContext();
- else
- return null;
- }
- }, ac);
- if ( ac2 == null ||
- (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
- }
- }, ac))
- ) {
- continue;
- }
- _visibleChildrenCount++;
-
- if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac2.getAccessibleChildrenCount();
- }
- }, ac) > 0 ) {
- _getVisibleChildrenCount(ac2);
- }
- }
- }
-
- /**
- * Gets the visible child of an AccessibleContext at the
- * specified index
- *
- * Bug ID 4944762- getVisibleChildren for list-like components needed
- */
- private AccessibleContext getVisibleChild(AccessibleContext ac, int index) {
- debugString("getVisibleChild: index = "+index);
- if (ac == null) {
- return null;
- }
- _visibleChild = null;
- _currentVisibleIndex = 0;
- _foundVisibleChild = false;
- _getVisibleChild(ac, index);
-
- if (_visibleChild != null) {
- debugString( " getVisibleChild: found child = " +
- InvocationUtils.invokeAndWait(new Callable<String>() {
- @Override
- public String call() throws Exception {
- return AccessBridge.this._visibleChild.getAccessibleName();
- }
- }, ac) );
- }
- return _visibleChild;
- }
-
- /*
- * Recursively searchs AccessibleContext and finds the visible component
- * at the specified index
- */
- private void _getVisibleChild(final AccessibleContext ac, final int index) {
- if (_visibleChild != null) {
- return;
- }
-
- int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac.getAccessibleChildrenCount();
- }
- }, ac);
- for (int i = 0; i < numChildren; i++) {
- final int idx=i;
- final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
- @Override
- public AccessibleContext call() throws Exception {
- Accessible a = ac.getAccessibleChild(idx);
- if (a == null)
- return null;
- else
- return a.getAccessibleContext();
- }
- }, ac);
- if (ac2 == null ||
- (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
- }
- }, ac))) {
- continue;
- }
- if (!_foundVisibleChild && _currentVisibleIndex == index) {
- _visibleChild = ac2;
- _foundVisibleChild = true;
- return;
- }
- _currentVisibleIndex++;
-
- if ( InvocationUtils.invokeAndWait(new Callable<Integer>() {
- @Override
- public Integer call() throws Exception {
- return ac2.getAccessibleChildrenCount();
- }
- }, ac) > 0 ) {
- _getVisibleChild(ac2, index);
- }
- }
- }
-
-
- /* ===== Java object memory management code ===== */
-
- /**
- * Class to track object references to ensure the
- * Java VM doesn't garbage collect them
- */
- private class ObjectReferences {
-
- private class Reference {
- private int value;
-
- Reference(int i) {
- value = i;
- }
-
- public String toString() {
- return ("refCount: " + value);
- }
- }
-
- /**
- * table object references, to keep 'em from being garbage collected
- */
- private ConcurrentHashMap<Object,Reference> refs;
-
- /**
- * Constructor
- */
- ObjectReferences() {
- refs = new ConcurrentHashMap<>(4);
- }
-
- /**
- * Debugging: dump the contents of ObjectReferences' refs Hashtable
- */
- String dump() {
- return refs.toString();
- }
-
- /**
- * Increment ref count; set to 1 if we have no references for it
- */
- void increment(Object o) {
- if (o == null){
- debugString("ObjectReferences::increment - Passed in object is null");
- return;
- }
-
- if (refs.containsKey(o)) {
- (refs.get(o)).value++;
- } else {
- refs.put(o, new Reference(1));
- }
- }
-
- /**
- * Decrement ref count; remove if count drops to 0
- */
- void decrement(Object o) {
- Reference aRef = refs.get(o);
- if (aRef != null) {
- aRef.value--;
- if (aRef.value == 0) {
- refs.remove(o);
- } else if (aRef.value < 0) {
- debugString("ERROR: decrementing reference count below 0");
- }
- } else {
- debugString("ERROR: object to decrement not in ObjectReferences table");
- }
- }
-
- }
-
- /* ===== event handling code ===== */
-
- /**
- * native method for handling property change events
- */
- private native void propertyCaretChange(PropertyChangeEvent e,
- AccessibleContext src,
- int oldValue, int newValue);
- private native void propertyDescriptionChange(PropertyChangeEvent e,
- AccessibleContext src,
- String oldValue, String newValue);
- private native void propertyNameChange(PropertyChangeEvent e,
- AccessibleContext src,
- String oldValue, String newValue);
- private native void propertySelectionChange(PropertyChangeEvent e,
- AccessibleContext src);
- private native void propertyStateChange(PropertyChangeEvent e,
- AccessibleContext src,
- String oldValue, String newValue);
- private native void propertyTextChange(PropertyChangeEvent e,
- AccessibleContext src);
- private native void propertyValueChange(PropertyChangeEvent e,
- AccessibleContext src,
- String oldValue, String newValue);
- private native void propertyVisibleDataChange(PropertyChangeEvent e,
- AccessibleContext src);
- private native void propertyChildChange(PropertyChangeEvent e,
- AccessibleContext src,
- AccessibleContext oldValue,
- AccessibleContext newValue);
- private native void propertyActiveDescendentChange(PropertyChangeEvent e,
- AccessibleContext src,
- AccessibleContext oldValue,
- AccessibleContext newValue);
-
- private native void javaShutdown();
-
- /**
- * native methods for handling focus events
- */
- private native void focusGained(FocusEvent e, AccessibleContext src);
- private native void focusLost(FocusEvent e, AccessibleContext src);
-
- /**
- * native method for handling caret events
- */
- private native void caretUpdate(CaretEvent e, AccessibleContext src);
-
- /**
- * native methods for handling mouse events
- */
- private native void mouseClicked(MouseEvent e, AccessibleContext src);
- private native void mouseEntered(MouseEvent e, AccessibleContext src);
- private native void mouseExited(MouseEvent e, AccessibleContext src);
- private native void mousePressed(MouseEvent e, AccessibleContext src);
- private native void mouseReleased(MouseEvent e, AccessibleContext src);
-
- /**
- * native methods for handling menu & popupMenu events
- */
- private native void menuCanceled(MenuEvent e, AccessibleContext src);
- private native void menuDeselected(MenuEvent e, AccessibleContext src);
- private native void menuSelected(MenuEvent e, AccessibleContext src);
- private native void popupMenuCanceled(PopupMenuEvent e, AccessibleContext src);
- private native void popupMenuWillBecomeInvisible(PopupMenuEvent e,
- AccessibleContext src);
- private native void popupMenuWillBecomeVisible(PopupMenuEvent e,
- AccessibleContext src);
-
- /* ===== event definitions ===== */
-
- private static final long PROPERTY_CHANGE_EVENTS = 1;
- private static final long FOCUS_GAINED_EVENTS = 2;
- private static final long FOCUS_LOST_EVENTS = 4;
- private static final long FOCUS_EVENTS = (FOCUS_GAINED_EVENTS | FOCUS_LOST_EVENTS);
-
- private static final long CARET_UPATE_EVENTS = 8;
- private static final long CARET_EVENTS = CARET_UPATE_EVENTS;
-
- private static final long MOUSE_CLICKED_EVENTS = 16;
- private static final long MOUSE_ENTERED_EVENTS = 32;
- private static final long MOUSE_EXITED_EVENTS = 64;
- private static final long MOUSE_PRESSED_EVENTS = 128;
- private static final long MOUSE_RELEASED_EVENTS = 256;
- private static final long MOUSE_EVENTS = (MOUSE_CLICKED_EVENTS | MOUSE_ENTERED_EVENTS |
- MOUSE_EXITED_EVENTS | MOUSE_PRESSED_EVENTS |
- MOUSE_RELEASED_EVENTS);
-
- private static final long MENU_CANCELED_EVENTS = 512;
- private static final long MENU_DESELECTED_EVENTS = 1024;
- private static final long MENU_SELECTED_EVENTS = 2048;
- private static final long MENU_EVENTS = (MENU_CANCELED_EVENTS | MENU_DESELECTED_EVENTS |
- MENU_SELECTED_EVENTS);
-
- private static final long POPUPMENU_CANCELED_EVENTS = 4096;
- private static final long POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS = 8192;
- private static final long POPUPMENU_WILL_BECOME_VISIBLE_EVENTS = 16384;
- private static final long POPUPMENU_EVENTS = (POPUPMENU_CANCELED_EVENTS |
- POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS |
- POPUPMENU_WILL_BECOME_VISIBLE_EVENTS);
-
- /* These use their own numbering scheme, to ensure sufficient expansion room */
- private static final long PROPERTY_NAME_CHANGE_EVENTS = 1;
- private static final long PROPERTY_DESCRIPTION_CHANGE_EVENTS = 2;
- private static final long PROPERTY_STATE_CHANGE_EVENTS = 4;
- private static final long PROPERTY_VALUE_CHANGE_EVENTS = 8;
- private static final long PROPERTY_SELECTION_CHANGE_EVENTS = 16;
- private static final long PROPERTY_TEXT_CHANGE_EVENTS = 32;
- private static final long PROPERTY_CARET_CHANGE_EVENTS = 64;
- private static final long PROPERTY_VISIBLEDATA_CHANGE_EVENTS = 128;
- private static final long PROPERTY_CHILD_CHANGE_EVENTS = 256;
- private static final long PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS = 512;
-
-
- private static final long PROPERTY_EVENTS = (PROPERTY_NAME_CHANGE_EVENTS |
- PROPERTY_DESCRIPTION_CHANGE_EVENTS |
- PROPERTY_STATE_CHANGE_EVENTS |
- PROPERTY_VALUE_CHANGE_EVENTS |
- PROPERTY_SELECTION_CHANGE_EVENTS |
- PROPERTY_TEXT_CHANGE_EVENTS |
- PROPERTY_CARET_CHANGE_EVENTS |
- PROPERTY_VISIBLEDATA_CHANGE_EVENTS |
- PROPERTY_CHILD_CHANGE_EVENTS |
- PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS);
-
- /**
- * The EventHandler class listens for Java events and
- * forwards them to the AT
- */
- private class EventHandler implements PropertyChangeListener,
- FocusListener, CaretListener,
- MenuListener, PopupMenuListener,
- MouseListener, WindowListener,
- ChangeListener {
-
- private AccessBridge accessBridge;
- private long javaEventMask = 0;
- private long accessibilityEventMask = 0;
-
- EventHandler(AccessBridge bridge) {
- accessBridge = bridge;
-
- // Register to receive WINDOW_OPENED and WINDOW_CLOSED
- // events. Add the event source as a native window
- // handler is it implements NativeWindowHandler.
- // SwingEventMonitor.addWindowListener(this);
- }
-
- // --------- Event Notification Registration methods
-
- /**
- * Invoked the first time a window is made visible.
- */
- public void windowOpened(WindowEvent e) {
- // If the window is a NativeWindowHandler, add it.
- Object o = null;
- if (e != null)
- o = e.getSource();
- if (o instanceof NativeWindowHandler) {
- addNativeWindowHandler((NativeWindowHandler)o);
- }
- }
-
- /**
- * Invoked when the user attempts to close the window
- * from the window's system menu. If the program does not
- * explicitly hide or dispose the window while processing
- * this event, the window close operation will be canceled.
- */
- public void windowClosing(WindowEvent e) {}
-
- /**
- * Invoked when a window has been closed as the result
- * of calling dispose on the window.
- */
- public void windowClosed(WindowEvent e) {
- // If the window is a NativeWindowHandler, remove it.
- Object o = null;
- if (e != null)
- o = e.getSource();
- if (o instanceof NativeWindowHandler) {
- removeNativeWindowHandler((NativeWindowHandler)o);
- }
- }
-
- /**
- * Invoked when a window is changed from a normal to a
- * minimized state. For many platforms, a minimized window
- * is displayed as the icon specified in the window's
- * iconImage property.
- * @see java.awt.Frame#setIconImage
- */
- public void windowIconified(WindowEvent e) {}
-
- /**
- * Invoked when a window is changed from a minimized
- * to a normal state.
- */
- public void windowDeiconified(WindowEvent e) {}
-
- /**
- * Invoked when the Window is set to be the active Window. Only a Frame or
- * a Dialog can be the active Window. The native windowing system may
- * denote the active Window or its children with special decorations, such
- * as a highlighted title bar. The active Window is always either the
- * focused Window, or the first Frame or Dialog that is an owner of the
- * focused Window.
- */
- public void windowActivated(WindowEvent e) {}
-
- /**
- * Invoked when a Window is no longer the active Window. Only a Frame or a
- * Dialog can be the active Window. The native windowing system may denote
- * the active Window or its children with special decorations, such as a
- * highlighted title bar. The active Window is always either the focused
- * Window, or the first Frame or Dialog that is an owner of the focused
- * Window.
- */
- public void windowDeactivated(WindowEvent e) {}
-
- /**
- * Turn on event monitoring for the event type passed in
- * If necessary, add the appropriate event listener (if
- * no other event of that type is being listened for)
- */
- void addJavaEventNotification(long type) {
- long newEventMask = javaEventMask | type;
- /*
- if ( ((javaEventMask & PROPERTY_EVENTS) == 0) &&
- ((newEventMask & PROPERTY_EVENTS) != 0) ) {
- AccessibilityEventMonitor.addPropertyChangeListener(this);
- }
- */
- if ( ((javaEventMask & FOCUS_EVENTS) == 0) &&
- ((newEventMask & FOCUS_EVENTS) != 0) ) {
- SwingEventMonitor.addFocusListener(this);
- }
- if ( ((javaEventMask & CARET_EVENTS) == 0) &&
- ((newEventMask & CARET_EVENTS) != 0) ) {
- SwingEventMonitor.addCaretListener(this);
- }
- if ( ((javaEventMask & MOUSE_EVENTS) == 0) &&
- ((newEventMask & MOUSE_EVENTS) != 0) ) {
- SwingEventMonitor.addMouseListener(this);
- }
- if ( ((javaEventMask & MENU_EVENTS) == 0) &&
- ((newEventMask & MENU_EVENTS) != 0) ) {
- SwingEventMonitor.addMenuListener(this);
- SwingEventMonitor.addPopupMenuListener(this);
- }
- if ( ((javaEventMask & POPUPMENU_EVENTS) == 0) &&
- ((newEventMask & POPUPMENU_EVENTS) != 0) ) {
- SwingEventMonitor.addPopupMenuListener(this);
- }
-
- javaEventMask = newEventMask;
- }
-
- /**
- * Turn off event monitoring for the event type passed in
- * If necessary, remove the appropriate event listener (if
- * no other event of that type is being listened for)
- */
- void removeJavaEventNotification(long type) {
- long newEventMask = javaEventMask & (~type);
- /*
- if ( ((javaEventMask & PROPERTY_EVENTS) != 0) &&
- ((newEventMask & PROPERTY_EVENTS) == 0) ) {
- AccessibilityEventMonitor.removePropertyChangeListener(this);
- }
- */
- if (((javaEventMask & FOCUS_EVENTS) != 0) &&
- ((newEventMask & FOCUS_EVENTS) == 0)) {
- SwingEventMonitor.removeFocusListener(this);
- }
- if (((javaEventMask & CARET_EVENTS) != 0) &&
- ((newEventMask & CARET_EVENTS) == 0)) {
- SwingEventMonitor.removeCaretListener(this);
- }
- if (((javaEventMask & MOUSE_EVENTS) == 0) &&
- ((newEventMask & MOUSE_EVENTS) != 0)) {
- SwingEventMonitor.removeMouseListener(this);
- }
- if (((javaEventMask & MENU_EVENTS) == 0) &&
- ((newEventMask & MENU_EVENTS) != 0)) {
- SwingEventMonitor.removeMenuListener(this);
- }
- if (((javaEventMask & POPUPMENU_EVENTS) == 0) &&
- ((newEventMask & POPUPMENU_EVENTS) != 0)) {
- SwingEventMonitor.removePopupMenuListener(this);
- }
-
- javaEventMask = newEventMask;
- }
-
- /**
- * Turn on event monitoring for the event type passed in
- * If necessary, add the appropriate event listener (if
- * no other event of that type is being listened for)
- */
- void addAccessibilityEventNotification(long type) {
- long newEventMask = accessibilityEventMask | type;
- if ( ((accessibilityEventMask & PROPERTY_EVENTS) == 0) &&
- ((newEventMask & PROPERTY_EVENTS) != 0) ) {
- AccessibilityEventMonitor.addPropertyChangeListener(this);
- }
- accessibilityEventMask = newEventMask;
- }
-
- /**
- * Turn off event monitoring for the event type passed in
- * If necessary, remove the appropriate event listener (if
- * no other event of that type is being listened for)
- */
- void removeAccessibilityEventNotification(long type) {
- long newEventMask = accessibilityEventMask & (~type);
- if ( ((accessibilityEventMask & PROPERTY_EVENTS) != 0) &&
- ((newEventMask & PROPERTY_EVENTS) == 0) ) {
- AccessibilityEventMonitor.removePropertyChangeListener(this);
- }
- accessibilityEventMask = newEventMask;
- }
-
- /**
- * ------- property change event glue
- */
- // This is invoked on the EDT , as
- public void propertyChange(PropertyChangeEvent e) {
-
- accessBridge.debugString("propertyChange(" + e.toString() + ") called");
-
- if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) {
- Object o = e.getSource();
- AccessibleContext ac;
-
- if (o instanceof AccessibleContext) {
- ac = (AccessibleContext) o;
- } else {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a == null)
- return;
- else
- ac = a.getAccessibleContext();
- }
- if (ac != null) {
- InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext());
-
- accessBridge.debugString("AccessibleContext: " + ac);
- String propertyName = e.getPropertyName();
-
- if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
- int oldValue = 0;
- int newValue = 0;
-
- if (e.getOldValue() instanceof Integer) {
- oldValue = ((Integer) e.getOldValue()).intValue();
- }
- if (e.getNewValue() instanceof Integer) {
- newValue = ((Integer) e.getNewValue()).intValue();
- }
- accessBridge.debugString(" - about to call propertyCaretChange()");
- accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue);
- accessBridge.propertyCaretChange(e, ac, oldValue, newValue);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) {
- String oldValue = null;
- String newValue = null;
-
- if (e.getOldValue() != null) {
- oldValue = e.getOldValue().toString();
- }
- if (e.getNewValue() != null) {
- newValue = e.getNewValue().toString();
- }
- accessBridge.debugString(" - about to call propertyDescriptionChange()");
- accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue);
- accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) {
- String oldValue = null;
- String newValue = null;
-
- if (e.getOldValue() != null) {
- oldValue = e.getOldValue().toString();
- }
- if (e.getNewValue() != null) {
- newValue = e.getNewValue().toString();
- }
- accessBridge.debugString(" - about to call propertyNameChange()");
- accessBridge.debugString(" old value: " + oldValue + " new value: " + newValue);
- accessBridge.propertyNameChange(e, ac, oldValue, newValue);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) {
- accessBridge.debugString(" - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource());
-
- accessBridge.propertySelectionChange(e, ac);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_STATE_PROPERTY) == 0) {
- String oldValue = null;
- String newValue = null;
-
- // Localization fix requested by Oliver for EA-1
- if (e.getOldValue() != null) {
- AccessibleState oldState = (AccessibleState) e.getOldValue();
- oldValue = oldState.toDisplayString(Locale.US);
- }
- if (e.getNewValue() != null) {
- AccessibleState newState = (AccessibleState) e.getNewValue();
- newValue = newState.toDisplayString(Locale.US);
- }
-
- accessBridge.debugString(" - about to call propertyStateChange()");
- accessBridge.propertyStateChange(e, ac, oldValue, newValue);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) {
- accessBridge.debugString(" - about to call propertyTextChange()");
- accessBridge.propertyTextChange(e, ac);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) { // strings 'cause of floating point, etc.
- String oldValue = null;
- String newValue = null;
-
- if (e.getOldValue() != null) {
- oldValue = e.getOldValue().toString();
- }
- if (e.getNewValue() != null) {
- newValue = e.getNewValue().toString();
- }
- accessBridge.debugString(" - about to call propertyDescriptionChange()");
- accessBridge.propertyValueChange(e, ac, oldValue, newValue);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) {
- accessBridge.propertyVisibleDataChange(e, ac);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
- AccessibleContext oldAC = null;
- AccessibleContext newAC = null;
- Accessible a;
-
- if (e.getOldValue() instanceof AccessibleContext) {
- oldAC = (AccessibleContext) e.getOldValue();
- InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
- }
- if (e.getNewValue() instanceof AccessibleContext) {
- newAC = (AccessibleContext) e.getNewValue();
- InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
- }
- accessBridge.debugString(" - about to call propertyChildChange()");
- accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC);
- accessBridge.propertyChildChange(e, ac, oldAC, newAC);
-
- } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) {
- handleActiveDescendentEvent(e, ac);
- }
- }
- }
- }
-
- /*
- * Handle an ActiveDescendent PropertyChangeEvent. This
- * method works around a JTree bug where ActiveDescendent
- * PropertyChangeEvents have the wrong parent.
- */
- private AccessibleContext prevAC = null; // previous AccessibleContext
-
- private void handleActiveDescendentEvent(PropertyChangeEvent e,
- AccessibleContext ac) {
- if (e == null || ac == null)
- return;
- AccessibleContext oldAC = null;
- AccessibleContext newAC = null;
- Accessible a;
-
- // get the old active descendent
- if (e.getOldValue() instanceof Accessible) {
- oldAC = ((Accessible) e.getOldValue()).getAccessibleContext();
- } else if (e.getOldValue() instanceof Component) {
- a = Translator.getAccessible(e.getOldValue());
- if (a != null) {
- oldAC = a.getAccessibleContext();
- }
- }
- if (oldAC != null) {
- Accessible parent = oldAC.getAccessibleParent();
- if (parent instanceof JTree) {
- // use the previous AccessibleJTreeNode
- oldAC = prevAC;
- }
- }
-
- // get the new active descendent
- if (e.getNewValue() instanceof Accessible) {
- newAC = ((Accessible) e.getNewValue()).getAccessibleContext();
- } else if (e.getNewValue() instanceof Component) {
- a = Translator.getAccessible(e.getNewValue());
- if (a != null) {
- newAC = a.getAccessibleContext();
- }
- }
- if (newAC != null) {
- Accessible parent = newAC.getAccessibleParent();
- if (parent instanceof JTree) {
- // use a new AccessibleJTreeNode with the right parent
- JTree tree = (JTree)parent;
- newAC = new AccessibleJTreeNode(tree,
- tree.getSelectionPath(),
- null);
- }
- }
- prevAC = newAC;
-
- accessBridge.debugString(" - about to call propertyActiveDescendentChange()");
- accessBridge.debugString(" AC: " + ac);
- accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC);
-
- InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
- InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
- accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC);
- }
-
- /**
- * ------- focus event glue
- */
- private boolean stateChangeListenerAdded = false;
-
- public void focusGained(FocusEvent e) {
- processFocusGained();
- }
-
- public void stateChanged(ChangeEvent e) {
- processFocusGained();
- }
-
- private void processFocusGained() {
- Component focusOwner = KeyboardFocusManager.
- getCurrentKeyboardFocusManager().getFocusOwner();
- if (focusOwner == null) {
- return;
- }
-
- // Only menus and popup selections are handled by the JRootPane.
- if (focusOwner instanceof JRootPane) {
- MenuElement [] path =
- MenuSelectionManager.defaultManager().getSelectedPath();
- if (path.length > 1) {
- Component penult = path[path.length-2].getComponent();
- Component last = path[path.length-1].getComponent();
-
- if (last instanceof JPopupMenu) {
- // This is a popup with nothing in the popup
- // selected. The menu itself is selected.
- FocusEvent e = new FocusEvent(penult, FocusEvent.FOCUS_GAINED);
- AccessibleContext context = penult.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(penult));
- accessBridge.focusGained(e, context);
- } else if (penult instanceof JPopupMenu) {
- // This is a popup with an item selected
- FocusEvent e =
- new FocusEvent(last, FocusEvent.FOCUS_GAINED);
- accessBridge.debugString(" - about to call focusGained()");
- AccessibleContext focusedAC = last.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last));
- accessBridge.debugString(" AC: " + focusedAC);
- accessBridge.focusGained(e, focusedAC);
- }
- }
- } else {
- // The focus owner has the selection.
- if (focusOwner instanceof Accessible) {
- FocusEvent e = new FocusEvent(focusOwner,
- FocusEvent.FOCUS_GAINED);
- accessBridge.debugString(" - about to call focusGained()");
- AccessibleContext focusedAC = focusOwner.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner));
- accessBridge.debugString(" AC: " + focusedAC);
- accessBridge.focusGained(e, focusedAC);
- }
- }
- }
-
- public void focusLost(FocusEvent e) {
- if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- accessBridge.debugString(" - about to call focusLost()");
- accessBridge.debugString(" AC: " + a.getAccessibleContext());
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.focusLost(e, context);
- }
- }
- }
-
- /**
- * ------- caret event glue
- */
- public void caretUpdate(CaretEvent e) {
- if (e != null && (javaEventMask & CARET_UPATE_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.caretUpdate(e, context);
- }
- }
- }
-
- /**
- * ------- mouse event glue
- */
-
- public void mouseClicked(MouseEvent e) {
- if (e != null && (javaEventMask & MOUSE_CLICKED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.mouseClicked(e, context);
- }
- }
- }
-
- public void mouseEntered(MouseEvent e) {
- if (e != null && (javaEventMask & MOUSE_ENTERED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.mouseEntered(e, context);
- }
- }
- }
-
- public void mouseExited(MouseEvent e) {
- if (e != null && (javaEventMask & MOUSE_EXITED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.mouseExited(e, context);
- }
- }
- }
-
- public void mousePressed(MouseEvent e) {
- if (e != null && (javaEventMask & MOUSE_PRESSED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.mousePressed(e, context);
- }
- }
- }
-
- public void mouseReleased(MouseEvent e) {
- if (e != null && (javaEventMask & MOUSE_RELEASED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.mouseReleased(e, context);
- }
- }
- }
-
- /**
- * ------- menu event glue
- */
- public void menuCanceled(MenuEvent e) {
- if (e != null && (javaEventMask & MENU_CANCELED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.menuCanceled(e, context);
- }
- }
- }
-
- public void menuDeselected(MenuEvent e) {
- if (e != null && (javaEventMask & MENU_DESELECTED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.menuDeselected(e, context);
- }
- }
- }
-
- public void menuSelected(MenuEvent e) {
- if (e != null && (javaEventMask & MENU_SELECTED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.menuSelected(e, context);
- }
- }
- }
-
- public void popupMenuCanceled(PopupMenuEvent e) {
- if (e != null && (javaEventMask & POPUPMENU_CANCELED_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.popupMenuCanceled(e, context);
- }
- }
- }
-
- public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
- if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.popupMenuWillBecomeInvisible(e, context);
- }
- }
- }
-
- public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
- if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_VISIBLE_EVENTS) != 0) {
- Accessible a = Translator.getAccessible(e.getSource());
- if (a != null) {
- AccessibleContext context = a.getAccessibleContext();
- InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
- accessBridge.popupMenuWillBecomeVisible(e, context);
- }
- }
- }
-
- } // End of EventHandler Class
-
- // --------- Event Notification Registration methods
-
- /**
- * Wrapper method around eventHandler.addJavaEventNotification()
- */
- private void addJavaEventNotification(final long type) {
- EventQueue.invokeLater(new Runnable() {
- public void run(){
- eventHandler.addJavaEventNotification(type);
- }
- });
- }
-
- /**
- * Wrapper method around eventHandler.removeJavaEventNotification()
- */
- private void removeJavaEventNotification(final long type) {
- EventQueue.invokeLater(new Runnable() {
- public void run(){
- eventHandler.removeJavaEventNotification(type);
- }
- });
- }
-
-
- /**
- * Wrapper method around eventHandler.addAccessibilityEventNotification()
- */
- private void addAccessibilityEventNotification(final long type) {
- EventQueue.invokeLater(new Runnable() {
- public void run(){
- eventHandler.addAccessibilityEventNotification(type);
- }
- });
- }
-
- /**
- * Wrapper method around eventHandler.removeAccessibilityEventNotification()
- */
- private void removeAccessibilityEventNotification(final long type) {
- EventQueue.invokeLater(new Runnable() {
- public void run(){
- eventHandler.removeAccessibilityEventNotification(type);
- }
- });
- }
-
- /**
- ******************************************************
- * All AccessibleRoles
- *
- * We shouldn't have to do this since it requires us
- * to synchronize the allAccessibleRoles array when
- * the AccessibleRoles class interface changes. However,
- * there is no Accessibility API method to get all
- * AccessibleRoles
- ******************************************************
- */
- private AccessibleRole [] allAccessibleRoles = {
- /**
- * Object is used to alert the user about something.
- */
- AccessibleRole.ALERT,
-
- /**
- * The header for a column of data.
- */
- AccessibleRole.COLUMN_HEADER,
-
- /**
- * Object that can be drawn into and is used to trap
- * events.
- * @see #FRAME
- * @see #GLASS_PANE
- * @see #LAYERED_PANE
- */
- AccessibleRole.CANVAS,
-
- /**
- * A list of choices the user can select from. Also optionally
- * allows the user to enter a choice of their own.
- */
- AccessibleRole.COMBO_BOX,
-
- /**
- * An iconified internal frame in a DESKTOP_PANE.
- * @see #DESKTOP_PANE
- * @see #INTERNAL_FRAME
- */
- AccessibleRole.DESKTOP_ICON,
-
- /**
- * A frame-like object that is clipped by a desktop pane. The
- * desktop pane, internal frame, and desktop icon objects are
- * often used to create multiple document interfaces within an
- * application.
- * @see #DESKTOP_ICON
- * @see #DESKTOP_PANE
- * @see #FRAME
- */
- AccessibleRole.INTERNAL_FRAME,
-
- /**
- * A pane that supports internal frames and
- * iconified versions of those internal frames.
- * @see #DESKTOP_ICON
- * @see #INTERNAL_FRAME
- */
- AccessibleRole.DESKTOP_PANE,
-
- /**
- * A specialized pane whose primary use is inside a DIALOG
- * @see #DIALOG
- */
- AccessibleRole.OPTION_PANE,
-
- /**
- * A top level window with no title or border.
- * @see #FRAME
- * @see #DIALOG
- */
- AccessibleRole.WINDOW,
-
- /**
- * A top level window with a title bar, border, menu bar, etc. It is
- * often used as the primary window for an application.
- * @see #DIALOG
- * @see #CANVAS
- * @see #WINDOW
- */
- AccessibleRole.FRAME,
-
- /**
- * A top level window with title bar and a border. A dialog is similar
- * to a frame, but it has fewer properties and is often used as a
- * secondary window for an application.
- * @see #FRAME
- * @see #WINDOW
- */
- AccessibleRole.DIALOG,
-
- /**
- * A specialized dialog that lets the user choose a color.
- */
- AccessibleRole.COLOR_CHOOSER,
-
-
- /**
- * A pane that allows the user to navigate through
- * and select the contents of a directory. May be used
- * by a file chooser.
- * @see #FILE_CHOOSER
- */
- AccessibleRole.DIRECTORY_PANE,
-
- /**
- * A specialized dialog that displays the files in the directory
- * and lets the user select a file, browse a different directory,
- * or specify a filename. May use the directory pane to show the
- * contents of a directory.
- * @see #DIRECTORY_PANE
- */
- AccessibleRole.FILE_CHOOSER,
-
- /**
- * An object that fills up space in a user interface. It is often
- * used in interfaces to tweak the spacing between components,
- * but serves no other purpose.
- */
- AccessibleRole.FILLER,
-
- /**
- * A hypertext anchor
- */
- // AccessibleRole.HYPERLINK,
-
- /**
- * A small fixed size picture, typically used to decorate components.
- */
- AccessibleRole.ICON,
-
- /**
- * An object used to present an icon or short string in an interface.
- */
- AccessibleRole.LABEL,
-
- /**
- * A specialized pane that has a glass pane and a layered pane as its
- * children.
- * @see #GLASS_PANE
- * @see #LAYERED_PANE
- */
- AccessibleRole.ROOT_PANE,
-
- /**
- * A pane that is guaranteed to be painted on top
- * of all panes beneath it.
- * @see #ROOT_PANE
- * @see #CANVAS
- */
- AccessibleRole.GLASS_PANE,
-
- /**
- * A specialized pane that allows its children to be drawn in layers,
- * providing a form of stacking order. This is usually the pane that
- * holds the menu bar as well as the pane that contains most of the
- * visual components in a window.
- * @see #GLASS_PANE
- * @see #ROOT_PANE
- */
- AccessibleRole.LAYERED_PANE,
-
- /**
- * An object that presents a list of objects to the user and allows the
- * user to select one or more of them. A list is usually contained
- * within a scroll pane.
- * @see #SCROLL_PANE
- * @see #LIST_ITEM
- */
- AccessibleRole.LIST,
-
- /**
- * An object that presents an element in a list. A list is usually
- * contained within a scroll pane.
- * @see #SCROLL_PANE
- * @see #LIST
- */
- AccessibleRole.LIST_ITEM,
-
- /**
- * An object usually drawn at the top of the primary dialog box of
- * an application that contains a list of menus the user can choose
- * from. For example, a menu bar might contain menus for "File,"
- * "Edit," and "Help."
- * @see #MENU
- * @see #POPUP_MENU
- * @see #LAYERED_PANE
- */
- AccessibleRole.MENU_BAR,
-
- /**
- * A temporary window that is usually used to offer the user a
- * list of choices, and then hides when the user selects one of
- * those choices.
- * @see #MENU
- * @see #MENU_ITEM
- */
- AccessibleRole.POPUP_MENU,
-
- /**
- * An object usually found inside a menu bar that contains a list
- * of actions the user can choose from. A menu can have any object
- * as its children, but most often they are menu items, other menus,
- * or rudimentary objects such as radio buttons, check boxes, or
- * separators. For example, an application may have an "Edit" menu
- * that contains menu items for "Cut" and "Paste."
- * @see #MENU_BAR
- * @see #MENU_ITEM
- * @see #SEPARATOR
- * @see #RADIO_BUTTON
- * @see #CHECK_BOX
- * @see #POPUP_MENU
- */
- AccessibleRole.MENU,
-
- /**
- * An object usually contained in a menu that presents an action
- * the user can choose. For example, the "Cut" menu item in an
- * "Edit" menu would be an action the user can select to cut the
- * selected area of text in a document.
- * @see #MENU_BAR
- * @see #SEPARATOR
- * @see #POPUP_MENU
- */
- AccessibleRole.MENU_ITEM,
-
- /**
- * An object usually contained in a menu to provide a visual
- * and logical separation of the contents in a menu. For example,
- * the "File" menu of an application might contain menu items for
- * "Open," "Close," and "Exit," and will place a separator between
- * "Close" and "Exit" menu items.
- * @see #MENU
- * @see #MENU_ITEM
- */
- AccessibleRole.SEPARATOR,
-
- /**
- * An object that presents a series of panels (or page tabs), one at a
- * time, through some mechanism provided by the object. The most common
- * mechanism is a list of tabs at the top of the panel. The children of
- * a page tab list are all page tabs.
- * @see #PAGE_TAB
- */
- AccessibleRole.PAGE_TAB_LIST,
-
- /**
- * An object that is a child of a page tab list. Its sole child is
- * the panel that is to be presented to the user when the user
- * selects the page tab from the list of tabs in the page tab list.
- * @see #PAGE_TAB_LIST
- */
- AccessibleRole.PAGE_TAB,
-
- /**
- * A generic container that is often used to group objects.
- */
- AccessibleRole.PANEL,
-
- /**
- * An object used to indicate how much of a task has been completed.
- */
- AccessibleRole.PROGRESS_BAR,
-
- /**
- * A text object used for passwords, or other places where the
- * text contents is not shown visibly to the user
- */
- AccessibleRole.PASSWORD_TEXT,
-
- /**
- * An object the user can manipulate to tell the application to do
- * something.
- * @see #CHECK_BOX
- * @see #TOGGLE_BUTTON
- * @see #RADIO_BUTTON
- */
- AccessibleRole.PUSH_BUTTON,
-
- /**
- * A specialized push button that can be checked or unchecked, but
- * does not provide a separate indicator for the current state.
- * @see #PUSH_BUTTON
- * @see #CHECK_BOX
- * @see #RADIO_BUTTON
- */
- AccessibleRole.TOGGLE_BUTTON,
-
- /**
- * A choice that can be checked or unchecked and provides a
- * separate indicator for the current state.
- * @see #PUSH_BUTTON
- * @see #TOGGLE_BUTTON
- * @see #RADIO_BUTTON
- */
- AccessibleRole.CHECK_BOX,
-
- /**
- * A specialized check box that will cause other radio buttons in the
- * same group to become unchecked when this one is checked.
- * @see #PUSH_BUTTON
- * @see #TOGGLE_BUTTON
- * @see #CHECK_BOX
- */
- AccessibleRole.RADIO_BUTTON,
-
- /**
- * The header for a row of data.
- */
- AccessibleRole.ROW_HEADER,
-
- /**
- * An object that allows a user to incrementally view a large amount
- * of information. Its children can include scroll bars and a viewport.
- * @see #SCROLL_BAR
- * @see #VIEWPORT
- */
- AccessibleRole.SCROLL_PANE,
-
- /**
- * An object usually used to allow a user to incrementally view a
- * large amount of data. Usually used only by a scroll pane.
- * @see #SCROLL_PANE
- */
- AccessibleRole.SCROLL_BAR,
-
- /**
- * An object usually used in a scroll pane. It represents the portion
- * of the entire data that the user can see. As the user manipulates
- * the scroll bars, the contents of the viewport can change.
- * @see #SCROLL_PANE
- */
- AccessibleRole.VIEWPORT,
-
- /**
- * An object that allows the user to select from a bounded range. For
- * example, a slider might be used to select a number between 0 and 100.
- */
- AccessibleRole.SLIDER,
-
- /**
- * A specialized panel that presents two other panels at the same time.
- * Between the two panels is a divider the user can manipulate to make
- * one panel larger and the other panel smaller.
- */
- AccessibleRole.SPLIT_PANE,
-
- /**
- * An object used to present information in terms of rows and columns.
- * An example might include a spreadsheet application.
- */
- AccessibleRole.TABLE,
-
- /**
- * An object that presents text to the user. The text is usually
- * editable by the user as opposed to a label.
- * @see #LABEL
- */
- AccessibleRole.TEXT,
-
- /**
- * An object used to present hierarchical information to the user.
- * The individual nodes in the tree can be collapsed and expanded
- * to provide selective disclosure of the tree's contents.
- */
- AccessibleRole.TREE,
-
- /**
- * A bar or palette usually composed of push buttons or toggle buttons.
- * It is often used to provide the most frequently used functions for an
- * application.
- */
- AccessibleRole.TOOL_BAR,
-
- /**
- * An object that provides information about another object. The
- * accessibleDescription property of the tool tip is often displayed
- * to the user in a small "help bubble" when the user causes the
- * mouse to hover over the object associated with the tool tip.
- */
- AccessibleRole.TOOL_TIP,
-
- /**
- * An AWT component, but nothing else is known about it.
- * @see #SWING_COMPONENT
- * @see #UNKNOWN
- */
- AccessibleRole.AWT_COMPONENT,
-
- /**
- * A Swing component, but nothing else is known about it.
- * @see #AWT_COMPONENT
- * @see #UNKNOWN
- */
- AccessibleRole.SWING_COMPONENT,
-
- /**
- * The object contains some Accessible information, but its role is
- * not known.
- * @see #AWT_COMPONENT
- * @see #SWING_COMPONENT
- */
- AccessibleRole.UNKNOWN,
-
- // These roles are only available in JDK 1.4
-
- /**
- * A STATUS_BAR is an simple component that can contain
- * multiple labels of status information to the user.
- AccessibleRole.STATUS_BAR,
-
- /**
- * A DATE_EDITOR is a component that allows users to edit
- * java.util.Date and java.util.Time objects
- AccessibleRole.DATE_EDITOR,
-
- /**
- * A SPIN_BOX is a simple spinner component and its main use
- * is for simple numbers.
- AccessibleRole.SPIN_BOX,
-
- /**
- * A FONT_CHOOSER is a component that lets the user pick various
- * attributes for fonts.
- AccessibleRole.FONT_CHOOSER,
-
- /**
- * A GROUP_BOX is a simple container that contains a border
- * around it and contains components inside it.
- AccessibleRole.GROUP_BOX
-
- /**
- * Since JDK 1.5
- *
- * A text header
-
- AccessibleRole.HEADER,
-
- /**
- * A text footer
-
- AccessibleRole.FOOTER,
-
- /**
- * A text paragraph
-
- AccessibleRole.PARAGRAPH,
-
- /**
- * A ruler is an object used to measure distance
-
- AccessibleRole.RULER,
-
- /**
- * A role indicating the object acts as a formula for
- * calculating a value. An example is a formula in
- * a spreadsheet cell.
- AccessibleRole.EDITBAR
- */
- };
-
- /**
- * This class implements accessibility support for the
- * <code>JTree</code> child. It provides an implementation of the
- * Java Accessibility API appropriate to tree nodes.
- *
- * Copied from JTree.java to work around a JTree bug where
- * ActiveDescendent PropertyChangeEvents contain the wrong
- * parent.
- */
- /**
- * This class in invoked on the EDT as its part of ActiveDescendant,
- * hence the calls do not need to be specifically made on the EDT
- */
- private class AccessibleJTreeNode extends AccessibleContext
- implements Accessible, AccessibleComponent, AccessibleSelection,
- AccessibleAction {
-
- private JTree tree = null;
- private TreeModel treeModel = null;
- private Object obj = null;
- private TreePath path = null;
- private Accessible accessibleParent = null;
- private int index = 0;
- private boolean isLeaf = false;
-
- /**
- * Constructs an AccessibleJTreeNode
- */
- AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) {
- tree = t;
- path = p;
- accessibleParent = ap;
- if (t != null)
- treeModel = t.getModel();
- if (p != null) {
- obj = p.getLastPathComponent();
- if (treeModel != null && obj != null) {
- isLeaf = treeModel.isLeaf(obj);
- }
- }
- debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap);
- }
-
- private TreePath getChildTreePath(int i) {
- // Tree nodes can't be so complex that they have
- // two sets of children -> we're ignoring that case
- if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
- return null;
- } else {
- Object childObj = treeModel.getChild(obj, i);
- Object[] objPath = path.getPath();
- Object[] objChildPath = new Object[objPath.length+1];
- java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
- objChildPath[objChildPath.length-1] = childObj;
- return new TreePath(objChildPath);
- }
- }
-
- /**
- * Get the AccessibleContext associated with this tree node.
- * In the implementation of the Java Accessibility API for
- * this class, return this object, which is its own
- * AccessibleContext.
- *
- * @return this object
- */
- public AccessibleContext getAccessibleContext() {
- return this;
- }
-
- private AccessibleContext getCurrentAccessibleContext() {
- Component c = getCurrentComponent();
- if (c instanceof Accessible) {
- return (c.getAccessibleContext());
- } else {
- return null;
- }
- }
-
- private Component getCurrentComponent() {
- debugString("AccessibleJTreeNode: getCurrentComponent");
- // is the object visible?
- // if so, get row, selected, focus & leaf state,
- // and then get the renderer component and return it
- if (tree != null && tree.isVisible(path)) {
- TreeCellRenderer r = tree.getCellRenderer();
- if (r == null) {
- debugString(" returning null 1");
- return null;
- }
- TreeUI ui = tree.getUI();
- if (ui != null) {
- int row = ui.getRowForPath(tree, path);
- boolean selected = tree.isPathSelected(path);
- boolean expanded = tree.isExpanded(path);
- boolean hasFocus = false; // how to tell?? -PK
- Component retval = r.getTreeCellRendererComponent(tree, obj,
- selected, expanded,
- isLeaf, row, hasFocus);
- debugString(" returning = "+retval.getClass());
- return retval;
- }
- }
- debugString(" returning null 2");
- return null;
- }
-
- // AccessibleContext methods
-
- /**
- * Get the accessible name of this object.
- *
- * @return the localized name of the object; null if this
- * object does not have a name
- */
- public String getAccessibleName() {
- debugString("AccessibleJTreeNode: getAccessibleName");
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- String name = ac.getAccessibleName();
- if ((name != null) && (!name.isEmpty())) {
- String retval = ac.getAccessibleName();
- debugString(" returning "+retval);
- return retval;
- } else {
- return null;
- }
- }
- if ((accessibleName != null) && (accessibleName.isEmpty())) {
- return accessibleName;
- } else {
- return null;
- }
- }
-
- /**
- * Set the localized accessible name of this object.
- *
- * @param s the new localized name of the object.
- */
- public void setAccessibleName(String s) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- ac.setAccessibleName(s);
- } else {
- super.setAccessibleName(s);
- }
- }
-
- //
- // *** should check tooltip text for desc. (needs MouseEvent)
- //
- /**
- * Get the accessible description of this object.
- *
- * @return the localized description of the object; null if
- * this object does not have a description
- */
- public String getAccessibleDescription() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- return ac.getAccessibleDescription();
- } else {
- return super.getAccessibleDescription();
- }
- }
-
- /**
- * Set the accessible description of this object.
- *
- * @param s the new localized description of the object
- */
- public void setAccessibleDescription(String s) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- ac.setAccessibleDescription(s);
- } else {
- super.setAccessibleDescription(s);
- }
- }
-
- /**
- * Get the role of this object.
- *
- * @return an instance of AccessibleRole describing the role of the object
- * @see AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- return ac.getAccessibleRole();
- } else {
- return AccessibleRole.UNKNOWN;
- }
- }
-
- /**
- * Get the state set of this object.
- *
- * @return an instance of AccessibleStateSet containing the
- * current state set of the object
- * @see AccessibleState
- */
- public AccessibleStateSet getAccessibleStateSet() {
- if (tree == null)
- return null;
- AccessibleContext ac = getCurrentAccessibleContext();
- AccessibleStateSet states;
- int row = tree.getUI().getRowForPath(tree,path);
- int lsr = tree.getLeadSelectionRow();
- if (ac != null) {
- states = ac.getAccessibleStateSet();
- } else {
- states = new AccessibleStateSet();
- }
- // need to test here, 'cause the underlying component
- // is a cellRenderer, which is never showing...
- if (isShowing()) {
- states.add(AccessibleState.SHOWING);
- } else if (states.contains(AccessibleState.SHOWING)) {
- states.remove(AccessibleState.SHOWING);
- }
- if (isVisible()) {
- states.add(AccessibleState.VISIBLE);
- } else if (states.contains(AccessibleState.VISIBLE)) {
- states.remove(AccessibleState.VISIBLE);
- }
- if (tree.isPathSelected(path)){
- states.add(AccessibleState.SELECTED);
- }
- if (lsr == row) {
- states.add(AccessibleState.ACTIVE);
- }
- if (!isLeaf) {
- states.add(AccessibleState.EXPANDABLE);
- }
- if (tree.isExpanded(path)) {
- states.add(AccessibleState.EXPANDED);
- } else {
- states.add(AccessibleState.COLLAPSED);
- }
- if (tree.isEditable()) {
- states.add(AccessibleState.EDITABLE);
- }
- return states;
- }
-
- /**
- * Get the Accessible parent of this object.
- *
- * @return the Accessible parent of this object; null if this
- * object does not have an Accessible parent
- */
- public Accessible getAccessibleParent() {
- // someone wants to know, so we need to create our parent
- // if we don't have one (hey, we're a talented kid!)
- if (accessibleParent == null && path != null) {
- Object[] objPath = path.getPath();
- if (objPath.length > 1) {
- Object objParent = objPath[objPath.length-2];
- if (treeModel != null) {
- index = treeModel.getIndexOfChild(objParent, obj);
- }
- Object[] objParentPath = new Object[objPath.length-1];
- java.lang.System.arraycopy(objPath, 0, objParentPath,
- 0, objPath.length-1);
- TreePath parentPath = new TreePath(objParentPath);
- accessibleParent = new AccessibleJTreeNode(tree,
- parentPath,
- null);
- this.setAccessibleParent(accessibleParent);
- } else if (treeModel != null) {
- accessibleParent = tree; // we're the top!
- index = 0; // we're an only child!
- this.setAccessibleParent(accessibleParent);
- }
- }
- return accessibleParent;
- }
-
- /**
- * Get the index of this object in its accessible parent.
- *
- * @return the index of this object in its parent; -1 if this
- * object does not have an accessible parent.
- * @see #getAccessibleParent
- */
- public int getAccessibleIndexInParent() {
- // index is invalid 'till we have an accessibleParent...
- if (accessibleParent == null) {
- getAccessibleParent();
- }
- if (path != null) {
- Object[] objPath = path.getPath();
- if (objPath.length > 1) {
- Object objParent = objPath[objPath.length-2];
- if (treeModel != null) {
- index = treeModel.getIndexOfChild(objParent, obj);
- }
- }
- }
- return index;
- }
-
- /**
- * Returns the number of accessible children in the object.
- *
- * @return the number of accessible children in the object.
- */
- public int getAccessibleChildrenCount() {
- // Tree nodes can't be so complex that they have
- // two sets of children -> we're ignoring that case
- if (obj != null && treeModel != null) {
- return treeModel.getChildCount(obj);
- }
- return 0;
- }
-
- /**
- * Return the specified Accessible child of the object.
- *
- * @param i zero-based index of child
- * @return the Accessible child of the object
- */
- public Accessible getAccessibleChild(int i) {
- // Tree nodes can't be so complex that they have
- // two sets of children -> we're ignoring that case
- if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
- return null;
- } else {
- Object childObj = treeModel.getChild(obj, i);
- Object[] objPath = path.getPath();
- Object[] objChildPath = new Object[objPath.length+1];
- java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
- objChildPath[objChildPath.length-1] = childObj;
- TreePath childPath = new TreePath(objChildPath);
- return new AccessibleJTreeNode(tree, childPath, this);
- }
- }
-
- /**
- * Gets the locale of the component. If the component does not have
- * a locale, then the locale of its parent is returned.
- *
- * @return This component's locale. If this component does not have
- * a locale, the locale of its parent is returned.
- * @exception IllegalComponentStateException
- * If the Component does not have its own locale and has not yet
- * been added to a containment hierarchy such that the locale can be
- * determined from the containing parent.
- * @see #setLocale
- */
- public Locale getLocale() {
- if (tree == null)
- return null;
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- return ac.getLocale();
- } else {
- return tree.getLocale();
- }
- }
-
- /**
- * Add a PropertyChangeListener to the listener list.
- * The listener is registered for all properties.
- *
- * @param l The PropertyChangeListener to be added
- */
- public void addPropertyChangeListener(PropertyChangeListener l) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- ac.addPropertyChangeListener(l);
- } else {
- super.addPropertyChangeListener(l);
- }
- }
-
- /**
- * Remove a PropertyChangeListener from the listener list.
- * This removes a PropertyChangeListener that was registered
- * for all properties.
- *
- * @param l The PropertyChangeListener to be removed
- */
- public void removePropertyChangeListener(PropertyChangeListener l) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- ac.removePropertyChangeListener(l);
- } else {
- super.removePropertyChangeListener(l);
- }
- }
-
- /**
- * Get the AccessibleAction associated with this object. In the
- * implementation of the Java Accessibility API for this class,
- * return this object, which is responsible for implementing the
- * AccessibleAction interface on behalf of itself.
- *
- * @return this object
- */
- public AccessibleAction getAccessibleAction() {
- return this;
- }
-
- /**
- * Get the AccessibleComponent associated with this object. In the
- * implementation of the Java Accessibility API for this class,
- * return this object, which is responsible for implementing the
- * AccessibleComponent interface on behalf of itself.
- *
- * @return this object
- */
- public AccessibleComponent getAccessibleComponent() {
- return this; // to override getBounds()
- }
-
- /**
- * Get the AccessibleSelection associated with this object if one
- * exists. Otherwise return null.
- *
- * @return the AccessibleSelection, or null
- */
- public AccessibleSelection getAccessibleSelection() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null && isLeaf) {
- return getCurrentAccessibleContext().getAccessibleSelection();
- } else {
- return this;
- }
- }
-
- /**
- * Get the AccessibleText associated with this object if one
- * exists. Otherwise return null.
- *
- * @return the AccessibleText, or null
- */
- public AccessibleText getAccessibleText() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- return getCurrentAccessibleContext().getAccessibleText();
- } else {
- return null;
- }
- }
-
- /**
- * Get the AccessibleValue associated with this object if one
- * exists. Otherwise return null.
- *
- * @return the AccessibleValue, or null
- */
- public AccessibleValue getAccessibleValue() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- return getCurrentAccessibleContext().getAccessibleValue();
- } else {
- return null;
- }
- }
-
-
- // AccessibleComponent methods
-
- /**
- * Get the background color of this object.
- *
- * @return the background color, if supported, of the object;
- * otherwise, null
- */
- public Color getBackground() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getBackground();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.getBackground();
- } else {
- return null;
- }
- }
- }
-
- /**
- * Set the background color of this object.
- *
- * @param c the new Color for the background
- */
- public void setBackground(Color c) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setBackground(c);
- } else {
- Component cp = getCurrentComponent();
- if ( cp != null) {
- cp.setBackground(c);
- }
- }
- }
-
-
- /**
- * Get the foreground color of this object.
- *
- * @return the foreground color, if supported, of the object;
- * otherwise, null
- */
- public Color getForeground() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getForeground();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.getForeground();
- } else {
- return null;
- }
- }
- }
-
- public void setForeground(Color c) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setForeground(c);
- } else {
- Component cp = getCurrentComponent();
- if (cp != null) {
- cp.setForeground(c);
- }
- }
- }
-
- public Cursor getCursor() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getCursor();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.getCursor();
- } else {
- Accessible ap = getAccessibleParent();
- if (ap instanceof AccessibleComponent) {
- return ((AccessibleComponent) ap).getCursor();
- } else {
- return null;
- }
- }
- }
- }
-
- public void setCursor(Cursor c) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setCursor(c);
- } else {
- Component cp = getCurrentComponent();
- if (cp != null) {
- cp.setCursor(c);
- }
- }
- }
-
- public Font getFont() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getFont();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.getFont();
- } else {
- return null;
- }
- }
- }
-
- public void setFont(Font f) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setFont(f);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.setFont(f);
- }
- }
- }
-
- public FontMetrics getFontMetrics(Font f) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getFontMetrics(f);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.getFontMetrics(f);
- } else {
- return null;
- }
- }
- }
-
- public boolean isEnabled() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).isEnabled();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.isEnabled();
- } else {
- return false;
- }
- }
- }
-
- public void setEnabled(boolean b) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setEnabled(b);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.setEnabled(b);
- }
- }
- }
-
- public boolean isVisible() {
- if (tree == null)
- return false;
- Rectangle pathBounds = tree.getPathBounds(path);
- Rectangle parentBounds = tree.getVisibleRect();
- if ( pathBounds != null && parentBounds != null &&
- parentBounds.intersects(pathBounds) ) {
- return true;
- } else {
- return false;
- }
- }
-
- public void setVisible(boolean b) {
- }
-
- public boolean isShowing() {
- return (tree.isShowing() && isVisible());
- }
-
- public boolean contains(Point p) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- Rectangle r = ((AccessibleComponent) ac).getBounds();
- return r.contains(p);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- Rectangle r = c.getBounds();
- return r.contains(p);
- } else {
- return getBounds().contains(p);
- }
- }
- }
-
- public Point getLocationOnScreen() {
- if (tree != null) {
- Point treeLocation = tree.getLocationOnScreen();
- Rectangle pathBounds = tree.getPathBounds(path);
- if (treeLocation != null && pathBounds != null) {
- Point nodeLocation = new Point(pathBounds.x,
- pathBounds.y);
- nodeLocation.translate(treeLocation.x, treeLocation.y);
- return nodeLocation;
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- private Point getLocationInJTree() {
- Rectangle r = tree.getPathBounds(path);
- if (r != null) {
- return r.getLocation();
- } else {
- return null;
- }
- }
-
- public Point getLocation() {
- Rectangle r = getBounds();
- if (r != null) {
- return r.getLocation();
- } else {
- return null;
- }
- }
-
- public void setLocation(Point p) {
- }
-
- public Rectangle getBounds() {
- if (tree == null)
- return null;
- Rectangle r = tree.getPathBounds(path);
- Accessible parent = getAccessibleParent();
- if (parent instanceof AccessibleJTreeNode) {
- Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree();
- if (parentLoc != null && r != null) {
- r.translate(-parentLoc.x, -parentLoc.y);
- } else {
- return null; // not visible!
- }
- }
- return r;
- }
-
- public void setBounds(Rectangle r) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setBounds(r);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.setBounds(r);
- }
- }
- }
-
- public Dimension getSize() {
- return getBounds().getSize();
- }
-
- public void setSize (Dimension d) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).setSize(d);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.setSize(d);
- }
- }
- }
-
- /**
- * Returns the <code>Accessible</code> child, if one exists,
- * contained at the local coordinate <code>Point</code>.
- * Otherwise returns <code>null</code>.
- *
- * @param p point in local coordinates of this
- * <code>Accessible</code>
- * @return the <code>Accessible</code>, if it exists,
- * at the specified location; else <code>null</code>
- */
- public Accessible getAccessibleAt(Point p) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).getAccessibleAt(p);
- } else {
- return null;
- }
- }
-
- public boolean isFocusTraversable() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- return ((AccessibleComponent) ac).isFocusTraversable();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- return c.isFocusable();
- } else {
- return false;
- }
- }
- }
-
- public void requestFocus() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).requestFocus();
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.requestFocus();
- }
- }
- }
-
- public void addFocusListener(FocusListener l) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).addFocusListener(l);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.addFocusListener(l);
- }
- }
- }
-
- public void removeFocusListener(FocusListener l) {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac instanceof AccessibleComponent) {
- ((AccessibleComponent) ac).removeFocusListener(l);
- } else {
- Component c = getCurrentComponent();
- if (c != null) {
- c.removeFocusListener(l);
- }
- }
- }
-
- // AccessibleSelection methods
-
- /**
- * Returns the number of items currently selected.
- * If no items are selected, the return value will be 0.
- *
- * @return the number of items currently selected.
- */
- public int getAccessibleSelectionCount() {
- int count = 0;
- int childCount = getAccessibleChildrenCount();
- for (int i = 0; i < childCount; i++) {
- TreePath childPath = getChildTreePath(i);
- if (tree.isPathSelected(childPath)) {
- count++;
- }
- }
- return count;
- }
-
- /**
- * Returns an Accessible representing the specified selected item
- * in the object. If there isn't a selection, or there are
- * fewer items selected than the integer passed in, the return
- * value will be null.
- *
- * @param i the zero-based index of selected items
- * @return an Accessible containing the selected item
- */
- public Accessible getAccessibleSelection(int i) {
- int childCount = getAccessibleChildrenCount();
- if (i < 0 || i >= childCount) {
- return null; // out of range
- }
- int count = 0;
- for (int j = 0; j < childCount && i >= count; j++) {
- TreePath childPath = getChildTreePath(j);
- if (tree.isPathSelected(childPath)) {
- if (count == i) {
- return new AccessibleJTreeNode(tree, childPath, this);
- } else {
- count++;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns true if the current child of this object is selected.
- *
- * @param i the zero-based index of the child in this Accessible
- * object.
- * @see AccessibleContext#getAccessibleChild
- */
- public boolean isAccessibleChildSelected(int i) {
- int childCount = getAccessibleChildrenCount();
- if (i < 0 || i >= childCount) {
- return false; // out of range
- } else {
- TreePath childPath = getChildTreePath(i);
- return tree.isPathSelected(childPath);
- }
- }
-
- /**
- * Adds the specified selected item in the object to the object's
- * selection. If the object supports multiple selections,
- * the specified item is added to any existing selection, otherwise
- * it replaces any existing selection in the object. If the
- * specified item is already selected, this method has no effect.
- *
- * @param i the zero-based index of selectable items
- */
- public void addAccessibleSelection(int i) {
- if (tree == null)
- return;
- TreeModel model = tree.getModel();
- if (model != null) {
- if (i >= 0 && i < getAccessibleChildrenCount()) {
- TreePath path = getChildTreePath(i);
- tree.addSelectionPath(path);
- }
- }
- }
-
- /**
- * Removes the specified selected item in the object from the
- * object's
- * selection. If the specified item isn't currently selected, this
- * method has no effect.
- *
- * @param i the zero-based index of selectable items
- */
- public void removeAccessibleSelection(int i) {
- if (tree == null)
- return;
- TreeModel model = tree.getModel();
- if (model != null) {
- if (i >= 0 && i < getAccessibleChildrenCount()) {
- TreePath path = getChildTreePath(i);
- tree.removeSelectionPath(path);
- }
- }
- }
-
- /**
- * Clears the selection in the object, so that nothing in the
- * object is selected.
- */
- public void clearAccessibleSelection() {
- int childCount = getAccessibleChildrenCount();
- for (int i = 0; i < childCount; i++) {
- removeAccessibleSelection(i);
- }
- }
-
- /**
- * Causes every selected item in the object to be selected
- * if the object supports multiple selections.
- */
- public void selectAllAccessibleSelection() {
- if (tree == null)
- return;
- TreeModel model = tree.getModel();
- if (model != null) {
- int childCount = getAccessibleChildrenCount();
- TreePath path;
- for (int i = 0; i < childCount; i++) {
- path = getChildTreePath(i);
- tree.addSelectionPath(path);
- }
- }
- }
-
- // AccessibleAction methods
-
- /**
- * Returns the number of accessible actions available in this
- * tree node. If this node is not a leaf, there is at least
- * one action (toggle expand), in addition to any available
- * on the object behind the TreeCellRenderer.
- *
- * @return the number of Actions in this object
- */
- public int getAccessibleActionCount() {
- AccessibleContext ac = getCurrentAccessibleContext();
- if (ac != null) {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa != null) {
- return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1));
- }
- }
- return isLeaf ? 0 : 1;
- }
-
- /**
- * Return a description of the specified action of the tree node.
- * If this node is not a leaf, there is at least one action
- * description (toggle expand), in addition to any available
- * on the object behind the TreeCellRenderer.
- *
- * @param i zero-based index of the actions
- * @return a description of the action
- */
- public String getAccessibleActionDescription(int i) {
- if (i < 0 || i >= getAccessibleActionCount()) {
- return null;
- }
- AccessibleContext ac = getCurrentAccessibleContext();
- if (i == 0) {
- // TIGER - 4766636
- // return AccessibleAction.TOGGLE_EXPAND;
- return "toggle expand";
- } else if (ac != null) {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa != null) {
- return aa.getAccessibleActionDescription(i - 1);
- }
- }
- return null;
- }
-
- /**
- * Perform the specified Action on the tree node. If this node
- * is not a leaf, there is at least one action which can be
- * done (toggle expand), in addition to any available on the
- * object behind the TreeCellRenderer.
- *
- * @param i zero-based index of actions
- * @return true if the the action was performed; else false.
- */
- public boolean doAccessibleAction(int i) {
- if (i < 0 || i >= getAccessibleActionCount()) {
- return false;
- }
- AccessibleContext ac = getCurrentAccessibleContext();
- if (i == 0) {
- if (tree.isExpanded(path)) {
- tree.collapsePath(path);
- } else {
- tree.expandPath(path);
- }
- return true;
- } else if (ac != null) {
- AccessibleAction aa = ac.getAccessibleAction();
- if (aa != null) {
- return aa.doAccessibleAction(i - 1);
- }
- }
- return false;
- }
-
- } // inner class AccessibleJTreeNode
-
- /**
- * A helper class to perform {@code Callable} objects on the event dispatch thread appropriate
- * for the provided {@code AccessibleContext}.
- */
- private static class InvocationUtils {
-
- /**
- * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible}
- * and waits for it to finish blocking the caller thread.
- *
- * @param callable the {@code Callable} to invoke
- * @param accessible the {@code Accessible} which would be used to find the right context
- * for the task execution
- * @param <T> type parameter for the result value
- *
- * @return the result of the {@code Callable} execution
- */
- public static <T> T invokeAndWait(final Callable<T> callable,
- final Accessible accessible) {
- if (accessible instanceof Component) {
- return invokeAndWait(callable, (Component)accessible);
- }
- if (accessible instanceof AccessibleContext) {
- // This case also covers the Translator
- return invokeAndWait(callable, (AccessibleContext)accessible);
- }
- throw new RuntimeException("Unmapped Accessible used to dispatch event: " + accessible);
- }
-
- /**
- * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Component}
- * and waits for it to finish blocking the caller thread.
- *
- * @param callable the {@code Callable} to invoke
- * @param component the {@code Component} which would be used to find the right context
- * for the task execution
- * @param <T> type parameter for the result value
- *
- * @return the result of the {@code Callable} execution
- */
- public static <T> T invokeAndWait(final Callable<T> callable,
- final Component component) {
- return invokeAndWait(callable, SunToolkit.targetToAppContext(component));
- }
-
- /**
- * Invokes a {@code Callable} in the {@code AppContext} mapped to the given {@code AccessibleContext}
- * and waits for it to finish blocking the caller thread.
- *
- * @param callable the {@code Callable} to invoke
- * @param accessibleContext the {@code AccessibleContext} which would be used to determine the right
- * context for the task execution.
- * @param <T> type parameter for the result value
- *
- * @return the result of the {@code Callable} execution
- */
- public static <T> T invokeAndWait(final Callable<T> callable,
- final AccessibleContext accessibleContext) {
- AppContext targetContext = AWTAccessor.getAccessibleContextAccessor()
- .getAppContext(accessibleContext);
- if (targetContext != null) {
- return invokeAndWait(callable, targetContext);
- } else {
- // Normally this should not happen, unmapped context provided and
- // the target AppContext is unknown.
-
- // Try to recover in case the context is a translator.
- if (accessibleContext instanceof Translator) {
- Object source = ((Translator)accessibleContext).getSource();
- if (source instanceof Component) {
- return invokeAndWait(callable, (Component)source);
- }
- }
- }
- throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleContext);
- }
-
- private static <T> T invokeAndWait(final Callable<T> callable,
- final AppContext targetAppContext) {
- final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
- try {
- invokeAndWait(wrapper, targetAppContext);
- T result = wrapper.getResult();
- updateAppContextMap(result, targetAppContext);
- return result;
- } catch (final Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private static void invokeAndWait(final Runnable runnable,
- final AppContext appContext)
- throws InterruptedException, InvocationTargetException {
-
- EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
- Object lock = new Object();
- Toolkit source = Toolkit.getDefaultToolkit();
- InvocationEvent event =
- new InvocationEvent(source, runnable, lock, true);
- synchronized (lock) {
- eq.postEvent(event);
- lock.wait();
- }
-
- Throwable eventThrowable = event.getThrowable();
- if (eventThrowable != null) {
- throw new InvocationTargetException(eventThrowable);
- }
- }
-
- /**
- * Maps the {@code AccessibleContext} to the {@code AppContext} which should be used
- * to dispatch events related to the {@code AccessibleContext}
- * @param accessibleContext the {@code AccessibleContext} for the mapping
- * @param targetContext the {@code AppContext} for the mapping
- */
- public static void registerAccessibleContext(final AccessibleContext accessibleContext,
- final AppContext targetContext) {
- if (accessibleContext != null) {
- AWTAccessor.getAccessibleContextAccessor().setAppContext(accessibleContext, targetContext);
- }
- }
-
- private static <T> void updateAppContextMap(final T accessibleContext,
- final AppContext targetContext) {
- if (accessibleContext instanceof AccessibleContext) {
- registerAccessibleContext((AccessibleContext)accessibleContext, targetContext);
- }
- }
-
- private static class CallableWrapper<T> implements Runnable {
- private final Callable<T> callable;
- private volatile T object;
- private Exception e;
-
- CallableWrapper(final Callable<T> callable) {
- this.callable = callable;
- }
-
- public void run() {
- try {
- if (callable != null) {
- object = callable.call();
- }
- } catch (final Exception e) {
- this.e = e;
- }
- }
-
- T getResult() throws Exception {
- if (e != null)
- throw e;
- return object;
- }
- }
- }
-}
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/ProviderImpl.java Thu Aug 13 13:30:15 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 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 javax.accessibility.AccessibilityProvider;
-
-/* This class provided methods to identify and activate the mapping from the
- * JavaAccessBridge API to the Java Accessibility API.
- */
-public final class ProviderImpl extends AccessibilityProvider {
- /**
- * Typically the service name returned by the name() method would be a simple
- * name such as JavaAccessBridge, but the following name is used for compatibility
- * with prior versions of ${user.home}/.accessibility.properties and
- * ${java.home}/conf/accessibility.properties where the text on the
- * assistive.technologies= line is a fully qualified class name. As of Java 9
- * class names are no longer used to identify assistive technology implementations.
- * If the properties file exists the installer will not replace it thus the
- * need for compatibility.
- */
- private final String name = "com.sun.java.accessibility.AccessBridge";
-
- public ProviderImpl() {}
-
- public String getName() {
- return name;
- }
-
- public void activate() {
- /**
- * Note that the AccessBridge is instantiated here rather than in the
- * constructor. If the caller determines that this object is named
- * "com.sun.java.accessibility.AccessBridge" then the caller will call
- * start to instantiate the AccessBridge which will in turn activate it.
- */
- new AccessBridge();
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,7170 @@
+/*
+ * 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.internal;
+
+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 {
+
+ private static AccessBridge theAccessBridge;
+ private ObjectReferences references;
+ private EventHandler eventHandler;
+
+ // 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<>();
+
+ private static native boolean isSysWow();
+
+
+ /**
+ * Load DLLs
+ */
+ static {
+ // Load the appropriate DLLs
+ boolean is32on64 = false;
+ if (System.getProperty("os.arch").equals("x86")) {
+ // 32 bit JRE
+ // Load jabsysinfo.dll so can determine Win bitness
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("jabsysinfo");
+ return null;
+ }
+ }, null, new java.lang.RuntimePermission("loadLibrary.jabsysinfo")
+ );
+ if (isSysWow()) {
+ // 32 bit JRE on 64 bit OS
+ is32on64 = true;
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("javaaccessbridge-32");
+ return null;
+ }
+ }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge-32")
+ );
+ }
+ }
+ if (!is32on64) {
+ // 32 bit JRE on 32 bit OS or 64 bit JRE on 64 bit OS
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("javaaccessbridge");
+ return null;
+ }
+ }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge")
+ );
+ }
+ }
+
+ /**
+ * AccessBridge constructor
+ *
+ * Note: This constructor has to be public. It's called from the VM like this:
+ * Class.forName(atName).newInstance();
+ */
+ public AccessBridge() {
+ 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);
+
+ // initialize the methods that map HWNDs and Java top-level
+ // windows
+ initHWNDcalls();
+
+ // 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
+ 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;
+ }
+
+ /* ===== 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 jawtGetNativeWindowHandleFromComponent(Component comp);
+
+ private native Component jawtGetComponentFromNativeWindowHandle(int handle);
+
+ Toolkit toolkit;
+
+ /**
+ * map an HWND to an AWT Component
+ */
+ private void 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());
+ }
+ toolkit = Toolkit.getDefaultToolkit();
+ return;
+ }
+
+ // 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 = jawtGetComponentFromNativeWindowHandle(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;
+ }
+ }
+ }
+
+ /* ===== 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>() {
+ @Override
+ public String call() throws Exception {
+ 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[]>() {
+ @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 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).
+ */
+ {
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return childContext.getAccessibleRole();
+ }
+ }, ac);
+ if ( AccessibleRole.LABEL == childRole ) {
+ childX = getAccessibleXcoordFromContext (childContext);
+ childY = getAccessibleYcoordFromContext (childContext);
+ childWidth = getAccessibleWidthFromContext (childContext);
+ childHeight = getAccessibleHeightFromContext (childContext);
+ if ( (childX < testX) &&
+ ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ } else if ( (childY < targetY) &&
+ ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ }
+ }
+ }
+ }
+ childIndex --;
+ }
+ childIndex = testIndex + 1;
+ while (childIndex <= testIndexMax) {
+ 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return childContext.getAccessibleRole();
+ }
+ }, ac);
+ if ( AccessibleRole.LABEL == childRole ) {
+ childX = getAccessibleXcoordFromContext (childContext);
+ childY = getAccessibleYcoordFromContext (childContext);
+ childWidth = getAccessibleWidthFromContext (childContext);
+ childHeight = getAccessibleHeightFromContext (childContext);
+ if ( (childX < testX) &&
+ ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ } else if ( (childY < targetY) &&
+ ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ }
+ }
+ }
+ }
+ childIndex ++;
+ }
+ /*
+ Step 8:
+ =======
+ Special case for combo boxes and text objects, based on a
+ similar special case I found in some of our internal JAWS code.
+
+ Search for a button object that is positioned either just to the left
+ or just above the object and get the Accessible Name of the button
+ object.
+ */
+ if ( (AccessibleRole.TEXT == role) ||
+ (AccessibleRole.COMBO_BOX == role) ||
+ (bIsEditCombo) ) {
+ childIndex = testIndex - 1;
+ 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return childContext.getAccessibleRole();
+ }
+ }, ac);
+ if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
+ ( AccessibleRole.TOGGLE_BUTTON == childRole )) {
+ childX = getAccessibleXcoordFromContext (childContext);
+ childY = getAccessibleYcoordFromContext (childContext);
+ childWidth = getAccessibleWidthFromContext (childContext);
+ childHeight = getAccessibleHeightFromContext (childContext);
+ if ( (childX < testX) &&
+ ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ }
+ }
+ }
+ }
+ childIndex --;
+ }
+ childIndex = testIndex + 1;
+ while (childIndex <= testIndexMax) {
+ 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 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return child.getAccessibleContext();
+ }
+ }, ac);
+ if ( null != childContext ) {
+ AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return childContext.getAccessibleRole();
+ }
+ }, ac);
+ if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
+ ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) {
+ childX = getAccessibleXcoordFromContext (childContext);
+ childY = getAccessibleYcoordFromContext (childContext);
+ childWidth = getAccessibleWidthFromContext (childContext);
+ childHeight = getAccessibleHeightFromContext (childContext);
+ if ( (childX < testX) &&
+ ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
+ childName = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleName();
+ }
+ }, ac);
+ if ( null != childName ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+ references.increment (childName);
+ return childName;
+ }
+ childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return childContext.getAccessibleDescription();
+ }
+ }, ac);
+ if ( null != childDescription ) {
+ debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
+ references.increment (childDescription);
+ return childDescription;
+ }
+ }
+ }
+ }
+ }
+ childIndex ++;
+ }
+ }
+ return null;
+ } else {
+ debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
+ return null;
+ }
+ }
+
+ /**
+ * returns the AccessibleDescription from an AccessibleContext
+ */
+ private String getAccessibleDescriptionFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return ac.getAccessibleDescription();
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ debugString("Returning AccessibleDescription from Context: " + s);
+ return s;
+ }
+ } else {
+ debugString("getAccessibleDescriptionFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * returns the AccessibleRole from an AccessibleContext
+ */
+ private String getAccessibleRoleStringFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
+ @Override
+ public AccessibleRole call() throws Exception {
+ return ac.getAccessibleRole();
+ }
+ }, ac);
+ if (role != null) {
+ String s = role.toDisplayString(Locale.US);
+ if (s != null) {
+ references.increment(s);
+ debugString("Returning AccessibleRole from Context: " + s);
+ return s;
+ }
+ }
+ } else {
+ debugString("getAccessibleRoleStringFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the AccessibleRole from an AccessibleContext in the en_US locale
+ */
+ private String getAccessibleRoleStringFromContext_en_US(final AccessibleContext ac) {
+ return getAccessibleRoleStringFromContext(ac);
+ }
+
+ /**
+ * return the AccessibleStates from an AccessibleContext
+ */
+ private String getAccessibleStatesStringFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
+ @Override
+ public AccessibleStateSet call() throws Exception {
+ return ac.getAccessibleStateSet();
+ }
+ }, ac);
+ if (stateSet != null) {
+ String s = stateSet.toString();
+ if (s != null &&
+ s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
+ // Indicate whether this component manages its own
+ // children
+ AccessibleRole role = ac.getAccessibleRole();
+ if (role == AccessibleRole.LIST ||
+ role == AccessibleRole.TABLE ||
+ role == AccessibleRole.TREE) {
+ s += ",";
+ s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US);
+ }
+ references.increment(s);
+ debugString("Returning AccessibleStateSet from Context: " + s);
+ return s;
+ }
+ }
+ } else {
+ debugString("getAccessibleStatesStringFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * returns the AccessibleStates from an AccessibleContext in the en_US locale
+ */
+ private String getAccessibleStatesStringFromContext_en_US(final AccessibleContext ac) {
+ if (ac != null) {
+ AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable<AccessibleStateSet>() {
+ @Override
+ public AccessibleStateSet call() throws Exception {
+ return ac.getAccessibleStateSet();
+ }
+ }, ac);
+ if (stateSet != null) {
+ String s = "";
+ AccessibleState[] states = stateSet.toArray();
+ if (states != null && states.length > 0) {
+ s = states[0].toDisplayString(Locale.US);
+ for (int i = 1; i < states.length; i++) {
+ s = s + "," + states[i].toDisplayString(Locale.US);
+ }
+ }
+ references.increment(s);
+ debugString("Returning AccessibleStateSet en_US from Context: " + s);
+ return s;
+ }
+ }
+ debugString("getAccessibleStatesStringFromContext; ac = null");
+ return null;
+ }
+
+ /**
+ * returns the AccessibleParent from an AccessibleContext
+ */
+ private AccessibleContext getAccessibleParentFromContext(final AccessibleContext ac) {
+ if (ac==null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ Accessible a = ac.getAccessibleParent();
+ if (a != null) {
+ AccessibleContext apc = a.getAccessibleContext();
+ if (apc != null) {
+ return apc;
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleIndexInParent from an AccessibleContext
+ */
+ private int getAccessibleIndexInParentFromContext(final AccessibleContext ac) {
+ if (ac==null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac.getAccessibleIndexInParent();
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleChild count from an AccessibleContext
+ */
+ private int getAccessibleChildrenCountFromContext(final AccessibleContext ac) {
+ if (ac==null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac.getAccessibleChildrenCount();
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleChild Context from an AccessibleContext
+ */
+ private AccessibleContext getAccessibleChildFromContext(final AccessibleContext ac, final int index) {
+
+ if (ac == null) {
+ return null;
+ }
+
+ final JTable table = InvocationUtils.invokeAndWait(new Callable<JTable>() {
+ @Override
+ public JTable call() throws Exception {
+ // work-around for AccessibleJTable.getCurrentAccessibleContext returning
+ // wrong renderer component when cell contains more than one component
+ Accessible parent = ac.getAccessibleParent();
+ if (parent != null) {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ Accessible child =
+ parent.getAccessibleContext().getAccessibleChild(indexInParent);
+ if (child instanceof JTable) {
+ return (JTable) child;
+ }
+ }
+ return null;
+ }
+ }, ac);
+
+ if (table == null) {
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ Accessible a = ac.getAccessibleChild(index);
+ if (a != null) {
+ return a.getAccessibleContext();
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ final AccessibleTable at = getAccessibleTableFromContext(ac);
+
+ final int row = getAccessibleTableRow(at, index);
+ final int column = getAccessibleTableColumn(at, index);
+
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ TableCellRenderer renderer = table.getCellRenderer(row, column);
+ if (renderer == null) {
+ Class<?> columnClass = table.getColumnClass(column);
+ renderer = table.getDefaultRenderer(columnClass);
+ }
+ Component component =
+ renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
+ false, false, row, column);
+ if (component instanceof Accessible) {
+ return component.getAccessibleContext();
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleComponent bounds on screen from an AccessibleContext
+ */
+ private Rectangle getAccessibleBoundsOnScreenFromContext(final AccessibleContext ac) {
+ if(ac==null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
+ @Override
+ public Rectangle call() throws Exception {
+ AccessibleComponent acmp = ac.getAccessibleComponent();
+ if (acmp != null) {
+ Rectangle r = acmp.getBounds();
+ if (r != null) {
+ try {
+ Point p = acmp.getLocationOnScreen();
+ if (p != null) {
+ r.x = p.x;
+ r.y = p.y;
+ return r;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleComponent x-coord from an AccessibleContext
+ */
+ private int getAccessibleXcoordFromContext(AccessibleContext ac) {
+ if (ac != null) {
+ Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
+ if (r != null) {
+ debugString(" - Returning Accessible x coord from Context: " + r.x);
+ return r.x;
+ }
+ } else {
+ debugString("getAccessibleXcoordFromContext ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * returns the AccessibleComponent y-coord from an AccessibleContext
+ */
+ private int getAccessibleYcoordFromContext(AccessibleContext ac) {
+ debugString("getAccessibleYcoordFromContext() called");
+ if (ac != null) {
+ Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
+ if (r != null) {
+ return r.y;
+ }
+ } else {
+ debugString("getAccessibleYcoordFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * returns the AccessibleComponent height from an AccessibleContext
+ */
+ private int getAccessibleHeightFromContext(AccessibleContext ac) {
+ if (ac != null) {
+ Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
+ if (r != null) {
+ return r.height;
+ }
+ } else {
+ debugString("getAccessibleHeightFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * returns the AccessibleComponent width from an AccessibleContext
+ */
+ private int getAccessibleWidthFromContext(AccessibleContext ac) {
+ if (ac != null) {
+ Rectangle r = getAccessibleBoundsOnScreenFromContext(ac);
+ if (r != null) {
+ return r.width;
+ }
+ } else {
+ debugString("getAccessibleWidthFromContext; ac = null");
+ }
+ return -1;
+ }
+
+
+ /**
+ * returns the AccessibleComponent from an AccessibleContext
+ */
+ private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
+ if (ac != null) {
+ AccessibleComponent acmp = ac.getAccessibleComponent();
+ if (acmp != null) {
+ debugString("Returning AccessibleComponent Context");
+ return acmp;
+ }
+ } else {
+ debugString("getAccessibleComponentFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * returns the AccessibleAction from an AccessibleContext
+ */
+ private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) {
+ debugString("Returning AccessibleAction Context");
+ return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleAction>() {
+ @Override
+ public AccessibleAction call() throws Exception {
+ return ac.getAccessibleAction();
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the AccessibleSelection from an AccessibleContext
+ */
+ private AccessibleSelection getAccessibleSelectionFromContext(final AccessibleContext ac) {
+ return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleSelection>() {
+ @Override
+ public AccessibleSelection call() throws Exception {
+ return ac.getAccessibleSelection();
+ }
+ }, ac);
+ }
+
+ /**
+ * return the AccessibleText from an AccessibleContext
+ */
+ private AccessibleText getAccessibleTextFromContext(final AccessibleContext ac) {
+ return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
+ @Override
+ public AccessibleText call() throws Exception {
+ return ac.getAccessibleText();
+ }
+ }, ac);
+ }
+
+ /**
+ * return the AccessibleComponent from an AccessibleContext
+ */
+ private AccessibleValue getAccessibleValueFromContext(final AccessibleContext ac) {
+ return ac == null ? null : InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
+ @Override
+ public AccessibleValue call() throws Exception {
+ return ac.getAccessibleValue();
+ }
+ }, ac);
+ }
+
+ /* ===== AccessibleText methods ===== */
+
+ /**
+ * returns the bounding rectangle for the text cursor
+ * XXX
+ */
+ private Rectangle getCaretLocation(final AccessibleContext ac) {
+ debugString("getCaretLocation");
+ if (ac==null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
+ @Override
+ public Rectangle call() throws Exception {
+ // workaround for JAAPI not returning cursor bounding rectangle
+ Rectangle r = null;
+ Accessible parent = ac.getAccessibleParent();
+ if (parent instanceof Accessible) {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ Accessible child =
+ parent.getAccessibleContext().getAccessibleChild(indexInParent);
+
+ if (child instanceof JTextComponent) {
+ JTextComponent text = (JTextComponent) child;
+ try {
+ r = text.modelToView(text.getCaretPosition());
+ if (r != null) {
+ Point p = text.getLocationOnScreen();
+ r.translate(p.x, p.y);
+ }
+ } catch (BadLocationException ble) {
+ }
+ }
+ }
+ return r;
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the x-coordinate for the text cursor rectangle
+ */
+ private int getCaretLocationX(AccessibleContext ac) {
+ Rectangle r = getCaretLocation(ac);
+ if (r != null) {
+ return r.x;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * returns the y-coordinate for the text cursor rectangle
+ */
+ private int getCaretLocationY(AccessibleContext ac) {
+ Rectangle r = getCaretLocation(ac);
+ if (r != null) {
+ return r.y;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * returns the height for the text cursor rectangle
+ */
+ private int getCaretLocationHeight(AccessibleContext ac) {
+ Rectangle r = getCaretLocation(ac);
+ if (r != null) {
+ return r.height;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * returns the width for the text cursor rectangle
+ */
+ private int getCaretLocationWidth(AccessibleContext ac) {
+ Rectangle r = getCaretLocation(ac);
+ if (r != null) {
+ return r.width;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * returns the character count from an AccessibleContext
+ */
+ private int getAccessibleCharCountFromContext(final AccessibleContext ac) {
+ if (ac==null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ return at.getCharCount();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * returns the caret position from an AccessibleContext
+ */
+ private int getAccessibleCaretPositionFromContext(final AccessibleContext ac) {
+ if (ac==null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ return at.getCaretPosition();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * Return the index at a specific point from an AccessibleContext
+ * Point(x, y) is in screen coordinates.
+ */
+ private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac,
+ final int x, final int y) {
+ debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y);
+ if (ac==null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ AccessibleComponent acomp = ac.getAccessibleComponent();
+ if (at != null && acomp != null) {
+ // Convert x and y from screen coordinates to
+ // local coordinates.
+ try {
+ Point p = acomp.getLocationOnScreen();
+ int x1, y1;
+ if (p != null) {
+ x1 = x - p.x;
+ if (x1 < 0) {
+ x1 = 0;
+ }
+ y1 = y - p.y;
+ if (y1 < 0) {
+ y1 = 0;
+ }
+
+ Point newPoint = new Point(x1, y1);
+ int indexAtPoint = at.getIndexAtPoint(new Point(x1, y1));
+ return indexAtPoint;
+ }
+ } catch (Exception e) {
+ }
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * return the letter at a specific point from an AccessibleContext
+ */
+ private String getAccessibleLetterAtIndexFromContext(final AccessibleContext ac, final int index) {
+ if (ac != null) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at == null) return null;
+ return at.getAtIndex(AccessibleText.CHARACTER, index);
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getAccessibleLetterAtIndexFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the word at a specific point from an AccessibleContext
+ */
+ private String getAccessibleWordAtIndexFromContext(final AccessibleContext ac, final int index) {
+ if (ac != null) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at == null) return null;
+ return at.getAtIndex(AccessibleText.WORD, index);
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getAccessibleWordAtIndexFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the sentence at a specific point from an AccessibleContext
+ */
+ private String getAccessibleSentenceAtIndexFromContext(final AccessibleContext ac, final int index) {
+ if (ac != null) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at == null) return null;
+ return at.getAtIndex(AccessibleText.SENTENCE, index);
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getAccessibleSentenceAtIndexFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the text selection start from an AccessibleContext
+ */
+ private int getAccessibleTextSelectionStartFromContext(final AccessibleContext ac) {
+ if (ac == null) return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ return at.getSelectionStart();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * return the text selection end from an AccessibleContext
+ */
+ private int getAccessibleTextSelectionEndFromContext(final AccessibleContext ac) {
+ if (ac == null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ return at.getSelectionEnd();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * return the selected text from an AccessibleContext
+ */
+ private String getAccessibleTextSelectedTextFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at == null) return null;
+ return at.getSelectedText();
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getAccessibleTextSelectedTextFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the attribute string at a given index from an AccessibleContext
+ */
+ private String getAccessibleAttributesAtIndexFromContext(final AccessibleContext ac,
+ final int index) {
+ if (ac == null)
+ return null;
+ AttributeSet as = InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
+ @Override
+ public AttributeSet call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ return at.getCharacterAttribute(index);
+ }
+ return null;
+ }
+ }, ac);
+ String s = expandStyleConstants(as);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ return null;
+ }
+
+ /**
+ * Get line info: left index of line
+ *
+ * algorithm: cast back, doubling each time,
+ * 'till find line boundaries
+ *
+ * return -1 if we can't get the info (e.g. index or at passed in
+ * is bogus; etc.)
+ */
+ private int getAccessibleTextLineLeftBoundsFromContext(final AccessibleContext ac,
+ final int index) {
+ if (ac == null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ int lineStart;
+ int offset;
+ Rectangle charRect;
+ Rectangle indexRect = at.getCharacterBounds(index);
+ int textLen = at.getCharCount();
+ if (indexRect == null) {
+ return -1;
+ }
+ // find the start of the line
+ //
+ offset = 1;
+ lineStart = index - offset < 0 ? 0 : index - offset;
+ charRect = at.getCharacterBounds(lineStart);
+ // slouch behind beginning of line
+ while (charRect != null
+ && charRect.y >= indexRect.y
+ && lineStart > 0) {
+ offset = offset << 1;
+ lineStart = index - offset < 0 ? 0 : index - offset;
+ charRect = at.getCharacterBounds(lineStart);
+ }
+ if (lineStart == 0) { // special case: we're on the first line!
+ // we found it!
+ } else {
+ offset = offset >> 1; // know boundary within last expansion
+ // ground forward to beginning of line
+ while (offset > 0) {
+ charRect = at.getCharacterBounds(lineStart + offset);
+ if (charRect.y < indexRect.y) { // still before line
+ lineStart += offset;
+ } else {
+ // leave lineStart alone, it's close!
+ }
+ offset = offset >> 1;
+ }
+ // subtract one 'cause we're already too far...
+ lineStart += 1;
+ }
+ return lineStart;
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * Get line info: right index of line
+ *
+ * algorithm: cast back, doubling each time,
+ * 'till find line boundaries
+ *
+ * return -1 if we can't get the info (e.g. index or at passed in
+ * is bogus; etc.)
+ */
+ private int getAccessibleTextLineRightBoundsFromContext(final AccessibleContext ac, final int index) {
+ if(ac == null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ int lineEnd;
+ int offset;
+ Rectangle charRect;
+ Rectangle indexRect = at.getCharacterBounds(index);
+ int textLen = at.getCharCount();
+ if (indexRect == null) {
+ return -1;
+ }
+ // find the end of the line
+ //
+ offset = 1;
+ lineEnd = index + offset > textLen - 1
+ ? textLen - 1 : index + offset;
+ charRect = at.getCharacterBounds(lineEnd);
+ // push past end of line
+ while (charRect != null &&
+ charRect.y <= indexRect.y &&
+ lineEnd < textLen - 1) {
+ offset = offset << 1;
+ lineEnd = index + offset > textLen - 1
+ ? textLen - 1 : index + offset;
+ charRect = at.getCharacterBounds(lineEnd);
+ }
+ if (lineEnd == textLen - 1) { // special case: on the last line!
+ // we found it!
+ } else {
+ offset = offset >> 1; // know boundary within last expansion
+ // pull back to end of line
+ while (offset > 0) {
+ charRect = at.getCharacterBounds(lineEnd - offset);
+ if (charRect.y > indexRect.y) { // still beyond line
+ lineEnd -= offset;
+ } else {
+ // leave lineEnd alone, it's close!
+ }
+ offset = offset >> 1;
+ }
+ // subtract one 'cause we're already too far...
+ lineEnd -= 1;
+ }
+ return lineEnd;
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * Get a range of text; null if indicies are bogus
+ */
+ private String getAccessibleTextRangeFromContext(final AccessibleContext ac,
+ final int start, final int end) {
+ String s = InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ if (ac != null) {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ // start - end is inclusive
+ if (start > end) {
+ return null;
+ }
+ if (end >= at.getCharCount()) {
+ return null;
+ }
+ StringBuffer buf = new StringBuffer(end - start + 1);
+ for (int i = start; i <= end; i++) {
+ buf.append(at.getAtIndex(AccessibleText.CHARACTER, i));
+ }
+ return buf.toString();
+ }
+ }
+ return null;
+ }
+ }, ac);
+ if (s != null) {
+ references.increment(s);
+ return s;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * return the AttributeSet object at a given index from an AccessibleContext
+ */
+ private AttributeSet getAccessibleAttributeSetAtIndexFromContext(final AccessibleContext ac,
+ final int index) {
+ return InvocationUtils.invokeAndWait(new Callable<AttributeSet>() {
+ @Override
+ public AttributeSet call() throws Exception {
+ if (ac != null) {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ AttributeSet as = at.getCharacterAttribute(index);
+ if (as != null) {
+ AccessBridge.this.references.increment(as);
+ return as;
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+
+ /**
+ * return the bounding rectangle at index from an AccessibleContext
+ */
+ private Rectangle getAccessibleTextRectAtIndexFromContext(final AccessibleContext ac,
+ final int index) {
+ // want to do this in global coords, so need to combine w/ac global coords
+ Rectangle r = InvocationUtils.invokeAndWait(new Callable<Rectangle>() {
+ @Override
+ public Rectangle call() throws Exception {
+ // want to do this in global coords, so need to combine w/ac global coords
+ if (ac != null) {
+ AccessibleText at = ac.getAccessibleText();
+ if (at != null) {
+ Rectangle rect = at.getCharacterBounds(index);
+ if (rect != null) {
+ String s = at.getAtIndex(AccessibleText.CHARACTER, index);
+ if (s != null && s.equals("\n")) {
+ rect.width = 0;
+ }
+ return rect;
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ Rectangle acRect = getAccessibleBoundsOnScreenFromContext(ac);
+ if (r != null && acRect != null) {
+ r.translate(acRect.x, acRect.y);
+ return r;
+ }
+ return null;
+ }
+
+ /**
+ * return the AccessibleText character x-coord at index from an AccessibleContext
+ */
+ private int getAccessibleXcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
+ if (ac != null) {
+ Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
+ if (r != null) {
+ return r.x;
+ }
+ } else {
+ debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the AccessibleText character y-coord at index from an AccessibleContext
+ */
+ private int getAccessibleYcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) {
+ if (ac != null) {
+ Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
+ if (r != null) {
+ return r.y;
+ }
+ } else {
+ debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the AccessibleText character height at index from an AccessibleContext
+ */
+ private int getAccessibleHeightTextRectAtIndexFromContext(AccessibleContext ac, int index) {
+ if (ac != null) {
+ Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
+ if (r != null) {
+ return r.height;
+ }
+ } else {
+ debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the AccessibleText character width at index from an AccessibleContext
+ */
+ private int getAccessibleWidthTextRectAtIndexFromContext(AccessibleContext ac, int index) {
+ if (ac != null) {
+ Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index);
+ if (r != null) {
+ return r.width;
+ }
+ } else {
+ debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null");
+ }
+ return -1;
+ }
+
+ /* ===== AttributeSet methods for AccessibleText ===== */
+
+ /**
+ * return the bold setting from an AttributeSet
+ */
+ private boolean getBoldFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isBold(as);
+ } else {
+ debugString("getBoldFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the italic setting from an AttributeSet
+ */
+ private boolean getItalicFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isItalic(as);
+ } else {
+ debugString("getItalicFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the underline setting from an AttributeSet
+ */
+ private boolean getUnderlineFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isUnderline(as);
+ } else {
+ debugString("getUnderlineFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the strikethrough setting from an AttributeSet
+ */
+ private boolean getStrikethroughFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isStrikeThrough(as);
+ } else {
+ debugString("getStrikethroughFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the superscript setting from an AttributeSet
+ */
+ private boolean getSuperscriptFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isSuperscript(as);
+ } else {
+ debugString("getSuperscriptFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the subscript setting from an AttributeSet
+ */
+ private boolean getSubscriptFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.isSubscript(as);
+ } else {
+ debugString("getSubscriptFromAttributeSet; as = null");
+ }
+ return false;
+ }
+
+ /**
+ * return the background color from an AttributeSet
+ */
+ private String getBackgroundColorFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ String s = StyleConstants.getBackground(as).toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getBackgroundColorFromAttributeSet; as = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the foreground color from an AttributeSet
+ */
+ private String getForegroundColorFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ String s = StyleConstants.getForeground(as).toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getForegroundColorFromAttributeSet; as = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the font family from an AttributeSet
+ */
+ private String getFontFamilyFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ String s = StyleConstants.getFontFamily(as).toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ } else {
+ debugString("getFontFamilyFromAttributeSet; as = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the font size from an AttributeSet
+ */
+ private int getFontSizeFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getFontSize(as);
+ } else {
+ debugString("getFontSizeFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the alignment from an AttributeSet
+ */
+ private int getAlignmentFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getAlignment(as);
+ } else {
+ debugString("getAlignmentFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the BiDi level from an AttributeSet
+ */
+ private int getBidiLevelFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getBidiLevel(as);
+ } else {
+ debugString("getBidiLevelFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+
+ /**
+ * return the first line indent from an AttributeSet
+ */
+ private float getFirstLineIndentFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getFirstLineIndent(as);
+ } else {
+ debugString("getFirstLineIndentFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the left indent from an AttributeSet
+ */
+ private float getLeftIndentFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getLeftIndent(as);
+ } else {
+ debugString("getLeftIndentFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the right indent from an AttributeSet
+ */
+ private float getRightIndentFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getRightIndent(as);
+ } else {
+ debugString("getRightIndentFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the line spacing from an AttributeSet
+ */
+ private float getLineSpacingFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getLineSpacing(as);
+ } else {
+ debugString("getLineSpacingFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the space above from an AttributeSet
+ */
+ private float getSpaceAboveFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getSpaceAbove(as);
+ } else {
+ debugString("getSpaceAboveFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * return the space below from an AttributeSet
+ */
+ private float getSpaceBelowFromAttributeSet(AttributeSet as) {
+ if (as != null) {
+ return StyleConstants.getSpaceBelow(as);
+ } else {
+ debugString("getSpaceBelowFromAttributeSet; as = null");
+ }
+ return -1;
+ }
+
+ /**
+ * Enumerate all StyleConstants in the AttributeSet
+ *
+ * We need to check explicitly, 'cause of the HTML package conversion
+ * mechanism (they may not be stored as StyleConstants, just translated
+ * to them when asked).
+ *
+ * (Use convenience methods where they are defined...)
+ *
+ * Not checking the following (which the IBM SNS guidelines says
+ * should be defined):
+ * - ComponentElementName
+ * - IconElementName
+ * - NameAttribute
+ * - ResolveAttribute
+ */
+ private String expandStyleConstants(AttributeSet as) {
+ Color c;
+ Object o;
+ String attrString = "";
+
+ // ---------- check for various Character Constants
+
+ attrString += "BidiLevel = " + StyleConstants.getBidiLevel(as);
+
+ final Component comp = StyleConstants.getComponent(as);
+ if (comp != null) {
+ if (comp instanceof Accessible) {
+ final AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return comp.getAccessibleContext();
+ }
+ }, comp);
+ if (ac != null) {
+ attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return ac.getAccessibleName();
+ }
+ }, ac);
+ } else {
+ attrString += "; Innaccessible Component = " + comp;
+ }
+ } else {
+ attrString += "; Innaccessible Component = " + comp;
+ }
+ }
+
+ Icon i = StyleConstants.getIcon(as);
+ if (i != null) {
+ if (i instanceof ImageIcon) {
+ attrString += "; ImageIcon = " + ((ImageIcon) i).getDescription();
+ } else {
+ attrString += "; Icon = " + i;
+ }
+ }
+
+ attrString += "; FontFamily = " + StyleConstants.getFontFamily(as);
+
+ attrString += "; FontSize = " + StyleConstants.getFontSize(as);
+
+ if (StyleConstants.isBold(as)) {
+ attrString += "; bold";
+ }
+
+ if (StyleConstants.isItalic(as)) {
+ attrString += "; italic";
+ }
+
+ if (StyleConstants.isUnderline(as)) {
+ attrString += "; underline";
+ }
+
+ if (StyleConstants.isStrikeThrough(as)) {
+ attrString += "; strikethrough";
+ }
+
+ if (StyleConstants.isSuperscript(as)) {
+ attrString += "; superscript";
+ }
+
+ if (StyleConstants.isSubscript(as)) {
+ attrString += "; subscript";
+ }
+
+ c = StyleConstants.getForeground(as);
+ if (c != null) {
+ attrString += "; Foreground = " + c;
+ }
+
+ c = StyleConstants.getBackground(as);
+ if (c != null) {
+ attrString += "; Background = " + c;
+ }
+
+ attrString += "; FirstLineIndent = " + StyleConstants.getFirstLineIndent(as);
+
+ attrString += "; RightIndent = " + StyleConstants.getRightIndent(as);
+
+ attrString += "; LeftIndent = " + StyleConstants.getLeftIndent(as);
+
+ attrString += "; LineSpacing = " + StyleConstants.getLineSpacing(as);
+
+ attrString += "; SpaceAbove = " + StyleConstants.getSpaceAbove(as);
+
+ attrString += "; SpaceBelow = " + StyleConstants.getSpaceBelow(as);
+
+ attrString += "; Alignment = " + StyleConstants.getAlignment(as);
+
+ TabSet ts = StyleConstants.getTabSet(as);
+ if (ts != null) {
+ attrString += "; TabSet = " + ts;
+ }
+
+ return attrString;
+ }
+
+
+ /* ===== AccessibleValue methods ===== */
+
+ /**
+ * return the AccessibleValue current value from an AccessibleContext
+ * returned using a String 'cause the value is a java Number
+ *
+ */
+ private String getCurrentAccessibleValueFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
+ @Override
+ public Number call() throws Exception {
+ AccessibleValue av = ac.getAccessibleValue();
+ if (av == null) return null;
+ return av.getCurrentAccessibleValue();
+ }
+ }, ac);
+ if (value != null) {
+ String s = value.toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ }
+ } else {
+ debugString("getCurrentAccessibleValueFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the AccessibleValue maximum value from an AccessibleContext
+ * returned using a String 'cause the value is a java Number
+ *
+ */
+ private String getMaximumAccessibleValueFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
+ @Override
+ public Number call() throws Exception {
+ AccessibleValue av = ac.getAccessibleValue();
+ if (av == null) return null;
+ return av.getMaximumAccessibleValue();
+ }
+ }, ac);
+ if (value != null) {
+ String s = value.toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ }
+ } else {
+ debugString("getMaximumAccessibleValueFromContext; ac = null");
+ }
+ return null;
+ }
+
+ /**
+ * return the AccessibleValue minimum value from an AccessibleContext
+ * returned using a String 'cause the value is a java Number
+ *
+ */
+ private String getMinimumAccessibleValueFromContext(final AccessibleContext ac) {
+ if (ac != null) {
+ final Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
+ @Override
+ public Number call() throws Exception {
+ AccessibleValue av = ac.getAccessibleValue();
+ if (av == null) return null;
+ return av.getMinimumAccessibleValue();
+ }
+ }, ac);
+ if (value != null) {
+ String s = value.toString();
+ if (s != null) {
+ references.increment(s);
+ return s;
+ }
+ }
+ } else {
+ debugString("getMinimumAccessibleValueFromContext; ac = null");
+ }
+ return null;
+ }
+
+
+ /* ===== AccessibleSelection methods ===== */
+
+ /**
+ * add to the AccessibleSelection of an AccessibleContext child i
+ *
+ */
+ private void addAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
+ try {
+ InvocationUtils.invokeAndWait(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ as.addAccessibleSelection(i);
+ }
+ }
+ return null;
+ }
+ }, ac);
+ } catch(Exception e){}
+ }
+
+ /**
+ * clear all of the AccessibleSelection of an AccessibleContex
+ *
+ */
+ private void clearAccessibleSelectionFromContext(final AccessibleContext ac) {
+ try {
+ InvocationUtils.invokeAndWait(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ as.clearAccessibleSelection();
+ }
+ return null;
+ }
+ }, ac);
+ } catch(Exception e){}
+
+ }
+
+ /**
+ * get the AccessibleContext of the i-th AccessibleSelection of an AccessibleContext
+ *
+ */
+ private AccessibleContext getAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ Accessible a = as.getAccessibleSelection(i);
+ if (a == null)
+ return null;
+ else
+ return a.getAccessibleContext();
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * get number of things selected in the AccessibleSelection of an AccessibleContext
+ *
+ */
+ private int getAccessibleSelectionCountFromContext(final AccessibleContext ac) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ return as.getAccessibleSelectionCount();
+ }
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /**
+ * return true if the i-th child of the AccessibleSelection of an AccessibleContext is selected
+ *
+ */
+ private boolean isAccessibleChildSelectedFromContext(final AccessibleContext ac, final int i) {
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ return as.isAccessibleChildSelected(i);
+ }
+ }
+ return false;
+ }
+ }, ac);
+ }
+
+ /**
+ * remove the i-th child from the AccessibleSelection of an AccessibleContext
+ *
+ */
+ private void removeAccessibleSelectionFromContext(final AccessibleContext ac, final int i) {
+ InvocationUtils.invokeAndWait(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ as.removeAccessibleSelection(i);
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * select all (if possible) of the children of the AccessibleSelection of an AccessibleContext
+ *
+ */
+ private void selectAllAccessibleSelectionFromContext(final AccessibleContext ac) {
+ InvocationUtils.invokeAndWait(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ if (ac != null) {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as != null) {
+ as.selectAllAccessibleSelection();
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ // ======== AccessibleTable ========
+
+ ConcurrentHashMap<AccessibleTable,AccessibleContext> hashtab = new ConcurrentHashMap<>();
+
+ /**
+ * returns the AccessibleTable for an AccessibleContext
+ */
+ private AccessibleTable getAccessibleTableFromContext(final AccessibleContext ac) {
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
+ @Override
+ public AccessibleTable call() throws Exception {
+ if (ac != null) {
+ AccessibleTable at = ac.getAccessibleTable();
+ if (at != null) {
+ AccessBridge.this.hashtab.put(at, ac);
+ return at;
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+
+ /*
+ * returns the AccessibleContext that contains an AccessibleTable
+ */
+ private AccessibleContext getContextFromAccessibleTable(AccessibleTable at) {
+ return hashtab.get(at);
+ }
+
+ /*
+ * returns the row count for an AccessibleTable
+ */
+ private int getAccessibleTableRowCount(final AccessibleContext ac) {
+ debugString("##### getAccessibleTableRowCount");
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (ac != null) {
+ AccessibleTable at = ac.getAccessibleTable();
+ if (at != null) {
+ return at.getAccessibleRowCount();
+ }
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns the column count for an AccessibleTable
+ */
+ private int getAccessibleTableColumnCount(final AccessibleContext ac) {
+ debugString("##### getAccessibleTableColumnCount");
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (ac != null) {
+ AccessibleTable at = ac.getAccessibleTable();
+ if (at != null) {
+ return at.getAccessibleColumnCount();
+ }
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns the AccessibleContext for an AccessibleTable cell
+ */
+ private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at,
+ final int row, final int column) {
+ debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass());
+ if (at == null) return null;
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ if (!(at instanceof AccessibleContext)) {
+ Accessible a = at.getAccessibleAt(row, column);
+ if (a != null) {
+ return a.getAccessibleContext();
+ }
+ } else {
+ // work-around for AccessibleJTable.getCurrentAccessibleContext returning
+ // wrong renderer component when cell contains more than one component
+ AccessibleContext ac = (AccessibleContext) at;
+ Accessible parent = ac.getAccessibleParent();
+ if (parent != null) {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ Accessible child =
+ parent.getAccessibleContext().getAccessibleChild(indexInParent);
+ if (child instanceof JTable) {
+ JTable table = (JTable) child;
+
+ TableCellRenderer renderer = table.getCellRenderer(row, column);
+ if (renderer == null) {
+ Class<?> columnClass = table.getColumnClass(column);
+ renderer = table.getDefaultRenderer(columnClass);
+ }
+ Component component =
+ renderer.getTableCellRendererComponent(table, table.getValueAt(row, column),
+ false, false, row, column);
+ if (component instanceof Accessible) {
+ return component.getAccessibleContext();
+ }
+ }
+ }
+ }
+ return null;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns the index of a cell at a given row and column in an AccessibleTable
+ */
+ private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) {
+ debugString("##### getAccessibleTableCellIndex: at="+at);
+ if (at != null) {
+ int cellIndex = row *
+ InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleColumnCount();
+ }
+ }, getContextFromAccessibleTable(at)) +
+ column;
+ debugString(" ##### getAccessibleTableCellIndex="+cellIndex);
+ return cellIndex;
+ }
+ debugString(" ##### getAccessibleTableCellIndex FAILED");
+ return -1;
+ }
+
+ /*
+ * returns the row extent of a cell at a given row and column in an AccessibleTable
+ */
+ private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) {
+ debugString("##### getAccessibleTableCellRowExtent");
+ if (at != null) {
+ int rowExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleRowExtentAt(row, column);
+ }
+ },
+ getContextFromAccessibleTable(at));
+ debugString(" ##### getAccessibleTableCellRowExtent="+rowExtent);
+ return rowExtent;
+ }
+ debugString(" ##### getAccessibleTableCellRowExtent FAILED");
+ return -1;
+ }
+
+ /*
+ * returns the column extent of a cell at a given row and column in an AccessibleTable
+ */
+ private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) {
+ debugString("##### getAccessibleTableCellColumnExtent");
+ if (at != null) {
+ int columnExtent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleColumnExtentAt(row, column);
+ }
+ },
+ getContextFromAccessibleTable(at));
+ debugString(" ##### getAccessibleTableCellColumnExtent="+columnExtent);
+ return columnExtent;
+ }
+ debugString(" ##### getAccessibleTableCellColumnExtent FAILED");
+ return -1;
+ }
+
+ /*
+ * returns whether a cell is selected at a given row and column in an AccessibleTable
+ */
+ private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row,
+ final int column) {
+ debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]");
+ if (at == null)
+ return false;
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ boolean isSelected = false;
+ Accessible a = at.getAccessibleAt(row, column);
+ if (a != null) {
+ AccessibleContext ac = a.getAccessibleContext();
+ if (ac == null)
+ return false;
+ AccessibleStateSet as = ac.getAccessibleStateSet();
+ if (as != null) {
+ isSelected = as.contains(AccessibleState.SELECTED);
+ }
+ }
+ return isSelected;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns an AccessibleTable that represents the row header in an
+ * AccessibleTable
+ */
+ private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) {
+ debugString(" ##### getAccessibleTableRowHeader called");
+ AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
+ @Override
+ public AccessibleTable call() throws Exception {
+ if (ac != null) {
+ AccessibleTable at = ac.getAccessibleTable();
+ if (at != null) {
+ return at.getAccessibleRowHeader();
+ }
+ }
+ return null;
+ }
+ }, ac);
+ if (at != null) {
+ hashtab.put(at, ac);
+ }
+ return at;
+ }
+
+ /*
+ * returns an AccessibleTable that represents the column header in an
+ * AccessibleTable
+ */
+ private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) {
+ debugString("##### getAccessibleTableColumnHeader");
+ if (ac == null)
+ return null;
+ AccessibleTable at = InvocationUtils.invokeAndWait(new Callable<AccessibleTable>() {
+ @Override
+ public AccessibleTable call() throws Exception {
+ // workaround for getAccessibleColumnHeader NPE
+ // when the table header is null
+ Accessible parent = ac.getAccessibleParent();
+ if (parent != null) {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ Accessible child =
+ parent.getAccessibleContext().getAccessibleChild(indexInParent);
+ if (child instanceof JTable) {
+ JTable table = (JTable) child;
+ if (table.getTableHeader() == null) {
+ return null;
+ }
+ }
+ }
+ AccessibleTable at = ac.getAccessibleTable();
+ if (at != null) {
+ return at.getAccessibleColumnHeader();
+ }
+ return null;
+ }
+ }, ac);
+ if (at != null) {
+ hashtab.put(at, ac);
+ }
+ return at;
+ }
+
+ /*
+ * returns the number of row headers in an AccessibleTable that represents
+ * the row header in an AccessibleTable
+ */
+ private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) {
+
+ debugString(" ##### getAccessibleTableRowHeaderRowCount called");
+ if (ac != null) {
+ final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
+ if (atRowHeader != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (atRowHeader != null) {
+ return atRowHeader.getAccessibleRowCount();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+ }
+ return -1;
+ }
+
+ /*
+ * returns the number of column headers in an AccessibleTable that represents
+ * the row header in an AccessibleTable
+ */
+ private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) {
+ debugString(" ##### getAccessibleTableRowHeaderColumnCount called");
+ if (ac != null) {
+ final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac);
+ if (atRowHeader != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (atRowHeader != null) {
+ return atRowHeader.getAccessibleColumnCount();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+ }
+ debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED");
+ return -1;
+ }
+
+ /*
+ * returns the number of row headers in an AccessibleTable that represents
+ * the column header in an AccessibleTable
+ */
+ private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) {
+
+ debugString("##### getAccessibleTableColumnHeaderRowCount");
+ if (ac != null) {
+ final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
+ if (atColumnHeader != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (atColumnHeader != null) {
+ return atColumnHeader.getAccessibleRowCount();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+ }
+ debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED");
+ return -1;
+ }
+
+ /*
+ * returns the number of column headers in an AccessibleTable that represents
+ * the column header in an AccessibleTable
+ */
+ private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) {
+
+ debugString("##### getAccessibleTableColumnHeaderColumnCount");
+ if (ac != null) {
+ final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac);
+ if (atColumnHeader != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (atColumnHeader != null) {
+ return atColumnHeader.getAccessibleColumnCount();
+ }
+ return -1;
+ }
+ }, ac);
+ }
+ }
+ debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED");
+ return -1;
+ }
+
+ /*
+ * returns the description of a row header in an AccessibleTable
+ */
+ private AccessibleContext getAccessibleTableRowDescription(final AccessibleTable table,
+ final int row) {
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ if (table != null) {
+ Accessible a = table.getAccessibleRowDescription(row);
+ if (a != null) {
+ return a.getAccessibleContext();
+ }
+ }
+ return null;
+ }
+ }, getContextFromAccessibleTable(table));
+ }
+
+ /*
+ * returns the description of a column header in an AccessibleTable
+ */
+ private AccessibleContext getAccessibleTableColumnDescription(final AccessibleTable at,
+ final int column) {
+ if (at == null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ Accessible a = at.getAccessibleColumnDescription(column);
+ if (a != null) {
+ return a.getAccessibleContext();
+ }
+ return null;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns the number of rows selected in an AccessibleTable
+ */
+ private int getAccessibleTableRowSelectionCount(final AccessibleTable at) {
+ if (at != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ int[] selections = at.getSelectedAccessibleRows();
+ if (selections != null)
+ return selections.length;
+ else
+ return -1;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+ return -1;
+ }
+
+ /*
+ * returns the row number of the i-th selected row in an AccessibleTable
+ */
+ private int getAccessibleTableRowSelections(final AccessibleTable at, final int i) {
+ if (at != null) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ int[] selections = at.getSelectedAccessibleRows();
+ if (selections.length > i) {
+ return selections[i];
+ }
+ return -1;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+ return -1;
+ }
+
+ /*
+ * returns whether a row is selected in an AccessibleTable
+ */
+ private boolean isAccessibleTableRowSelected(final AccessibleTable at,
+ final int row) {
+ if (at == null)
+ return false;
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return at.isAccessibleRowSelected(row);
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns whether a column is selected in an AccessibleTable
+ */
+ private boolean isAccessibleTableColumnSelected(final AccessibleTable at,
+ final int column) {
+ if (at == null)
+ return false;
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return at.isAccessibleColumnSelected(column);
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns the number of columns selected in an AccessibleTable
+ */
+ private int getAccessibleTableColumnSelectionCount(final AccessibleTable at) {
+ if (at == null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ int[] selections = at.getSelectedAccessibleColumns();
+ if (selections != null)
+ return selections.length;
+ else
+ return -1;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /*
+ * returns the row number of the i-th selected row in an AccessibleTable
+ */
+ private int getAccessibleTableColumnSelections(final AccessibleTable at, final int i) {
+ if (at == null)
+ return -1;
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ int[] selections = at.getSelectedAccessibleColumns();
+ if (selections != null && selections.length > i) {
+ return selections[i];
+ }
+ return -1;
+ }
+ }, getContextFromAccessibleTable(at));
+ }
+
+ /* ===== AccessibleExtendedTable (since 1.4) ===== */
+
+ /*
+ * returns the row number for a cell at a given index in an AccessibleTable
+ */
+ private int getAccessibleTableRow(final AccessibleTable at, int index) {
+ if (at == null)
+ return -1;
+ int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleColumnCount();
+ }
+ }, getContextFromAccessibleTable(at));
+ return index / colCount;
+ }
+
+ /*
+ * returns the column number for a cell at a given index in an AccessibleTable
+ */
+ private int getAccessibleTableColumn(final AccessibleTable at, int index) {
+ if (at == null)
+ return -1;
+ int colCount=InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleColumnCount();
+ }
+ }, getContextFromAccessibleTable(at));
+ return index % colCount;
+ }
+
+ /*
+ * returns the index for a cell at a given row and column in an
+ * AccessibleTable
+ */
+ private int getAccessibleTableIndex(final AccessibleTable at, int row, int column) {
+ if (at == null)
+ return -1;
+ int colCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return at.getAccessibleColumnCount();
+ }
+ }, getContextFromAccessibleTable(at));
+ return row * colCount + column;
+ }
+
+ // ===== AccessibleRelationSet =====
+
+ /*
+ * returns the number of relations in the AccessibleContext's
+ * AccessibleRelationSet
+ */
+ private int getAccessibleRelationCount(final AccessibleContext ac) {
+ {
+ if (ac != null) {
+ AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
+ @Override
+ public AccessibleRelationSet call() throws Exception {
+ return ac.getAccessibleRelationSet();
+ }
+ }, ac);
+ if (ars != null)
+ return ars.size();
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * returns the ith relation key in the AccessibleContext's
+ * AccessibleRelationSet
+ */
+ private String getAccessibleRelationKey(final AccessibleContext ac, final int i) {
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ if (ac != null) {
+ AccessibleRelationSet ars = ac.getAccessibleRelationSet();
+ if (ars != null) {
+ AccessibleRelation[] relations = ars.toArray();
+ if (relations != null && i >= 0 && i < relations.length) {
+ return relations[i].getKey();
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns the number of targets in a relation in the AccessibleContext's
+ * AccessibleRelationSet
+ */
+ private int getAccessibleRelationTargetCount(final AccessibleContext ac, final int i) {
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ if (ac != null) {
+ AccessibleRelationSet ars = ac.getAccessibleRelationSet();
+ if (ars != null) {
+ AccessibleRelation[] relations = ars.toArray();
+ if (relations != null && i >= 0 && i < relations.length) {
+ Object[] targets = relations[i].getTarget();
+ return targets.length;
+ }
+ }
+ }
+ return -1;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns the jth target in the ith relation in the AccessibleContext's
+ * AccessibleRelationSet
+ */
+ private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac,
+ final int i, final int j) {
+ debugString("***** getAccessibleRelationTarget");
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ if (ac != null) {
+ AccessibleRelationSet ars = ac.getAccessibleRelationSet();
+ if (ars != null) {
+ AccessibleRelation[] relations = ars.toArray();
+ if (relations != null && i >= 0 && i < relations.length) {
+ Object[] targets = relations[i].getTarget();
+ if (targets != null && j >= 0 & j < targets.length) {
+ Object o = targets[j];
+ if (o instanceof Accessible) {
+ return ((Accessible) o).getAccessibleContext();
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ // ========= AccessibleHypertext =========
+
+ private Map<AccessibleHypertext, AccessibleContext> hyperTextContextMap = new WeakHashMap<>();
+ private Map<AccessibleHyperlink, AccessibleContext> hyperLinkContextMap = new WeakHashMap<>();
+
+ /*
+ * Returns the AccessibleHypertext
+ */
+ private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) {
+ debugString("getAccessibleHyperlink");
+ if (ac==null)
+ return null;
+ AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable<AccessibleHypertext>() {
+ @Override
+ public AccessibleHypertext call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (!(at instanceof AccessibleHypertext)) {
+ return null;
+ }
+ return ((AccessibleHypertext) at);
+ }
+ }, ac);
+ hyperTextContextMap.put(hypertext, ac);
+ return hypertext;
+ }
+
+ /*
+ * Returns the number of AccessibleHyperlinks
+ */
+ private int getAccessibleHyperlinkCount(AccessibleContext ac) {
+ debugString("getAccessibleHyperlinkCount");
+ if (ac == null) {
+ return 0;
+ }
+ final AccessibleHypertext hypertext = getAccessibleHypertext(ac);
+ if (hypertext == null) {
+ return 0;
+ }
+ //return hypertext.getLinkCount();
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return hypertext.getLinkCount();
+ }
+ }, ac);
+ }
+
+ /*
+ * Returns the hyperlink at the specified index
+ */
+ private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) {
+ debugString("getAccessibleHyperlink");
+ if (hypertext == null) {
+ return null;
+ }
+ AccessibleContext ac = hyperTextContextMap.get(hypertext);
+ if ( i < 0 || i >=
+ InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return hypertext.getLinkCount();
+ }
+ }, ac) ) {
+ return null;
+ }
+ AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable<AccessibleHyperlink>() {
+ @Override
+ public AccessibleHyperlink call() throws Exception {
+ AccessibleHyperlink link = hypertext.getLink(i);
+ if (link == null || (!link.isValid())) {
+ return null;
+ }
+ return link;
+ }
+ }, ac);
+ hyperLinkContextMap.put(acLink, ac);
+ return acLink;
+ }
+
+ /*
+ * Returns the hyperlink object description
+ */
+ private String getAccessibleHyperlinkText(final AccessibleHyperlink link) {
+ debugString("getAccessibleHyperlinkText");
+ if (link == null) {
+ return null;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ Object o = link.getAccessibleActionDescription(0);
+ if (o != null) {
+ return o.toString();
+ }
+ return null;
+ }
+ }, hyperLinkContextMap.get(link));
+ }
+
+ /*
+ * Returns the hyperlink URL
+ */
+ private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) {
+ debugString("getAccessibleHyperlinkURL");
+ if (link == null) {
+ return null;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ Object o = link.getAccessibleActionObject(0);
+ if (o != null) {
+ return o.toString();
+ } else {
+ return null;
+ }
+ }
+ }, hyperLinkContextMap.get(link));
+ }
+
+ /*
+ * Returns the start index of the hyperlink text
+ */
+ private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) {
+ debugString("getAccessibleHyperlinkStartIndex");
+ if (link == null) {
+ return -1;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return link.getStartIndex();
+ }
+ }, hyperLinkContextMap.get(link));
+ }
+
+ /*
+ * Returns the end index of the hyperlink text
+ */
+ private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) {
+ debugString("getAccessibleHyperlinkEndIndex");
+ if (link == null) {
+ return -1;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return link.getEndIndex();
+ }
+ }, hyperLinkContextMap.get(link));
+ }
+
+ /*
+ * Returns the index into an array of hyperlinks that
+ * is associated with this character index, or -1 if there
+ * is no hyperlink associated with this index.
+ */
+ private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) {
+ debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex);
+ if (hypertext == null) {
+ return -1;
+ }
+ int linkIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return hypertext.getLinkIndex(charIndex);
+ }
+ }, hyperTextContextMap.get(hypertext));
+ debugString("getAccessibleHypertextLinkIndex returning "+linkIndex);
+ return linkIndex;
+ }
+
+ /*
+ * Actives the hyperlink
+ */
+ private boolean activateAccessibleHyperlink(final AccessibleContext ac,
+ final AccessibleHyperlink link) {
+ //debugString("activateAccessibleHyperlink: link = "+link.getClass());
+ if (link == null) {
+ return false;
+ }
+ boolean retval = InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return link.doAccessibleAction(0);
+ }
+ }, ac);
+ debugString("activateAccessibleHyperlink: returning = "+retval);
+ return retval;
+ }
+
+
+ // ============ AccessibleKeyBinding =============
+
+ /*
+ * returns the component mnemonic
+ */
+ private KeyStroke getMnemonic(final AccessibleContext ac) {
+ if (ac == null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
+ @Override
+ public KeyStroke call() throws Exception {
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (!(comp instanceof AccessibleExtendedComponent)) {
+ return null;
+ }
+ AccessibleExtendedComponent aec = (AccessibleExtendedComponent) comp;
+ if (aec != null) {
+ AccessibleKeyBinding akb = aec.getAccessibleKeyBinding();
+ if (akb != null) {
+ Object o = akb.getAccessibleKeyBinding(0);
+ if (o instanceof KeyStroke) {
+ return (KeyStroke) o;
+ }
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns the JMenuItem accelerator
+ */
+ private KeyStroke getAccelerator(final AccessibleContext ac) {
+ // workaround for getAccessibleKeyBinding not returning the
+ // JMenuItem accelerator
+ if (ac == null)
+ return null;
+ return InvocationUtils.invokeAndWait(new Callable<KeyStroke>() {
+ @Override
+ public KeyStroke call() throws Exception {
+ Accessible parent = ac.getAccessibleParent();
+ if (parent instanceof Accessible) {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ Accessible child =
+ parent.getAccessibleContext().getAccessibleChild(indexInParent);
+ if (child instanceof JMenuItem) {
+ JMenuItem menuItem = (JMenuItem) child;
+ if (menuItem == null)
+ return null;
+ KeyStroke keyStroke = menuItem.getAccelerator();
+ return keyStroke;
+ }
+ }
+ return null;
+ }
+ }, ac);
+ }
+
+ /*
+ * returns 1-24 to indicate which F key is being used for a shortcut or 0 otherwise
+ */
+ private int fKeyNumber(KeyStroke keyStroke) {
+ if (keyStroke == null)
+ return 0;
+ int fKey = 0;
+ String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
+ if (keyText != null && (keyText.length() == 2 || keyText.length() == 3)) {
+ String prefix = keyText.substring(0, 1);
+ if (prefix.equals("F")) {
+ try {
+ int suffix = Integer.parseInt(keyText.substring(1));
+ if (suffix >= 1 && suffix <= 24) {
+ fKey = suffix;
+ }
+ } catch (Exception e) { // ignore NumberFormatException
+ }
+ }
+ }
+ return fKey;
+ }
+
+ /*
+ * returns one of several important control characters or 0 otherwise
+ */
+ private int controlCode(KeyStroke keyStroke) {
+ if (keyStroke == null)
+ return 0;
+ int code = keyStroke.getKeyCode();
+ switch (code) {
+ case KeyEvent.VK_BACK_SPACE:
+ case KeyEvent.VK_DELETE:
+ case KeyEvent.VK_DOWN:
+ case KeyEvent.VK_END:
+ case KeyEvent.VK_HOME:
+ case KeyEvent.VK_INSERT:
+ case KeyEvent.VK_KP_DOWN:
+ case KeyEvent.VK_KP_LEFT:
+ case KeyEvent.VK_KP_RIGHT:
+ case KeyEvent.VK_KP_UP:
+ case KeyEvent.VK_LEFT:
+ case KeyEvent.VK_PAGE_DOWN:
+ case KeyEvent.VK_PAGE_UP:
+ case KeyEvent.VK_RIGHT:
+ case KeyEvent.VK_UP:
+ break;
+ default:
+ code = 0;
+ break;
+ }
+ return code;
+ }
+
+ /*
+ * returns the KeyStoke character
+ */
+ private char getKeyChar(KeyStroke keyStroke) {
+ // If the shortcut is an FKey return 1-24
+ if (keyStroke == null)
+ return 0;
+ int fKey = fKeyNumber(keyStroke);
+ if (fKey != 0) {
+ // return 0x00000001 through 0x00000018
+ debugString(" Shortcut is: F" + fKey);
+ return (char)fKey;
+ }
+ // If the accelerator is a control character, return it
+ int keyCode = controlCode(keyStroke);
+ if (keyCode != 0) {
+ debugString(" Shortcut is control character: " + Integer.toHexString(keyCode));
+ return (char)keyCode;
+ }
+ String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());
+ debugString(" Shortcut is: " + keyText);
+ if (keyText != null || keyText.length() > 0) {
+ CharSequence seq = keyText.subSequence(0, 1);
+ if (seq != null || seq.length() > 0) {
+ return seq.charAt(0);
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * returns the KeyStroke modifiers as an int
+ */
+ private int getModifiers(KeyStroke keyStroke) {
+ if (keyStroke == null)
+ return 0;
+ debugString("In AccessBridge.getModifiers");
+ // modifiers is a bit strip where bits 0-7 indicate a traditional modifier
+ // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates
+ // a control code shortcut such as the delete key.
+
+ int modifiers = 0;
+ // Is the shortcut an FKey?
+ if (fKeyNumber(keyStroke) != 0) {
+ modifiers |= 1 << 8;
+ }
+ // Is the shortcut a control code?
+ if (controlCode(keyStroke) != 0) {
+ modifiers |= 1 << 9;
+ }
+ // The following is needed in order to handle translated modifiers.
+ // getKeyModifiersText doesn't work because for example in German Strg is
+ // returned for Ctrl.
+
+ // There can be more than one modifier, e.g. if the modifier is ctrl + shift + B
+ // the toString text is "shift ctrl pressed B". Need to parse through that.
+ StringTokenizer st = new StringTokenizer(keyStroke.toString());
+ while (st.hasMoreTokens()) {
+ String text = st.nextToken();
+ // Meta+Ctrl+Alt+Shift
+ // 0-3 are shift, ctrl, meta, alt
+ // 4-7 are for Solaris workstations (though not being used)
+ if (text.startsWith("met")) {
+ debugString(" found meta");
+ modifiers |= ActionEvent.META_MASK;
+ }
+ if (text.startsWith("ctr")) {
+ debugString(" found ctrl");
+ modifiers |= ActionEvent.CTRL_MASK;
+ }
+ if (text.startsWith("alt")) {
+ debugString(" found alt");
+ modifiers |= ActionEvent.ALT_MASK;
+ }
+ if (text.startsWith("shi")) {
+ debugString(" found shift");
+ modifiers |= ActionEvent.SHIFT_MASK;
+ }
+ }
+ debugString(" returning modifiers: 0x" + Integer.toHexString(modifiers));
+ return modifiers;
+ }
+
+ /*
+ * returns the number of key bindings associated with this context
+ */
+ private int getAccessibleKeyBindingsCount(AccessibleContext ac) {
+ if (ac == null)
+ return 0;
+ int count = 0;
+
+ if (getMnemonic(ac) != null) {
+ count++;
+ }
+ if (getAccelerator(ac) != null) {
+ count++;
+ }
+ return count;
+ }
+
+ /*
+ * returns the key binding character at the specified index
+ */
+ private char getAccessibleKeyBindingChar(AccessibleContext ac, int index) {
+ if (ac == null)
+ return 0;
+ if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
+ KeyStroke keyStroke = getAccelerator(ac);
+ if (keyStroke != null) {
+ return getKeyChar(keyStroke);
+ }
+ }
+ if (index == 0) { // mnemonic
+ KeyStroke keyStroke = getMnemonic(ac);
+ if (keyStroke != null) {
+ return getKeyChar(keyStroke);
+ }
+ } else if (index == 1) { // accelerator
+ KeyStroke keyStroke = getAccelerator(ac);
+ if (keyStroke != null) {
+ return getKeyChar(keyStroke);
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * returns the key binding modifiers at the specified index
+ */
+ private int getAccessibleKeyBindingModifiers(AccessibleContext ac, int index) {
+ if (ac == null)
+ return 0;
+ if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic
+ KeyStroke keyStroke = getAccelerator(ac);
+ if (keyStroke != null) {
+ return getModifiers(keyStroke);
+ }
+ }
+ if (index == 0) { // mnemonic
+ KeyStroke keyStroke = getMnemonic(ac);
+ if (keyStroke != null) {
+ return getModifiers(keyStroke);
+ }
+ } else if (index == 1) { // accelerator
+ KeyStroke keyStroke = getAccelerator(ac);
+ if (keyStroke != null) {
+ return getModifiers(keyStroke);
+ }
+ }
+ return 0;
+ }
+
+ // ========== AccessibleIcon ============
+
+ /*
+ * return the number of icons associated with this context
+ */
+ private int getAccessibleIconsCount(final AccessibleContext ac) {
+ debugString("getAccessibleIconsCount");
+ if (ac == null) {
+ return 0;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleIcon[] ai = ac.getAccessibleIcon();
+ if (ai == null) {
+ return 0;
+ }
+ return ai.length;
+ }
+ }, ac);
+ }
+
+ /*
+ * return icon description at the specified index
+ */
+ private String getAccessibleIconDescription(final AccessibleContext ac, final int index) {
+ debugString("getAccessibleIconDescription: index = "+index);
+ if (ac == null) {
+ return null;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleIcon[] ai = ac.getAccessibleIcon();
+ if (ai == null || index < 0 || index >= ai.length) {
+ return null;
+ }
+ return ai[index].getAccessibleIconDescription();
+ }
+ }, ac);
+ }
+
+ /*
+ * return icon height at the specified index
+ */
+ private int getAccessibleIconHeight(final AccessibleContext ac, final int index) {
+ debugString("getAccessibleIconHeight: index = "+index);
+ if (ac == null) {
+ return 0;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleIcon[] ai = ac.getAccessibleIcon();
+ if (ai == null || index < 0 || index >= ai.length) {
+ return 0;
+ }
+ return ai[index].getAccessibleIconHeight();
+ }
+ }, ac);
+ }
+
+ /*
+ * return icon width at the specified index
+ */
+ private int getAccessibleIconWidth(final AccessibleContext ac, final int index) {
+ debugString("getAccessibleIconWidth: index = "+index);
+ if (ac == null) {
+ return 0;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleIcon[] ai = ac.getAccessibleIcon();
+ if (ai == null || index < 0 || index >= ai.length) {
+ return 0;
+ }
+ return ai[index].getAccessibleIconWidth();
+ }
+ }, ac);
+ }
+
+ // ========= AccessibleAction ===========
+
+ /*
+ * return the number of icons associated with this context
+ */
+ private int getAccessibleActionsCount(final AccessibleContext ac) {
+ debugString("getAccessibleActionsCount");
+ if (ac == null) {
+ return 0;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa == null)
+ return 0;
+ return aa.getAccessibleActionCount();
+ }
+ }, ac);
+ }
+
+ /*
+ * return icon description at the specified index
+ */
+ private String getAccessibleActionName(final AccessibleContext ac, final int index) {
+ debugString("getAccessibleActionName: index = "+index);
+ if (ac == null) {
+ return null;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa == null) {
+ return null;
+ }
+ return aa.getAccessibleActionDescription(index);
+ }
+ }, ac);
+ }
+ /*
+ * return icon description at the specified index
+ */
+ private boolean doAccessibleActions(final AccessibleContext ac, final String name) {
+ debugString("doAccessibleActions: action name = "+name);
+ if (ac == null || name == null) {
+ return false;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa == null) {
+ return false;
+ }
+ int index = -1;
+ int numActions = aa.getAccessibleActionCount();
+ for (int i = 0; i < numActions; i++) {
+ String actionName = aa.getAccessibleActionDescription(i);
+ if (name.equals(actionName)) {
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) {
+ return false;
+ }
+ boolean retval = aa.doAccessibleAction(index);
+ return retval;
+ }
+ }, ac);
+ }
+
+ /* ===== AT utility methods ===== */
+
+ /**
+ * Sets the contents of an AccessibleContext that
+ * implements AccessibleEditableText with the
+ * specified text string.
+ * Returns whether successful.
+ */
+ private boolean setTextContents(final AccessibleContext ac, final String text) {
+ debugString("setTextContents: ac = "+ac+"; text = "+text);
+
+ if (! (ac instanceof AccessibleEditableText)) {
+ debugString(" ac not instanceof AccessibleEditableText: "+ac);
+ return false;
+ }
+ if (text == null) {
+ debugString(" text is null");
+ return false;
+ }
+
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ // check whether the text field is editable
+ AccessibleStateSet ass = ac.getAccessibleStateSet();
+ if (!ass.contains(AccessibleState.ENABLED)) {
+ return false;
+ }
+ ((AccessibleEditableText) ac).setTextContents(text);
+ return true;
+ }
+ }, ac);
+ }
+
+ /**
+ * Returns the Accessible Context of an Internal Frame object that is
+ * the ancestor of a given object. If the object is an Internal Frame
+ * object or an Internal Frame ancestor object was found, returns the
+ * object's AccessibleContext.
+ * If there is no ancestor object that has an Accessible Role of
+ * Internal Frame, returns (AccessibleContext)0.
+ */
+ private AccessibleContext getInternalFrame (AccessibleContext ac) {
+ return getParentWithRole(ac, AccessibleRole.INTERNAL_FRAME.toString());
+ }
+
+ /**
+ * Returns the Accessible Context for the top level object in
+ * a Java Window. This is same Accessible Context that is obtained
+ * from GetAccessibleContextFromHWND for that window. Returns
+ * (AccessibleContext)0 on error.
+ */
+ private AccessibleContext getTopLevelObject (final AccessibleContext ac) {
+ debugString("getTopLevelObject; ac = "+ac);
+ if (ac == null) {
+ return null;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ if (ac.getAccessibleRole() == AccessibleRole.DIALOG) {
+ // return the dialog, not the parent window
+ return ac;
+ }
+
+ Accessible parent = ac.getAccessibleParent();
+ if (parent == null) {
+ return ac;
+ }
+ Accessible tmp = parent;
+ while (tmp != null && tmp.getAccessibleContext() != null) {
+ AccessibleContext ac2 = tmp.getAccessibleContext();
+ if (ac2 != null && ac2.getAccessibleRole() == AccessibleRole.DIALOG) {
+ // return the dialog, not the parent window
+ return ac2;
+ }
+ parent = tmp;
+ tmp = parent.getAccessibleContext().getAccessibleParent();
+ }
+ return parent.getAccessibleContext();
+ }
+ }, ac);
+ }
+
+ /**
+ * Returns the parent AccessibleContext that has the specified AccessibleRole.
+ * Returns null on error or if the AccessibleContext does not exist.
+ */
+ private AccessibleContext getParentWithRole (final AccessibleContext ac,
+ final String roleName) {
+ debugString("getParentWithRole; ac = "+ac);
+ debugString("role = "+roleName);
+ if (ac == null || roleName == null) {
+ return null;
+ }
+
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ AccessibleRole role = AccessBridge.this.accessibleRoleMap.get(roleName);
+ if (role == null) {
+ return ac;
+ }
+
+ Accessible parent = ac.getAccessibleParent();
+ if (parent == null && ac.getAccessibleRole() == role) {
+ return ac;
+ }
+
+ Accessible tmp = parent;
+ AccessibleContext tmp_ac = null;
+
+ while (tmp != null && (tmp_ac = tmp.getAccessibleContext()) != null) {
+ AccessibleRole ar = tmp_ac.getAccessibleRole();
+ if (ar == role) {
+ // found
+ return tmp_ac;
+ }
+ parent = tmp;
+ tmp = parent.getAccessibleContext().getAccessibleParent();
+ }
+ // not found
+ return null;
+ }
+ }, ac);
+ }
+
+ /**
+ * Returns the parent AccessibleContext that has the specified AccessibleRole.
+ * Otherwise, returns the top level object for the Java Window.
+ * Returns (AccessibleContext)0 on error.
+ */
+ private AccessibleContext getParentWithRoleElseRoot (AccessibleContext ac,
+ String roleName) {
+ AccessibleContext retval = getParentWithRole(ac, roleName);
+ if (retval == null) {
+ retval = getTopLevelObject(ac);
+ }
+ return retval;
+ }
+
+ /**
+ * Returns how deep in the object hierarchy a given object is.
+ * The top most object in the object hierarchy has an object depth of 0.
+ * Returns -1 on error.
+ */
+ private int getObjectDepth(final AccessibleContext ac) {
+ debugString("getObjectDepth: ac = "+ac);
+
+ if (ac == null) {
+ return -1;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ int count = 0;
+ Accessible parent = ac.getAccessibleParent();
+ if (parent == null) {
+ return count;
+ }
+ Accessible tmp = parent;
+ while (tmp != null && tmp.getAccessibleContext() != null) {
+ parent = tmp;
+ tmp = parent.getAccessibleContext().getAccessibleParent();
+ count++;
+ }
+ return count;
+ }
+ }, ac);
+ }
+
+ /**
+ * Returns the Accessible Context of the current ActiveDescendent of an object.
+ * Returns (AccessibleContext)0 on error.
+ */
+ private AccessibleContext getActiveDescendent (final AccessibleContext ac) {
+ debugString("getActiveDescendent: ac = "+ac);
+ if (ac == null) {
+ return null;
+ }
+ // workaround for JTree bug where the only possible active
+ // descendent is the JTree root
+ final Accessible parent = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ return ac.getAccessibleParent();
+ }
+ }, ac);
+
+ if (parent != null) {
+ Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
+ @Override
+ public Accessible call() throws Exception {
+ int indexInParent = ac.getAccessibleIndexInParent();
+ return parent.getAccessibleContext().getAccessibleChild(indexInParent);
+ }
+ }, ac);
+
+ if (child instanceof JTree) {
+ // return the selected node
+ final JTree tree = (JTree)child;
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ return new AccessibleJTreeNode(tree,
+ tree.getSelectionPath(),
+ null);
+ }
+ }, child);
+ }
+ }
+
+ return InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ AccessibleSelection as = ac.getAccessibleSelection();
+ if (as == null) {
+ return null;
+ }
+ // assume single selection
+ if (as.getAccessibleSelectionCount() != 1) {
+ return null;
+ }
+ Accessible a = as.getAccessibleSelection(0);
+ if (a == null) {
+ return null;
+ }
+ return a.getAccessibleContext();
+ }
+ }, ac);
+ }
+
+
+ /**
+ * Additional methods for Teton
+ */
+
+ /**
+ * Gets the AccessibleName for a component based upon the JAWS algorithm.
+ * Returns whether successful.
+ *
+ * Bug ID 4916682 - Implement JAWS AccessibleName policy
+ */
+ private String getJAWSAccessibleName(final AccessibleContext ac) {
+ debugString("getJAWSAccessibleName");
+ if (ac == null) {
+ return null;
+ }
+ // placeholder
+ return InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return ac.getAccessibleName();
+ }
+ }, ac);
+ }
+
+ /**
+ * Request focus for a component. Returns whether successful;
+ *
+ * Bug ID 4944757 - requestFocus method needed
+ */
+ private boolean requestFocus(final AccessibleContext ac) {
+ debugString("requestFocus");
+ if (ac == null) {
+ return false;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ AccessibleComponent acomp = ac.getAccessibleComponent();
+ if (acomp == null) {
+ return false;
+ }
+ acomp.requestFocus();
+ return ac.getAccessibleStateSet().contains(AccessibleState.FOCUSED);
+ }
+ }, ac);
+ }
+
+ /**
+ * Selects text between two indices. Selection includes the
+ * text at the start index and the text at the end index. Returns
+ * whether successful;
+ *
+ * Bug ID 4944758 - selectTextRange method needed
+ */
+ private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) {
+ debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex);
+ if (ac == null) {
+ return false;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (!(at instanceof AccessibleEditableText)) {
+ return false;
+ }
+ ((AccessibleEditableText) at).selectText(startIndex, endIndex);
+
+ boolean result = at.getSelectionStart() == startIndex &&
+ at.getSelectionEnd() == endIndex;
+ return result;
+ }
+ }, ac);
+ }
+
+ /**
+ * Set the caret to a text position. Returns whether successful;
+ *
+ * Bug ID 4944770 - setCaretPosition method needed
+ */
+ private boolean setCaretPosition(final AccessibleContext ac, final int position) {
+ debugString("setCaretPosition: position = "+position);
+ if (ac == null) {
+ return false;
+ }
+ return InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ AccessibleText at = ac.getAccessibleText();
+ if (!(at instanceof AccessibleEditableText)) {
+ return false;
+ }
+ ((AccessibleEditableText) at).selectText(position, position);
+ return at.getCaretPosition() == position;
+ }
+ }, ac);
+ }
+
+ /**
+ * Gets the number of visible children of an AccessibleContext.
+ *
+ * Bug ID 4944762- getVisibleChildren for list-like components needed
+ */
+ private int _visibleChildrenCount;
+ private AccessibleContext _visibleChild;
+ private int _currentVisibleIndex;
+ private boolean _foundVisibleChild;
+
+ private int getVisibleChildrenCount(AccessibleContext ac) {
+ debugString("getVisibleChildrenCount");
+ if (ac == null) {
+ return -1;
+ }
+ _visibleChildrenCount = 0;
+ _getVisibleChildrenCount(ac);
+ debugString(" _visibleChildrenCount = "+_visibleChildrenCount);
+ return _visibleChildrenCount;
+ }
+
+ /*
+ * Recursively descends AccessibleContext and gets the number
+ * of visible children
+ */
+ private void _getVisibleChildrenCount(final AccessibleContext ac) {
+ if (ac == null)
+ return;
+ int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac.getAccessibleChildrenCount();
+ }
+ }, ac);
+ for (int i = 0; i < numChildren; i++) {
+ final int idx = i;
+ final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ Accessible a = ac.getAccessibleChild(idx);
+ if (a != null)
+ return a.getAccessibleContext();
+ else
+ return null;
+ }
+ }, ac);
+ if ( ac2 == null ||
+ (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
+ }
+ }, ac))
+ ) {
+ continue;
+ }
+ _visibleChildrenCount++;
+
+ if (InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac2.getAccessibleChildrenCount();
+ }
+ }, ac) > 0 ) {
+ _getVisibleChildrenCount(ac2);
+ }
+ }
+ }
+
+ /**
+ * Gets the visible child of an AccessibleContext at the
+ * specified index
+ *
+ * Bug ID 4944762- getVisibleChildren for list-like components needed
+ */
+ private AccessibleContext getVisibleChild(AccessibleContext ac, int index) {
+ debugString("getVisibleChild: index = "+index);
+ if (ac == null) {
+ return null;
+ }
+ _visibleChild = null;
+ _currentVisibleIndex = 0;
+ _foundVisibleChild = false;
+ _getVisibleChild(ac, index);
+
+ if (_visibleChild != null) {
+ debugString( " getVisibleChild: found child = " +
+ InvocationUtils.invokeAndWait(new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return AccessBridge.this._visibleChild.getAccessibleName();
+ }
+ }, ac) );
+ }
+ return _visibleChild;
+ }
+
+ /*
+ * Recursively searchs AccessibleContext and finds the visible component
+ * at the specified index
+ */
+ private void _getVisibleChild(final AccessibleContext ac, final int index) {
+ if (_visibleChild != null) {
+ return;
+ }
+
+ int numChildren = InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac.getAccessibleChildrenCount();
+ }
+ }, ac);
+ for (int i = 0; i < numChildren; i++) {
+ final int idx=i;
+ final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
+ @Override
+ public AccessibleContext call() throws Exception {
+ Accessible a = ac.getAccessibleChild(idx);
+ if (a == null)
+ return null;
+ else
+ return a.getAccessibleContext();
+ }
+ }, ac);
+ if (ac2 == null ||
+ (!InvocationUtils.invokeAndWait(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING);
+ }
+ }, ac))) {
+ continue;
+ }
+ if (!_foundVisibleChild && _currentVisibleIndex == index) {
+ _visibleChild = ac2;
+ _foundVisibleChild = true;
+ return;
+ }
+ _currentVisibleIndex++;
+
+ if ( InvocationUtils.invokeAndWait(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return ac2.getAccessibleChildrenCount();
+ }
+ }, ac) > 0 ) {
+ _getVisibleChild(ac2, index);
+ }
+ }
+ }
+
+
+ /* ===== Java object memory management code ===== */
+
+ /**
+ * Class to track object references to ensure the
+ * Java VM doesn't garbage collect them
+ */
+ private class ObjectReferences {
+
+ private class Reference {
+ private int value;
+
+ Reference(int i) {
+ value = i;
+ }
+
+ public String toString() {
+ return ("refCount: " + value);
+ }
+ }
+
+ /**
+ * table object references, to keep 'em from being garbage collected
+ */
+ private ConcurrentHashMap<Object,Reference> refs;
+
+ /**
+ * Constructor
+ */
+ ObjectReferences() {
+ refs = new ConcurrentHashMap<>(4);
+ }
+
+ /**
+ * Debugging: dump the contents of ObjectReferences' refs Hashtable
+ */
+ String dump() {
+ return refs.toString();
+ }
+
+ /**
+ * Increment ref count; set to 1 if we have no references for it
+ */
+ void increment(Object o) {
+ if (o == null){
+ debugString("ObjectReferences::increment - Passed in object is null");
+ return;
+ }
+
+ if (refs.containsKey(o)) {
+ (refs.get(o)).value++;
+ } else {
+ refs.put(o, new Reference(1));
+ }
+ }
+
+ /**
+ * Decrement ref count; remove if count drops to 0
+ */
+ void decrement(Object o) {
+ Reference aRef = refs.get(o);
+ if (aRef != null) {
+ aRef.value--;
+ if (aRef.value == 0) {
+ refs.remove(o);
+ } else if (aRef.value < 0) {
+ debugString("ERROR: decrementing reference count below 0");
+ }
+ } else {
+ debugString("ERROR: object to decrement not in ObjectReferences table");
+ }
+ }
+
+ }
+
+ /* ===== event handling code ===== */
+
+ /**
+ * native method for handling property change events
+ */
+ private native void propertyCaretChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ int oldValue, int newValue);
+ private native void propertyDescriptionChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ String oldValue, String newValue);
+ private native void propertyNameChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ String oldValue, String newValue);
+ private native void propertySelectionChange(PropertyChangeEvent e,
+ AccessibleContext src);
+ private native void propertyStateChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ String oldValue, String newValue);
+ private native void propertyTextChange(PropertyChangeEvent e,
+ AccessibleContext src);
+ private native void propertyValueChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ String oldValue, String newValue);
+ private native void propertyVisibleDataChange(PropertyChangeEvent e,
+ AccessibleContext src);
+ private native void propertyChildChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ AccessibleContext oldValue,
+ AccessibleContext newValue);
+ private native void propertyActiveDescendentChange(PropertyChangeEvent e,
+ AccessibleContext src,
+ AccessibleContext oldValue,
+ AccessibleContext newValue);
+
+ private native void javaShutdown();
+
+ /**
+ * native methods for handling focus events
+ */
+ private native void focusGained(FocusEvent e, AccessibleContext src);
+ private native void focusLost(FocusEvent e, AccessibleContext src);
+
+ /**
+ * native method for handling caret events
+ */
+ private native void caretUpdate(CaretEvent e, AccessibleContext src);
+
+ /**
+ * native methods for handling mouse events
+ */
+ private native void mouseClicked(MouseEvent e, AccessibleContext src);
+ private native void mouseEntered(MouseEvent e, AccessibleContext src);
+ private native void mouseExited(MouseEvent e, AccessibleContext src);
+ private native void mousePressed(MouseEvent e, AccessibleContext src);
+ private native void mouseReleased(MouseEvent e, AccessibleContext src);
+
+ /**
+ * native methods for handling menu & popupMenu events
+ */
+ private native void menuCanceled(MenuEvent e, AccessibleContext src);
+ private native void menuDeselected(MenuEvent e, AccessibleContext src);
+ private native void menuSelected(MenuEvent e, AccessibleContext src);
+ private native void popupMenuCanceled(PopupMenuEvent e, AccessibleContext src);
+ private native void popupMenuWillBecomeInvisible(PopupMenuEvent e,
+ AccessibleContext src);
+ private native void popupMenuWillBecomeVisible(PopupMenuEvent e,
+ AccessibleContext src);
+
+ /* ===== event definitions ===== */
+
+ private static final long PROPERTY_CHANGE_EVENTS = 1;
+ private static final long FOCUS_GAINED_EVENTS = 2;
+ private static final long FOCUS_LOST_EVENTS = 4;
+ private static final long FOCUS_EVENTS = (FOCUS_GAINED_EVENTS | FOCUS_LOST_EVENTS);
+
+ private static final long CARET_UPATE_EVENTS = 8;
+ private static final long CARET_EVENTS = CARET_UPATE_EVENTS;
+
+ private static final long MOUSE_CLICKED_EVENTS = 16;
+ private static final long MOUSE_ENTERED_EVENTS = 32;
+ private static final long MOUSE_EXITED_EVENTS = 64;
+ private static final long MOUSE_PRESSED_EVENTS = 128;
+ private static final long MOUSE_RELEASED_EVENTS = 256;
+ private static final long MOUSE_EVENTS = (MOUSE_CLICKED_EVENTS | MOUSE_ENTERED_EVENTS |
+ MOUSE_EXITED_EVENTS | MOUSE_PRESSED_EVENTS |
+ MOUSE_RELEASED_EVENTS);
+
+ private static final long MENU_CANCELED_EVENTS = 512;
+ private static final long MENU_DESELECTED_EVENTS = 1024;
+ private static final long MENU_SELECTED_EVENTS = 2048;
+ private static final long MENU_EVENTS = (MENU_CANCELED_EVENTS | MENU_DESELECTED_EVENTS |
+ MENU_SELECTED_EVENTS);
+
+ private static final long POPUPMENU_CANCELED_EVENTS = 4096;
+ private static final long POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS = 8192;
+ private static final long POPUPMENU_WILL_BECOME_VISIBLE_EVENTS = 16384;
+ private static final long POPUPMENU_EVENTS = (POPUPMENU_CANCELED_EVENTS |
+ POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS |
+ POPUPMENU_WILL_BECOME_VISIBLE_EVENTS);
+
+ /* These use their own numbering scheme, to ensure sufficient expansion room */
+ private static final long PROPERTY_NAME_CHANGE_EVENTS = 1;
+ private static final long PROPERTY_DESCRIPTION_CHANGE_EVENTS = 2;
+ private static final long PROPERTY_STATE_CHANGE_EVENTS = 4;
+ private static final long PROPERTY_VALUE_CHANGE_EVENTS = 8;
+ private static final long PROPERTY_SELECTION_CHANGE_EVENTS = 16;
+ private static final long PROPERTY_TEXT_CHANGE_EVENTS = 32;
+ private static final long PROPERTY_CARET_CHANGE_EVENTS = 64;
+ private static final long PROPERTY_VISIBLEDATA_CHANGE_EVENTS = 128;
+ private static final long PROPERTY_CHILD_CHANGE_EVENTS = 256;
+ private static final long PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS = 512;
+
+
+ private static final long PROPERTY_EVENTS = (PROPERTY_NAME_CHANGE_EVENTS |
+ PROPERTY_DESCRIPTION_CHANGE_EVENTS |
+ PROPERTY_STATE_CHANGE_EVENTS |
+ PROPERTY_VALUE_CHANGE_EVENTS |
+ PROPERTY_SELECTION_CHANGE_EVENTS |
+ PROPERTY_TEXT_CHANGE_EVENTS |
+ PROPERTY_CARET_CHANGE_EVENTS |
+ PROPERTY_VISIBLEDATA_CHANGE_EVENTS |
+ PROPERTY_CHILD_CHANGE_EVENTS |
+ PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS);
+
+ /**
+ * The EventHandler class listens for Java events and
+ * forwards them to the AT
+ */
+ private class EventHandler implements PropertyChangeListener,
+ FocusListener, CaretListener,
+ MenuListener, PopupMenuListener,
+ MouseListener, WindowListener,
+ ChangeListener {
+
+ private AccessBridge accessBridge;
+ private long javaEventMask = 0;
+ private long accessibilityEventMask = 0;
+
+ EventHandler(AccessBridge bridge) {
+ accessBridge = bridge;
+
+ // Register to receive WINDOW_OPENED and WINDOW_CLOSED
+ // events. Add the event source as a native window
+ // handler is it implements NativeWindowHandler.
+ // SwingEventMonitor.addWindowListener(this);
+ }
+
+ // --------- Event Notification Registration methods
+
+ /**
+ * Invoked the first time a window is made visible.
+ */
+ public void windowOpened(WindowEvent e) {
+ // If the window is a NativeWindowHandler, add it.
+ Object o = null;
+ if (e != null)
+ o = e.getSource();
+ if (o instanceof NativeWindowHandler) {
+ addNativeWindowHandler((NativeWindowHandler)o);
+ }
+ }
+
+ /**
+ * Invoked when the user attempts to close the window
+ * from the window's system menu. If the program does not
+ * explicitly hide or dispose the window while processing
+ * this event, the window close operation will be canceled.
+ */
+ public void windowClosing(WindowEvent e) {}
+
+ /**
+ * Invoked when a window has been closed as the result
+ * of calling dispose on the window.
+ */
+ public void windowClosed(WindowEvent e) {
+ // If the window is a NativeWindowHandler, remove it.
+ Object o = null;
+ if (e != null)
+ o = e.getSource();
+ if (o instanceof NativeWindowHandler) {
+ removeNativeWindowHandler((NativeWindowHandler)o);
+ }
+ }
+
+ /**
+ * Invoked when a window is changed from a normal to a
+ * minimized state. For many platforms, a minimized window
+ * is displayed as the icon specified in the window's
+ * iconImage property.
+ * @see java.awt.Frame#setIconImage
+ */
+ public void windowIconified(WindowEvent e) {}
+
+ /**
+ * Invoked when a window is changed from a minimized
+ * to a normal state.
+ */
+ public void windowDeiconified(WindowEvent e) {}
+
+ /**
+ * Invoked when the Window is set to be the active Window. Only a Frame or
+ * a Dialog can be the active Window. The native windowing system may
+ * denote the active Window or its children with special decorations, such
+ * as a highlighted title bar. The active Window is always either the
+ * focused Window, or the first Frame or Dialog that is an owner of the
+ * focused Window.
+ */
+ public void windowActivated(WindowEvent e) {}
+
+ /**
+ * Invoked when a Window is no longer the active Window. Only a Frame or a
+ * Dialog can be the active Window. The native windowing system may denote
+ * the active Window or its children with special decorations, such as a
+ * highlighted title bar. The active Window is always either the focused
+ * Window, or the first Frame or Dialog that is an owner of the focused
+ * Window.
+ */
+ public void windowDeactivated(WindowEvent e) {}
+
+ /**
+ * Turn on event monitoring for the event type passed in
+ * If necessary, add the appropriate event listener (if
+ * no other event of that type is being listened for)
+ */
+ void addJavaEventNotification(long type) {
+ long newEventMask = javaEventMask | type;
+ /*
+ if ( ((javaEventMask & PROPERTY_EVENTS) == 0) &&
+ ((newEventMask & PROPERTY_EVENTS) != 0) ) {
+ AccessibilityEventMonitor.addPropertyChangeListener(this);
+ }
+ */
+ if ( ((javaEventMask & FOCUS_EVENTS) == 0) &&
+ ((newEventMask & FOCUS_EVENTS) != 0) ) {
+ SwingEventMonitor.addFocusListener(this);
+ }
+ if ( ((javaEventMask & CARET_EVENTS) == 0) &&
+ ((newEventMask & CARET_EVENTS) != 0) ) {
+ SwingEventMonitor.addCaretListener(this);
+ }
+ if ( ((javaEventMask & MOUSE_EVENTS) == 0) &&
+ ((newEventMask & MOUSE_EVENTS) != 0) ) {
+ SwingEventMonitor.addMouseListener(this);
+ }
+ if ( ((javaEventMask & MENU_EVENTS) == 0) &&
+ ((newEventMask & MENU_EVENTS) != 0) ) {
+ SwingEventMonitor.addMenuListener(this);
+ SwingEventMonitor.addPopupMenuListener(this);
+ }
+ if ( ((javaEventMask & POPUPMENU_EVENTS) == 0) &&
+ ((newEventMask & POPUPMENU_EVENTS) != 0) ) {
+ SwingEventMonitor.addPopupMenuListener(this);
+ }
+
+ javaEventMask = newEventMask;
+ }
+
+ /**
+ * Turn off event monitoring for the event type passed in
+ * If necessary, remove the appropriate event listener (if
+ * no other event of that type is being listened for)
+ */
+ void removeJavaEventNotification(long type) {
+ long newEventMask = javaEventMask & (~type);
+ /*
+ if ( ((javaEventMask & PROPERTY_EVENTS) != 0) &&
+ ((newEventMask & PROPERTY_EVENTS) == 0) ) {
+ AccessibilityEventMonitor.removePropertyChangeListener(this);
+ }
+ */
+ if (((javaEventMask & FOCUS_EVENTS) != 0) &&
+ ((newEventMask & FOCUS_EVENTS) == 0)) {
+ SwingEventMonitor.removeFocusListener(this);
+ }
+ if (((javaEventMask & CARET_EVENTS) != 0) &&
+ ((newEventMask & CARET_EVENTS) == 0)) {
+ SwingEventMonitor.removeCaretListener(this);
+ }
+ if (((javaEventMask & MOUSE_EVENTS) == 0) &&
+ ((newEventMask & MOUSE_EVENTS) != 0)) {
+ SwingEventMonitor.removeMouseListener(this);
+ }
+ if (((javaEventMask & MENU_EVENTS) == 0) &&
+ ((newEventMask & MENU_EVENTS) != 0)) {
+ SwingEventMonitor.removeMenuListener(this);
+ }
+ if (((javaEventMask & POPUPMENU_EVENTS) == 0) &&
+ ((newEventMask & POPUPMENU_EVENTS) != 0)) {
+ SwingEventMonitor.removePopupMenuListener(this);
+ }
+
+ javaEventMask = newEventMask;
+ }
+
+ /**
+ * Turn on event monitoring for the event type passed in
+ * If necessary, add the appropriate event listener (if
+ * no other event of that type is being listened for)
+ */
+ void addAccessibilityEventNotification(long type) {
+ long newEventMask = accessibilityEventMask | type;
+ if ( ((accessibilityEventMask & PROPERTY_EVENTS) == 0) &&
+ ((newEventMask & PROPERTY_EVENTS) != 0) ) {
+ AccessibilityEventMonitor.addPropertyChangeListener(this);
+ }
+ accessibilityEventMask = newEventMask;
+ }
+
+ /**
+ * Turn off event monitoring for the event type passed in
+ * If necessary, remove the appropriate event listener (if
+ * no other event of that type is being listened for)
+ */
+ void removeAccessibilityEventNotification(long type) {
+ long newEventMask = accessibilityEventMask & (~type);
+ if ( ((accessibilityEventMask & PROPERTY_EVENTS) != 0) &&
+ ((newEventMask & PROPERTY_EVENTS) == 0) ) {
+ AccessibilityEventMonitor.removePropertyChangeListener(this);
+ }
+ accessibilityEventMask = newEventMask;
+ }
+
+ /**
+ * ------- property change event glue
+ */
+ // This is invoked on the EDT , as
+ public void propertyChange(PropertyChangeEvent e) {
+
+ accessBridge.debugString("propertyChange(" + e.toString() + ") called");
+
+ if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) {
+ Object o = e.getSource();
+ AccessibleContext ac;
+
+ if (o instanceof AccessibleContext) {
+ ac = (AccessibleContext) o;
+ } else {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a == null)
+ return;
+ else
+ ac = a.getAccessibleContext();
+ }
+ if (ac != null) {
+ InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext());
+
+ accessBridge.debugString("AccessibleContext: " + ac);
+ String propertyName = e.getPropertyName();
+
+ if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
+ int oldValue = 0;
+ int newValue = 0;
+
+ if (e.getOldValue() instanceof Integer) {
+ oldValue = ((Integer) e.getOldValue()).intValue();
+ }
+ if (e.getNewValue() instanceof Integer) {
+ newValue = ((Integer) e.getNewValue()).intValue();
+ }
+ accessBridge.debugString(" - about to call propertyCaretChange()");
+ accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue);
+ accessBridge.propertyCaretChange(e, ac, oldValue, newValue);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) {
+ String oldValue = null;
+ String newValue = null;
+
+ if (e.getOldValue() != null) {
+ oldValue = e.getOldValue().toString();
+ }
+ if (e.getNewValue() != null) {
+ newValue = e.getNewValue().toString();
+ }
+ accessBridge.debugString(" - about to call propertyDescriptionChange()");
+ accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue);
+ accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) {
+ String oldValue = null;
+ String newValue = null;
+
+ if (e.getOldValue() != null) {
+ oldValue = e.getOldValue().toString();
+ }
+ if (e.getNewValue() != null) {
+ newValue = e.getNewValue().toString();
+ }
+ accessBridge.debugString(" - about to call propertyNameChange()");
+ accessBridge.debugString(" old value: " + oldValue + " new value: " + newValue);
+ accessBridge.propertyNameChange(e, ac, oldValue, newValue);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) {
+ accessBridge.debugString(" - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource());
+
+ accessBridge.propertySelectionChange(e, ac);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_STATE_PROPERTY) == 0) {
+ String oldValue = null;
+ String newValue = null;
+
+ // Localization fix requested by Oliver for EA-1
+ if (e.getOldValue() != null) {
+ AccessibleState oldState = (AccessibleState) e.getOldValue();
+ oldValue = oldState.toDisplayString(Locale.US);
+ }
+ if (e.getNewValue() != null) {
+ AccessibleState newState = (AccessibleState) e.getNewValue();
+ newValue = newState.toDisplayString(Locale.US);
+ }
+
+ accessBridge.debugString(" - about to call propertyStateChange()");
+ accessBridge.propertyStateChange(e, ac, oldValue, newValue);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) {
+ accessBridge.debugString(" - about to call propertyTextChange()");
+ accessBridge.propertyTextChange(e, ac);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) { // strings 'cause of floating point, etc.
+ String oldValue = null;
+ String newValue = null;
+
+ if (e.getOldValue() != null) {
+ oldValue = e.getOldValue().toString();
+ }
+ if (e.getNewValue() != null) {
+ newValue = e.getNewValue().toString();
+ }
+ accessBridge.debugString(" - about to call propertyDescriptionChange()");
+ accessBridge.propertyValueChange(e, ac, oldValue, newValue);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) {
+ accessBridge.propertyVisibleDataChange(e, ac);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
+ AccessibleContext oldAC = null;
+ AccessibleContext newAC = null;
+ Accessible a;
+
+ if (e.getOldValue() instanceof AccessibleContext) {
+ oldAC = (AccessibleContext) e.getOldValue();
+ InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
+ }
+ if (e.getNewValue() instanceof AccessibleContext) {
+ newAC = (AccessibleContext) e.getNewValue();
+ InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
+ }
+ accessBridge.debugString(" - about to call propertyChildChange()");
+ accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC);
+ accessBridge.propertyChildChange(e, ac, oldAC, newAC);
+
+ } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) {
+ handleActiveDescendentEvent(e, ac);
+ }
+ }
+ }
+ }
+
+ /*
+ * Handle an ActiveDescendent PropertyChangeEvent. This
+ * method works around a JTree bug where ActiveDescendent
+ * PropertyChangeEvents have the wrong parent.
+ */
+ private AccessibleContext prevAC = null; // previous AccessibleContext
+
+ private void handleActiveDescendentEvent(PropertyChangeEvent e,
+ AccessibleContext ac) {
+ if (e == null || ac == null)
+ return;
+ AccessibleContext oldAC = null;
+ AccessibleContext newAC = null;
+ Accessible a;
+
+ // get the old active descendent
+ if (e.getOldValue() instanceof Accessible) {
+ oldAC = ((Accessible) e.getOldValue()).getAccessibleContext();
+ } else if (e.getOldValue() instanceof Component) {
+ a = Translator.getAccessible(e.getOldValue());
+ if (a != null) {
+ oldAC = a.getAccessibleContext();
+ }
+ }
+ if (oldAC != null) {
+ Accessible parent = oldAC.getAccessibleParent();
+ if (parent instanceof JTree) {
+ // use the previous AccessibleJTreeNode
+ oldAC = prevAC;
+ }
+ }
+
+ // get the new active descendent
+ if (e.getNewValue() instanceof Accessible) {
+ newAC = ((Accessible) e.getNewValue()).getAccessibleContext();
+ } else if (e.getNewValue() instanceof Component) {
+ a = Translator.getAccessible(e.getNewValue());
+ if (a != null) {
+ newAC = a.getAccessibleContext();
+ }
+ }
+ if (newAC != null) {
+ Accessible parent = newAC.getAccessibleParent();
+ if (parent instanceof JTree) {
+ // use a new AccessibleJTreeNode with the right parent
+ JTree tree = (JTree)parent;
+ newAC = new AccessibleJTreeNode(tree,
+ tree.getSelectionPath(),
+ null);
+ }
+ }
+ prevAC = newAC;
+
+ accessBridge.debugString(" - about to call propertyActiveDescendentChange()");
+ accessBridge.debugString(" AC: " + ac);
+ accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC);
+
+ InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext());
+ InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext());
+ accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC);
+ }
+
+ /**
+ * ------- focus event glue
+ */
+ private boolean stateChangeListenerAdded = false;
+
+ public void focusGained(FocusEvent e) {
+ processFocusGained();
+ }
+
+ public void stateChanged(ChangeEvent e) {
+ processFocusGained();
+ }
+
+ private void processFocusGained() {
+ Component focusOwner = KeyboardFocusManager.
+ getCurrentKeyboardFocusManager().getFocusOwner();
+ if (focusOwner == null) {
+ return;
+ }
+
+ // Only menus and popup selections are handled by the JRootPane.
+ if (focusOwner instanceof JRootPane) {
+ MenuElement [] path =
+ MenuSelectionManager.defaultManager().getSelectedPath();
+ if (path.length > 1) {
+ Component penult = path[path.length-2].getComponent();
+ Component last = path[path.length-1].getComponent();
+
+ if (last instanceof JPopupMenu) {
+ // This is a popup with nothing in the popup
+ // selected. The menu itself is selected.
+ FocusEvent e = new FocusEvent(penult, FocusEvent.FOCUS_GAINED);
+ AccessibleContext context = penult.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(penult));
+ accessBridge.focusGained(e, context);
+ } else if (penult instanceof JPopupMenu) {
+ // This is a popup with an item selected
+ FocusEvent e =
+ new FocusEvent(last, FocusEvent.FOCUS_GAINED);
+ accessBridge.debugString(" - about to call focusGained()");
+ AccessibleContext focusedAC = last.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last));
+ accessBridge.debugString(" AC: " + focusedAC);
+ accessBridge.focusGained(e, focusedAC);
+ }
+ }
+ } else {
+ // The focus owner has the selection.
+ if (focusOwner instanceof Accessible) {
+ FocusEvent e = new FocusEvent(focusOwner,
+ FocusEvent.FOCUS_GAINED);
+ accessBridge.debugString(" - about to call focusGained()");
+ AccessibleContext focusedAC = focusOwner.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner));
+ accessBridge.debugString(" AC: " + focusedAC);
+ accessBridge.focusGained(e, focusedAC);
+ }
+ }
+ }
+
+ public void focusLost(FocusEvent e) {
+ if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ accessBridge.debugString(" - about to call focusLost()");
+ accessBridge.debugString(" AC: " + a.getAccessibleContext());
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.focusLost(e, context);
+ }
+ }
+ }
+
+ /**
+ * ------- caret event glue
+ */
+ public void caretUpdate(CaretEvent e) {
+ if (e != null && (javaEventMask & CARET_UPATE_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.caretUpdate(e, context);
+ }
+ }
+ }
+
+ /**
+ * ------- mouse event glue
+ */
+
+ public void mouseClicked(MouseEvent e) {
+ if (e != null && (javaEventMask & MOUSE_CLICKED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.mouseClicked(e, context);
+ }
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ if (e != null && (javaEventMask & MOUSE_ENTERED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.mouseEntered(e, context);
+ }
+ }
+ }
+
+ public void mouseExited(MouseEvent e) {
+ if (e != null && (javaEventMask & MOUSE_EXITED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.mouseExited(e, context);
+ }
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {
+ if (e != null && (javaEventMask & MOUSE_PRESSED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.mousePressed(e, context);
+ }
+ }
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ if (e != null && (javaEventMask & MOUSE_RELEASED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.mouseReleased(e, context);
+ }
+ }
+ }
+
+ /**
+ * ------- menu event glue
+ */
+ public void menuCanceled(MenuEvent e) {
+ if (e != null && (javaEventMask & MENU_CANCELED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.menuCanceled(e, context);
+ }
+ }
+ }
+
+ public void menuDeselected(MenuEvent e) {
+ if (e != null && (javaEventMask & MENU_DESELECTED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.menuDeselected(e, context);
+ }
+ }
+ }
+
+ public void menuSelected(MenuEvent e) {
+ if (e != null && (javaEventMask & MENU_SELECTED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.menuSelected(e, context);
+ }
+ }
+ }
+
+ public void popupMenuCanceled(PopupMenuEvent e) {
+ if (e != null && (javaEventMask & POPUPMENU_CANCELED_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.popupMenuCanceled(e, context);
+ }
+ }
+ }
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+ if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.popupMenuWillBecomeInvisible(e, context);
+ }
+ }
+ }
+
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_VISIBLE_EVENTS) != 0) {
+ Accessible a = Translator.getAccessible(e.getSource());
+ if (a != null) {
+ AccessibleContext context = a.getAccessibleContext();
+ InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext());
+ accessBridge.popupMenuWillBecomeVisible(e, context);
+ }
+ }
+ }
+
+ } // End of EventHandler Class
+
+ // --------- Event Notification Registration methods
+
+ /**
+ * Wrapper method around eventHandler.addJavaEventNotification()
+ */
+ private void addJavaEventNotification(final long type) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run(){
+ eventHandler.addJavaEventNotification(type);
+ }
+ });
+ }
+
+ /**
+ * Wrapper method around eventHandler.removeJavaEventNotification()
+ */
+ private void removeJavaEventNotification(final long type) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run(){
+ eventHandler.removeJavaEventNotification(type);
+ }
+ });
+ }
+
+
+ /**
+ * Wrapper method around eventHandler.addAccessibilityEventNotification()
+ */
+ private void addAccessibilityEventNotification(final long type) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run(){
+ eventHandler.addAccessibilityEventNotification(type);
+ }
+ });
+ }
+
+ /**
+ * Wrapper method around eventHandler.removeAccessibilityEventNotification()
+ */
+ private void removeAccessibilityEventNotification(final long type) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run(){
+ eventHandler.removeAccessibilityEventNotification(type);
+ }
+ });
+ }
+
+ /**
+ ******************************************************
+ * All AccessibleRoles
+ *
+ * We shouldn't have to do this since it requires us
+ * to synchronize the allAccessibleRoles array when
+ * the AccessibleRoles class interface changes. However,
+ * there is no Accessibility API method to get all
+ * AccessibleRoles
+ ******************************************************
+ */
+ private AccessibleRole [] allAccessibleRoles = {
+ /**
+ * Object is used to alert the user about something.
+ */
+ AccessibleRole.ALERT,
+
+ /**
+ * The header for a column of data.
+ */
+ AccessibleRole.COLUMN_HEADER,
+
+ /**
+ * Object that can be drawn into and is used to trap
+ * events.
+ * @see #FRAME
+ * @see #GLASS_PANE
+ * @see #LAYERED_PANE
+ */
+ AccessibleRole.CANVAS,
+
+ /**
+ * A list of choices the user can select from. Also optionally
+ * allows the user to enter a choice of their own.
+ */
+ AccessibleRole.COMBO_BOX,
+
+ /**
+ * An iconified internal frame in a DESKTOP_PANE.
+ * @see #DESKTOP_PANE
+ * @see #INTERNAL_FRAME
+ */
+ AccessibleRole.DESKTOP_ICON,
+
+ /**
+ * A frame-like object that is clipped by a desktop pane. The
+ * desktop pane, internal frame, and desktop icon objects are
+ * often used to create multiple document interfaces within an
+ * application.
+ * @see #DESKTOP_ICON
+ * @see #DESKTOP_PANE
+ * @see #FRAME
+ */
+ AccessibleRole.INTERNAL_FRAME,
+
+ /**
+ * A pane that supports internal frames and
+ * iconified versions of those internal frames.
+ * @see #DESKTOP_ICON
+ * @see #INTERNAL_FRAME
+ */
+ AccessibleRole.DESKTOP_PANE,
+
+ /**
+ * A specialized pane whose primary use is inside a DIALOG
+ * @see #DIALOG
+ */
+ AccessibleRole.OPTION_PANE,
+
+ /**
+ * A top level window with no title or border.
+ * @see #FRAME
+ * @see #DIALOG
+ */
+ AccessibleRole.WINDOW,
+
+ /**
+ * A top level window with a title bar, border, menu bar, etc. It is
+ * often used as the primary window for an application.
+ * @see #DIALOG
+ * @see #CANVAS
+ * @see #WINDOW
+ */
+ AccessibleRole.FRAME,
+
+ /**
+ * A top level window with title bar and a border. A dialog is similar
+ * to a frame, but it has fewer properties and is often used as a
+ * secondary window for an application.
+ * @see #FRAME
+ * @see #WINDOW
+ */
+ AccessibleRole.DIALOG,
+
+ /**
+ * A specialized dialog that lets the user choose a color.
+ */
+ AccessibleRole.COLOR_CHOOSER,
+
+
+ /**
+ * A pane that allows the user to navigate through
+ * and select the contents of a directory. May be used
+ * by a file chooser.
+ * @see #FILE_CHOOSER
+ */
+ AccessibleRole.DIRECTORY_PANE,
+
+ /**
+ * A specialized dialog that displays the files in the directory
+ * and lets the user select a file, browse a different directory,
+ * or specify a filename. May use the directory pane to show the
+ * contents of a directory.
+ * @see #DIRECTORY_PANE
+ */
+ AccessibleRole.FILE_CHOOSER,
+
+ /**
+ * An object that fills up space in a user interface. It is often
+ * used in interfaces to tweak the spacing between components,
+ * but serves no other purpose.
+ */
+ AccessibleRole.FILLER,
+
+ /**
+ * A hypertext anchor
+ */
+ // AccessibleRole.HYPERLINK,
+
+ /**
+ * A small fixed size picture, typically used to decorate components.
+ */
+ AccessibleRole.ICON,
+
+ /**
+ * An object used to present an icon or short string in an interface.
+ */
+ AccessibleRole.LABEL,
+
+ /**
+ * A specialized pane that has a glass pane and a layered pane as its
+ * children.
+ * @see #GLASS_PANE
+ * @see #LAYERED_PANE
+ */
+ AccessibleRole.ROOT_PANE,
+
+ /**
+ * A pane that is guaranteed to be painted on top
+ * of all panes beneath it.
+ * @see #ROOT_PANE
+ * @see #CANVAS
+ */
+ AccessibleRole.GLASS_PANE,
+
+ /**
+ * A specialized pane that allows its children to be drawn in layers,
+ * providing a form of stacking order. This is usually the pane that
+ * holds the menu bar as well as the pane that contains most of the
+ * visual components in a window.
+ * @see #GLASS_PANE
+ * @see #ROOT_PANE
+ */
+ AccessibleRole.LAYERED_PANE,
+
+ /**
+ * An object that presents a list of objects to the user and allows the
+ * user to select one or more of them. A list is usually contained
+ * within a scroll pane.
+ * @see #SCROLL_PANE
+ * @see #LIST_ITEM
+ */
+ AccessibleRole.LIST,
+
+ /**
+ * An object that presents an element in a list. A list is usually
+ * contained within a scroll pane.
+ * @see #SCROLL_PANE
+ * @see #LIST
+ */
+ AccessibleRole.LIST_ITEM,
+
+ /**
+ * An object usually drawn at the top of the primary dialog box of
+ * an application that contains a list of menus the user can choose
+ * from. For example, a menu bar might contain menus for "File,"
+ * "Edit," and "Help."
+ * @see #MENU
+ * @see #POPUP_MENU
+ * @see #LAYERED_PANE
+ */
+ AccessibleRole.MENU_BAR,
+
+ /**
+ * A temporary window that is usually used to offer the user a
+ * list of choices, and then hides when the user selects one of
+ * those choices.
+ * @see #MENU
+ * @see #MENU_ITEM
+ */
+ AccessibleRole.POPUP_MENU,
+
+ /**
+ * An object usually found inside a menu bar that contains a list
+ * of actions the user can choose from. A menu can have any object
+ * as its children, but most often they are menu items, other menus,
+ * or rudimentary objects such as radio buttons, check boxes, or
+ * separators. For example, an application may have an "Edit" menu
+ * that contains menu items for "Cut" and "Paste."
+ * @see #MENU_BAR
+ * @see #MENU_ITEM
+ * @see #SEPARATOR
+ * @see #RADIO_BUTTON
+ * @see #CHECK_BOX
+ * @see #POPUP_MENU
+ */
+ AccessibleRole.MENU,
+
+ /**
+ * An object usually contained in a menu that presents an action
+ * the user can choose. For example, the "Cut" menu item in an
+ * "Edit" menu would be an action the user can select to cut the
+ * selected area of text in a document.
+ * @see #MENU_BAR
+ * @see #SEPARATOR
+ * @see #POPUP_MENU
+ */
+ AccessibleRole.MENU_ITEM,
+
+ /**
+ * An object usually contained in a menu to provide a visual
+ * and logical separation of the contents in a menu. For example,
+ * the "File" menu of an application might contain menu items for
+ * "Open," "Close," and "Exit," and will place a separator between
+ * "Close" and "Exit" menu items.
+ * @see #MENU
+ * @see #MENU_ITEM
+ */
+ AccessibleRole.SEPARATOR,
+
+ /**
+ * An object that presents a series of panels (or page tabs), one at a
+ * time, through some mechanism provided by the object. The most common
+ * mechanism is a list of tabs at the top of the panel. The children of
+ * a page tab list are all page tabs.
+ * @see #PAGE_TAB
+ */
+ AccessibleRole.PAGE_TAB_LIST,
+
+ /**
+ * An object that is a child of a page tab list. Its sole child is
+ * the panel that is to be presented to the user when the user
+ * selects the page tab from the list of tabs in the page tab list.
+ * @see #PAGE_TAB_LIST
+ */
+ AccessibleRole.PAGE_TAB,
+
+ /**
+ * A generic container that is often used to group objects.
+ */
+ AccessibleRole.PANEL,
+
+ /**
+ * An object used to indicate how much of a task has been completed.
+ */
+ AccessibleRole.PROGRESS_BAR,
+
+ /**
+ * A text object used for passwords, or other places where the
+ * text contents is not shown visibly to the user
+ */
+ AccessibleRole.PASSWORD_TEXT,
+
+ /**
+ * An object the user can manipulate to tell the application to do
+ * something.
+ * @see #CHECK_BOX
+ * @see #TOGGLE_BUTTON
+ * @see #RADIO_BUTTON
+ */
+ AccessibleRole.PUSH_BUTTON,
+
+ /**
+ * A specialized push button that can be checked or unchecked, but
+ * does not provide a separate indicator for the current state.
+ * @see #PUSH_BUTTON
+ * @see #CHECK_BOX
+ * @see #RADIO_BUTTON
+ */
+ AccessibleRole.TOGGLE_BUTTON,
+
+ /**
+ * A choice that can be checked or unchecked and provides a
+ * separate indicator for the current state.
+ * @see #PUSH_BUTTON
+ * @see #TOGGLE_BUTTON
+ * @see #RADIO_BUTTON
+ */
+ AccessibleRole.CHECK_BOX,
+
+ /**
+ * A specialized check box that will cause other radio buttons in the
+ * same group to become unchecked when this one is checked.
+ * @see #PUSH_BUTTON
+ * @see #TOGGLE_BUTTON
+ * @see #CHECK_BOX
+ */
+ AccessibleRole.RADIO_BUTTON,
+
+ /**
+ * The header for a row of data.
+ */
+ AccessibleRole.ROW_HEADER,
+
+ /**
+ * An object that allows a user to incrementally view a large amount
+ * of information. Its children can include scroll bars and a viewport.
+ * @see #SCROLL_BAR
+ * @see #VIEWPORT
+ */
+ AccessibleRole.SCROLL_PANE,
+
+ /**
+ * An object usually used to allow a user to incrementally view a
+ * large amount of data. Usually used only by a scroll pane.
+ * @see #SCROLL_PANE
+ */
+ AccessibleRole.SCROLL_BAR,
+
+ /**
+ * An object usually used in a scroll pane. It represents the portion
+ * of the entire data that the user can see. As the user manipulates
+ * the scroll bars, the contents of the viewport can change.
+ * @see #SCROLL_PANE
+ */
+ AccessibleRole.VIEWPORT,
+
+ /**
+ * An object that allows the user to select from a bounded range. For
+ * example, a slider might be used to select a number between 0 and 100.
+ */
+ AccessibleRole.SLIDER,
+
+ /**
+ * A specialized panel that presents two other panels at the same time.
+ * Between the two panels is a divider the user can manipulate to make
+ * one panel larger and the other panel smaller.
+ */
+ AccessibleRole.SPLIT_PANE,
+
+ /**
+ * An object used to present information in terms of rows and columns.
+ * An example might include a spreadsheet application.
+ */
+ AccessibleRole.TABLE,
+
+ /**
+ * An object that presents text to the user. The text is usually
+ * editable by the user as opposed to a label.
+ * @see #LABEL
+ */
+ AccessibleRole.TEXT,
+
+ /**
+ * An object used to present hierarchical information to the user.
+ * The individual nodes in the tree can be collapsed and expanded
+ * to provide selective disclosure of the tree's contents.
+ */
+ AccessibleRole.TREE,
+
+ /**
+ * A bar or palette usually composed of push buttons or toggle buttons.
+ * It is often used to provide the most frequently used functions for an
+ * application.
+ */
+ AccessibleRole.TOOL_BAR,
+
+ /**
+ * An object that provides information about another object. The
+ * accessibleDescription property of the tool tip is often displayed
+ * to the user in a small "help bubble" when the user causes the
+ * mouse to hover over the object associated with the tool tip.
+ */
+ AccessibleRole.TOOL_TIP,
+
+ /**
+ * An AWT component, but nothing else is known about it.
+ * @see #SWING_COMPONENT
+ * @see #UNKNOWN
+ */
+ AccessibleRole.AWT_COMPONENT,
+
+ /**
+ * A Swing component, but nothing else is known about it.
+ * @see #AWT_COMPONENT
+ * @see #UNKNOWN
+ */
+ AccessibleRole.SWING_COMPONENT,
+
+ /**
+ * The object contains some Accessible information, but its role is
+ * not known.
+ * @see #AWT_COMPONENT
+ * @see #SWING_COMPONENT
+ */
+ AccessibleRole.UNKNOWN,
+
+ // These roles are only available in JDK 1.4
+
+ /**
+ * A STATUS_BAR is an simple component that can contain
+ * multiple labels of status information to the user.
+ AccessibleRole.STATUS_BAR,
+
+ /**
+ * A DATE_EDITOR is a component that allows users to edit
+ * java.util.Date and java.util.Time objects
+ AccessibleRole.DATE_EDITOR,
+
+ /**
+ * A SPIN_BOX is a simple spinner component and its main use
+ * is for simple numbers.
+ AccessibleRole.SPIN_BOX,
+
+ /**
+ * A FONT_CHOOSER is a component that lets the user pick various
+ * attributes for fonts.
+ AccessibleRole.FONT_CHOOSER,
+
+ /**
+ * A GROUP_BOX is a simple container that contains a border
+ * around it and contains components inside it.
+ AccessibleRole.GROUP_BOX
+
+ /**
+ * Since JDK 1.5
+ *
+ * A text header
+
+ AccessibleRole.HEADER,
+
+ /**
+ * A text footer
+
+ AccessibleRole.FOOTER,
+
+ /**
+ * A text paragraph
+
+ AccessibleRole.PARAGRAPH,
+
+ /**
+ * A ruler is an object used to measure distance
+
+ AccessibleRole.RULER,
+
+ /**
+ * A role indicating the object acts as a formula for
+ * calculating a value. An example is a formula in
+ * a spreadsheet cell.
+ AccessibleRole.EDITBAR
+ */
+ };
+
+ /**
+ * This class implements accessibility support for the
+ * <code>JTree</code> child. It provides an implementation of the
+ * Java Accessibility API appropriate to tree nodes.
+ *
+ * Copied from JTree.java to work around a JTree bug where
+ * ActiveDescendent PropertyChangeEvents contain the wrong
+ * parent.
+ */
+ /**
+ * This class in invoked on the EDT as its part of ActiveDescendant,
+ * hence the calls do not need to be specifically made on the EDT
+ */
+ private class AccessibleJTreeNode extends AccessibleContext
+ implements Accessible, AccessibleComponent, AccessibleSelection,
+ AccessibleAction {
+
+ private JTree tree = null;
+ private TreeModel treeModel = null;
+ private Object obj = null;
+ private TreePath path = null;
+ private Accessible accessibleParent = null;
+ private int index = 0;
+ private boolean isLeaf = false;
+
+ /**
+ * Constructs an AccessibleJTreeNode
+ */
+ AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) {
+ tree = t;
+ path = p;
+ accessibleParent = ap;
+ if (t != null)
+ treeModel = t.getModel();
+ if (p != null) {
+ obj = p.getLastPathComponent();
+ if (treeModel != null && obj != null) {
+ isLeaf = treeModel.isLeaf(obj);
+ }
+ }
+ debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap);
+ }
+
+ private TreePath getChildTreePath(int i) {
+ // Tree nodes can't be so complex that they have
+ // two sets of children -> we're ignoring that case
+ if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
+ return null;
+ } else {
+ Object childObj = treeModel.getChild(obj, i);
+ Object[] objPath = path.getPath();
+ Object[] objChildPath = new Object[objPath.length+1];
+ java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
+ objChildPath[objChildPath.length-1] = childObj;
+ return new TreePath(objChildPath);
+ }
+ }
+
+ /**
+ * Get the AccessibleContext associated with this tree node.
+ * In the implementation of the Java Accessibility API for
+ * this class, return this object, which is its own
+ * AccessibleContext.
+ *
+ * @return this object
+ */
+ public AccessibleContext getAccessibleContext() {
+ return this;
+ }
+
+ private AccessibleContext getCurrentAccessibleContext() {
+ Component c = getCurrentComponent();
+ if (c instanceof Accessible) {
+ return (c.getAccessibleContext());
+ } else {
+ return null;
+ }
+ }
+
+ private Component getCurrentComponent() {
+ debugString("AccessibleJTreeNode: getCurrentComponent");
+ // is the object visible?
+ // if so, get row, selected, focus & leaf state,
+ // and then get the renderer component and return it
+ if (tree != null && tree.isVisible(path)) {
+ TreeCellRenderer r = tree.getCellRenderer();
+ if (r == null) {
+ debugString(" returning null 1");
+ return null;
+ }
+ TreeUI ui = tree.getUI();
+ if (ui != null) {
+ int row = ui.getRowForPath(tree, path);
+ boolean selected = tree.isPathSelected(path);
+ boolean expanded = tree.isExpanded(path);
+ boolean hasFocus = false; // how to tell?? -PK
+ Component retval = r.getTreeCellRendererComponent(tree, obj,
+ selected, expanded,
+ isLeaf, row, hasFocus);
+ debugString(" returning = "+retval.getClass());
+ return retval;
+ }
+ }
+ debugString(" returning null 2");
+ return null;
+ }
+
+ // AccessibleContext methods
+
+ /**
+ * Get the accessible name of this object.
+ *
+ * @return the localized name of the object; null if this
+ * object does not have a name
+ */
+ public String getAccessibleName() {
+ debugString("AccessibleJTreeNode: getAccessibleName");
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ String name = ac.getAccessibleName();
+ if ((name != null) && (!name.isEmpty())) {
+ String retval = ac.getAccessibleName();
+ debugString(" returning "+retval);
+ return retval;
+ } else {
+ return null;
+ }
+ }
+ if ((accessibleName != null) && (accessibleName.isEmpty())) {
+ return accessibleName;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set the localized accessible name of this object.
+ *
+ * @param s the new localized name of the object.
+ */
+ public void setAccessibleName(String s) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ ac.setAccessibleName(s);
+ } else {
+ super.setAccessibleName(s);
+ }
+ }
+
+ //
+ // *** should check tooltip text for desc. (needs MouseEvent)
+ //
+ /**
+ * Get the accessible description of this object.
+ *
+ * @return the localized description of the object; null if
+ * this object does not have a description
+ */
+ public String getAccessibleDescription() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ return ac.getAccessibleDescription();
+ } else {
+ return super.getAccessibleDescription();
+ }
+ }
+
+ /**
+ * Set the accessible description of this object.
+ *
+ * @param s the new localized description of the object
+ */
+ public void setAccessibleDescription(String s) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ ac.setAccessibleDescription(s);
+ } else {
+ super.setAccessibleDescription(s);
+ }
+ }
+
+ /**
+ * Get the role of this object.
+ *
+ * @return an instance of AccessibleRole describing the role of the object
+ * @see AccessibleRole
+ */
+ public AccessibleRole getAccessibleRole() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ return ac.getAccessibleRole();
+ } else {
+ return AccessibleRole.UNKNOWN;
+ }
+ }
+
+ /**
+ * Get the state set of this object.
+ *
+ * @return an instance of AccessibleStateSet containing the
+ * current state set of the object
+ * @see AccessibleState
+ */
+ public AccessibleStateSet getAccessibleStateSet() {
+ if (tree == null)
+ return null;
+ AccessibleContext ac = getCurrentAccessibleContext();
+ AccessibleStateSet states;
+ int row = tree.getUI().getRowForPath(tree,path);
+ int lsr = tree.getLeadSelectionRow();
+ if (ac != null) {
+ states = ac.getAccessibleStateSet();
+ } else {
+ states = new AccessibleStateSet();
+ }
+ // need to test here, 'cause the underlying component
+ // is a cellRenderer, which is never showing...
+ if (isShowing()) {
+ states.add(AccessibleState.SHOWING);
+ } else if (states.contains(AccessibleState.SHOWING)) {
+ states.remove(AccessibleState.SHOWING);
+ }
+ if (isVisible()) {
+ states.add(AccessibleState.VISIBLE);
+ } else if (states.contains(AccessibleState.VISIBLE)) {
+ states.remove(AccessibleState.VISIBLE);
+ }
+ if (tree.isPathSelected(path)){
+ states.add(AccessibleState.SELECTED);
+ }
+ if (lsr == row) {
+ states.add(AccessibleState.ACTIVE);
+ }
+ if (!isLeaf) {
+ states.add(AccessibleState.EXPANDABLE);
+ }
+ if (tree.isExpanded(path)) {
+ states.add(AccessibleState.EXPANDED);
+ } else {
+ states.add(AccessibleState.COLLAPSED);
+ }
+ if (tree.isEditable()) {
+ states.add(AccessibleState.EDITABLE);
+ }
+ return states;
+ }
+
+ /**
+ * Get the Accessible parent of this object.
+ *
+ * @return the Accessible parent of this object; null if this
+ * object does not have an Accessible parent
+ */
+ public Accessible getAccessibleParent() {
+ // someone wants to know, so we need to create our parent
+ // if we don't have one (hey, we're a talented kid!)
+ if (accessibleParent == null && path != null) {
+ Object[] objPath = path.getPath();
+ if (objPath.length > 1) {
+ Object objParent = objPath[objPath.length-2];
+ if (treeModel != null) {
+ index = treeModel.getIndexOfChild(objParent, obj);
+ }
+ Object[] objParentPath = new Object[objPath.length-1];
+ java.lang.System.arraycopy(objPath, 0, objParentPath,
+ 0, objPath.length-1);
+ TreePath parentPath = new TreePath(objParentPath);
+ accessibleParent = new AccessibleJTreeNode(tree,
+ parentPath,
+ null);
+ this.setAccessibleParent(accessibleParent);
+ } else if (treeModel != null) {
+ accessibleParent = tree; // we're the top!
+ index = 0; // we're an only child!
+ this.setAccessibleParent(accessibleParent);
+ }
+ }
+ return accessibleParent;
+ }
+
+ /**
+ * Get the index of this object in its accessible parent.
+ *
+ * @return the index of this object in its parent; -1 if this
+ * object does not have an accessible parent.
+ * @see #getAccessibleParent
+ */
+ public int getAccessibleIndexInParent() {
+ // index is invalid 'till we have an accessibleParent...
+ if (accessibleParent == null) {
+ getAccessibleParent();
+ }
+ if (path != null) {
+ Object[] objPath = path.getPath();
+ if (objPath.length > 1) {
+ Object objParent = objPath[objPath.length-2];
+ if (treeModel != null) {
+ index = treeModel.getIndexOfChild(objParent, obj);
+ }
+ }
+ }
+ return index;
+ }
+
+ /**
+ * Returns the number of accessible children in the object.
+ *
+ * @return the number of accessible children in the object.
+ */
+ public int getAccessibleChildrenCount() {
+ // Tree nodes can't be so complex that they have
+ // two sets of children -> we're ignoring that case
+ if (obj != null && treeModel != null) {
+ return treeModel.getChildCount(obj);
+ }
+ return 0;
+ }
+
+ /**
+ * Return the specified Accessible child of the object.
+ *
+ * @param i zero-based index of child
+ * @return the Accessible child of the object
+ */
+ public Accessible getAccessibleChild(int i) {
+ // Tree nodes can't be so complex that they have
+ // two sets of children -> we're ignoring that case
+ if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) {
+ return null;
+ } else {
+ Object childObj = treeModel.getChild(obj, i);
+ Object[] objPath = path.getPath();
+ Object[] objChildPath = new Object[objPath.length+1];
+ java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
+ objChildPath[objChildPath.length-1] = childObj;
+ TreePath childPath = new TreePath(objChildPath);
+ return new AccessibleJTreeNode(tree, childPath, this);
+ }
+ }
+
+ /**
+ * Gets the locale of the component. If the component does not have
+ * a locale, then the locale of its parent is returned.
+ *
+ * @return This component's locale. If this component does not have
+ * a locale, the locale of its parent is returned.
+ * @exception IllegalComponentStateException
+ * If the Component does not have its own locale and has not yet
+ * been added to a containment hierarchy such that the locale can be
+ * determined from the containing parent.
+ * @see #setLocale
+ */
+ public Locale getLocale() {
+ if (tree == null)
+ return null;
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ return ac.getLocale();
+ } else {
+ return tree.getLocale();
+ }
+ }
+
+ /**
+ * Add a PropertyChangeListener to the listener list.
+ * The listener is registered for all properties.
+ *
+ * @param l The PropertyChangeListener to be added
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ ac.addPropertyChangeListener(l);
+ } else {
+ super.addPropertyChangeListener(l);
+ }
+ }
+
+ /**
+ * Remove a PropertyChangeListener from the listener list.
+ * This removes a PropertyChangeListener that was registered
+ * for all properties.
+ *
+ * @param l The PropertyChangeListener to be removed
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ ac.removePropertyChangeListener(l);
+ } else {
+ super.removePropertyChangeListener(l);
+ }
+ }
+
+ /**
+ * Get the AccessibleAction associated with this object. In the
+ * implementation of the Java Accessibility API for this class,
+ * return this object, which is responsible for implementing the
+ * AccessibleAction interface on behalf of itself.
+ *
+ * @return this object
+ */
+ public AccessibleAction getAccessibleAction() {
+ return this;
+ }
+
+ /**
+ * Get the AccessibleComponent associated with this object. In the
+ * implementation of the Java Accessibility API for this class,
+ * return this object, which is responsible for implementing the
+ * AccessibleComponent interface on behalf of itself.
+ *
+ * @return this object
+ */
+ public AccessibleComponent getAccessibleComponent() {
+ return this; // to override getBounds()
+ }
+
+ /**
+ * Get the AccessibleSelection associated with this object if one
+ * exists. Otherwise return null.
+ *
+ * @return the AccessibleSelection, or null
+ */
+ public AccessibleSelection getAccessibleSelection() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null && isLeaf) {
+ return getCurrentAccessibleContext().getAccessibleSelection();
+ } else {
+ return this;
+ }
+ }
+
+ /**
+ * Get the AccessibleText associated with this object if one
+ * exists. Otherwise return null.
+ *
+ * @return the AccessibleText, or null
+ */
+ public AccessibleText getAccessibleText() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ return getCurrentAccessibleContext().getAccessibleText();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the AccessibleValue associated with this object if one
+ * exists. Otherwise return null.
+ *
+ * @return the AccessibleValue, or null
+ */
+ public AccessibleValue getAccessibleValue() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ return getCurrentAccessibleContext().getAccessibleValue();
+ } else {
+ return null;
+ }
+ }
+
+
+ // AccessibleComponent methods
+
+ /**
+ * Get the background color of this object.
+ *
+ * @return the background color, if supported, of the object;
+ * otherwise, null
+ */
+ public Color getBackground() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getBackground();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.getBackground();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Set the background color of this object.
+ *
+ * @param c the new Color for the background
+ */
+ public void setBackground(Color c) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setBackground(c);
+ } else {
+ Component cp = getCurrentComponent();
+ if ( cp != null) {
+ cp.setBackground(c);
+ }
+ }
+ }
+
+
+ /**
+ * Get the foreground color of this object.
+ *
+ * @return the foreground color, if supported, of the object;
+ * otherwise, null
+ */
+ public Color getForeground() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getForeground();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.getForeground();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public void setForeground(Color c) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setForeground(c);
+ } else {
+ Component cp = getCurrentComponent();
+ if (cp != null) {
+ cp.setForeground(c);
+ }
+ }
+ }
+
+ public Cursor getCursor() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getCursor();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.getCursor();
+ } else {
+ Accessible ap = getAccessibleParent();
+ if (ap instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ap).getCursor();
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+
+ public void setCursor(Cursor c) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setCursor(c);
+ } else {
+ Component cp = getCurrentComponent();
+ if (cp != null) {
+ cp.setCursor(c);
+ }
+ }
+ }
+
+ public Font getFont() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getFont();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.getFont();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public void setFont(Font f) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setFont(f);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.setFont(f);
+ }
+ }
+ }
+
+ public FontMetrics getFontMetrics(Font f) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getFontMetrics(f);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.getFontMetrics(f);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).isEnabled();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.isEnabled();
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public void setEnabled(boolean b) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setEnabled(b);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.setEnabled(b);
+ }
+ }
+ }
+
+ public boolean isVisible() {
+ if (tree == null)
+ return false;
+ Rectangle pathBounds = tree.getPathBounds(path);
+ Rectangle parentBounds = tree.getVisibleRect();
+ if ( pathBounds != null && parentBounds != null &&
+ parentBounds.intersects(pathBounds) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void setVisible(boolean b) {
+ }
+
+ public boolean isShowing() {
+ return (tree.isShowing() && isVisible());
+ }
+
+ public boolean contains(Point p) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ Rectangle r = ((AccessibleComponent) ac).getBounds();
+ return r.contains(p);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ Rectangle r = c.getBounds();
+ return r.contains(p);
+ } else {
+ return getBounds().contains(p);
+ }
+ }
+ }
+
+ public Point getLocationOnScreen() {
+ if (tree != null) {
+ Point treeLocation = tree.getLocationOnScreen();
+ Rectangle pathBounds = tree.getPathBounds(path);
+ if (treeLocation != null && pathBounds != null) {
+ Point nodeLocation = new Point(pathBounds.x,
+ pathBounds.y);
+ nodeLocation.translate(treeLocation.x, treeLocation.y);
+ return nodeLocation;
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ private Point getLocationInJTree() {
+ Rectangle r = tree.getPathBounds(path);
+ if (r != null) {
+ return r.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public Point getLocation() {
+ Rectangle r = getBounds();
+ if (r != null) {
+ return r.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public void setLocation(Point p) {
+ }
+
+ public Rectangle getBounds() {
+ if (tree == null)
+ return null;
+ Rectangle r = tree.getPathBounds(path);
+ Accessible parent = getAccessibleParent();
+ if (parent instanceof AccessibleJTreeNode) {
+ Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree();
+ if (parentLoc != null && r != null) {
+ r.translate(-parentLoc.x, -parentLoc.y);
+ } else {
+ return null; // not visible!
+ }
+ }
+ return r;
+ }
+
+ public void setBounds(Rectangle r) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setBounds(r);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.setBounds(r);
+ }
+ }
+ }
+
+ public Dimension getSize() {
+ return getBounds().getSize();
+ }
+
+ public void setSize (Dimension d) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).setSize(d);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.setSize(d);
+ }
+ }
+ }
+
+ /**
+ * Returns the <code>Accessible</code> child, if one exists,
+ * contained at the local coordinate <code>Point</code>.
+ * Otherwise returns <code>null</code>.
+ *
+ * @param p point in local coordinates of this
+ * <code>Accessible</code>
+ * @return the <code>Accessible</code>, if it exists,
+ * at the specified location; else <code>null</code>
+ */
+ public Accessible getAccessibleAt(Point p) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).getAccessibleAt(p);
+ } else {
+ return null;
+ }
+ }
+
+ public boolean isFocusTraversable() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ return ((AccessibleComponent) ac).isFocusTraversable();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ return c.isFocusable();
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public void requestFocus() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).requestFocus();
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.requestFocus();
+ }
+ }
+ }
+
+ public void addFocusListener(FocusListener l) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).addFocusListener(l);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.addFocusListener(l);
+ }
+ }
+ }
+
+ public void removeFocusListener(FocusListener l) {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac instanceof AccessibleComponent) {
+ ((AccessibleComponent) ac).removeFocusListener(l);
+ } else {
+ Component c = getCurrentComponent();
+ if (c != null) {
+ c.removeFocusListener(l);
+ }
+ }
+ }
+
+ // AccessibleSelection methods
+
+ /**
+ * Returns the number of items currently selected.
+ * If no items are selected, the return value will be 0.
+ *
+ * @return the number of items currently selected.
+ */
+ public int getAccessibleSelectionCount() {
+ int count = 0;
+ int childCount = getAccessibleChildrenCount();
+ for (int i = 0; i < childCount; i++) {
+ TreePath childPath = getChildTreePath(i);
+ if (tree.isPathSelected(childPath)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Returns an Accessible representing the specified selected item
+ * in the object. If there isn't a selection, or there are
+ * fewer items selected than the integer passed in, the return
+ * value will be null.
+ *
+ * @param i the zero-based index of selected items
+ * @return an Accessible containing the selected item
+ */
+ public Accessible getAccessibleSelection(int i) {
+ int childCount = getAccessibleChildrenCount();
+ if (i < 0 || i >= childCount) {
+ return null; // out of range
+ }
+ int count = 0;
+ for (int j = 0; j < childCount && i >= count; j++) {
+ TreePath childPath = getChildTreePath(j);
+ if (tree.isPathSelected(childPath)) {
+ if (count == i) {
+ return new AccessibleJTreeNode(tree, childPath, this);
+ } else {
+ count++;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the current child of this object is selected.
+ *
+ * @param i the zero-based index of the child in this Accessible
+ * object.
+ * @see AccessibleContext#getAccessibleChild
+ */
+ public boolean isAccessibleChildSelected(int i) {
+ int childCount = getAccessibleChildrenCount();
+ if (i < 0 || i >= childCount) {
+ return false; // out of range
+ } else {
+ TreePath childPath = getChildTreePath(i);
+ return tree.isPathSelected(childPath);
+ }
+ }
+
+ /**
+ * Adds the specified selected item in the object to the object's
+ * selection. If the object supports multiple selections,
+ * the specified item is added to any existing selection, otherwise
+ * it replaces any existing selection in the object. If the
+ * specified item is already selected, this method has no effect.
+ *
+ * @param i the zero-based index of selectable items
+ */
+ public void addAccessibleSelection(int i) {
+ if (tree == null)
+ return;
+ TreeModel model = tree.getModel();
+ if (model != null) {
+ if (i >= 0 && i < getAccessibleChildrenCount()) {
+ TreePath path = getChildTreePath(i);
+ tree.addSelectionPath(path);
+ }
+ }
+ }
+
+ /**
+ * Removes the specified selected item in the object from the
+ * object's
+ * selection. If the specified item isn't currently selected, this
+ * method has no effect.
+ *
+ * @param i the zero-based index of selectable items
+ */
+ public void removeAccessibleSelection(int i) {
+ if (tree == null)
+ return;
+ TreeModel model = tree.getModel();
+ if (model != null) {
+ if (i >= 0 && i < getAccessibleChildrenCount()) {
+ TreePath path = getChildTreePath(i);
+ tree.removeSelectionPath(path);
+ }
+ }
+ }
+
+ /**
+ * Clears the selection in the object, so that nothing in the
+ * object is selected.
+ */
+ public void clearAccessibleSelection() {
+ int childCount = getAccessibleChildrenCount();
+ for (int i = 0; i < childCount; i++) {
+ removeAccessibleSelection(i);
+ }
+ }
+
+ /**
+ * Causes every selected item in the object to be selected
+ * if the object supports multiple selections.
+ */
+ public void selectAllAccessibleSelection() {
+ if (tree == null)
+ return;
+ TreeModel model = tree.getModel();
+ if (model != null) {
+ int childCount = getAccessibleChildrenCount();
+ TreePath path;
+ for (int i = 0; i < childCount; i++) {
+ path = getChildTreePath(i);
+ tree.addSelectionPath(path);
+ }
+ }
+ }
+
+ // AccessibleAction methods
+
+ /**
+ * Returns the number of accessible actions available in this
+ * tree node. If this node is not a leaf, there is at least
+ * one action (toggle expand), in addition to any available
+ * on the object behind the TreeCellRenderer.
+ *
+ * @return the number of Actions in this object
+ */
+ public int getAccessibleActionCount() {
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (ac != null) {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa != null) {
+ return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1));
+ }
+ }
+ return isLeaf ? 0 : 1;
+ }
+
+ /**
+ * Return a description of the specified action of the tree node.
+ * If this node is not a leaf, there is at least one action
+ * description (toggle expand), in addition to any available
+ * on the object behind the TreeCellRenderer.
+ *
+ * @param i zero-based index of the actions
+ * @return a description of the action
+ */
+ public String getAccessibleActionDescription(int i) {
+ if (i < 0 || i >= getAccessibleActionCount()) {
+ return null;
+ }
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (i == 0) {
+ // TIGER - 4766636
+ // return AccessibleAction.TOGGLE_EXPAND;
+ return "toggle expand";
+ } else if (ac != null) {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa != null) {
+ return aa.getAccessibleActionDescription(i - 1);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Perform the specified Action on the tree node. If this node
+ * is not a leaf, there is at least one action which can be
+ * done (toggle expand), in addition to any available on the
+ * object behind the TreeCellRenderer.
+ *
+ * @param i zero-based index of actions
+ * @return true if the the action was performed; else false.
+ */
+ public boolean doAccessibleAction(int i) {
+ if (i < 0 || i >= getAccessibleActionCount()) {
+ return false;
+ }
+ AccessibleContext ac = getCurrentAccessibleContext();
+ if (i == 0) {
+ if (tree.isExpanded(path)) {
+ tree.collapsePath(path);
+ } else {
+ tree.expandPath(path);
+ }
+ return true;
+ } else if (ac != null) {
+ AccessibleAction aa = ac.getAccessibleAction();
+ if (aa != null) {
+ return aa.doAccessibleAction(i - 1);
+ }
+ }
+ return false;
+ }
+
+ } // inner class AccessibleJTreeNode
+
+ /**
+ * A helper class to perform {@code Callable} objects on the event dispatch thread appropriate
+ * for the provided {@code AccessibleContext}.
+ */
+ private static class InvocationUtils {
+
+ /**
+ * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible}
+ * and waits for it to finish blocking the caller thread.
+ *
+ * @param callable the {@code Callable} to invoke
+ * @param accessible the {@code Accessible} which would be used to find the right context
+ * for the task execution
+ * @param <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> callable,
+ final Accessible accessible) {
+ if (accessible instanceof Component) {
+ return invokeAndWait(callable, (Component)accessible);
+ }
+ if (accessible instanceof AccessibleContext) {
+ // This case also covers the Translator
+ return invokeAndWait(callable, (AccessibleContext)accessible);
+ }
+ throw new RuntimeException("Unmapped Accessible used to dispatch event: " + accessible);
+ }
+
+ /**
+ * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Component}
+ * and waits for it to finish blocking the caller thread.
+ *
+ * @param callable the {@code Callable} to invoke
+ * @param component the {@code Component} which would be used to find the right context
+ * for the task execution
+ * @param <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> callable,
+ final Component component) {
+ return invokeAndWait(callable, SunToolkit.targetToAppContext(component));
+ }
+
+ /**
+ * Invokes a {@code Callable} in the {@code AppContext} mapped to the given {@code AccessibleContext}
+ * and waits for it to finish blocking the caller thread.
+ *
+ * @param callable the {@code Callable} to invoke
+ * @param accessibleContext the {@code AccessibleContext} which would be used to determine the right
+ * context for the task execution.
+ * @param <T> type parameter for the result value
+ *
+ * @return the result of the {@code Callable} execution
+ */
+ public static <T> T invokeAndWait(final Callable<T> callable,
+ final AccessibleContext accessibleContext) {
+ AppContext targetContext = AWTAccessor.getAccessibleContextAccessor()
+ .getAppContext(accessibleContext);
+ if (targetContext != null) {
+ return invokeAndWait(callable, targetContext);
+ } else {
+ // Normally this should not happen, unmapped context provided and
+ // the target AppContext is unknown.
+
+ // Try to recover in case the context is a translator.
+ if (accessibleContext instanceof Translator) {
+ Object source = ((Translator)accessibleContext).getSource();
+ if (source instanceof Component) {
+ return invokeAndWait(callable, (Component)source);
+ }
+ }
+ }
+ throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleContext);
+ }
+
+ private static <T> T invokeAndWait(final Callable<T> callable,
+ final AppContext targetAppContext) {
+ final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
+ try {
+ invokeAndWait(wrapper, targetAppContext);
+ T result = wrapper.getResult();
+ updateAppContextMap(result, targetAppContext);
+ return result;
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void invokeAndWait(final Runnable runnable,
+ final AppContext appContext)
+ throws InterruptedException, InvocationTargetException {
+
+ EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
+ Object lock = new Object();
+ Toolkit source = Toolkit.getDefaultToolkit();
+ InvocationEvent event =
+ new InvocationEvent(source, runnable, lock, true);
+ synchronized (lock) {
+ eq.postEvent(event);
+ lock.wait();
+ }
+
+ Throwable eventThrowable = event.getThrowable();
+ if (eventThrowable != null) {
+ throw new InvocationTargetException(eventThrowable);
+ }
+ }
+
+ /**
+ * Maps the {@code AccessibleContext} to the {@code AppContext} which should be used
+ * to dispatch events related to the {@code AccessibleContext}
+ * @param accessibleContext the {@code AccessibleContext} for the mapping
+ * @param targetContext the {@code AppContext} for the mapping
+ */
+ public static void registerAccessibleContext(final AccessibleContext accessibleContext,
+ final AppContext targetContext) {
+ if (accessibleContext != null) {
+ AWTAccessor.getAccessibleContextAccessor().setAppContext(accessibleContext, targetContext);
+ }
+ }
+
+ private static <T> void updateAppContextMap(final T accessibleContext,
+ final AppContext targetContext) {
+ if (accessibleContext instanceof AccessibleContext) {
+ registerAccessibleContext((AccessibleContext)accessibleContext, targetContext);
+ }
+ }
+
+ private static class CallableWrapper<T> implements Runnable {
+ private final Callable<T> callable;
+ private volatile T object;
+ private Exception e;
+
+ CallableWrapper(final Callable<T> callable) {
+ this.callable = callable;
+ }
+
+ public void run() {
+ try {
+ if (callable != null) {
+ object = callable.call();
+ }
+ } catch (final Exception e) {
+ this.e = e;
+ }
+ }
+
+ T getResult() throws Exception {
+ if (e != null)
+ throw e;
+ return object;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/ProviderImpl.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 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.internal;
+
+import javax.accessibility.AccessibilityProvider;
+
+/* This class provided methods to identify and activate the mapping from the
+ * JavaAccessBridge API to the Java Accessibility API.
+ */
+public final class ProviderImpl extends AccessibilityProvider {
+ /**
+ * Typically the service name returned by the name() method would be a simple
+ * name such as JavaAccessBridge, but the following name is used for compatibility
+ * with prior versions of ${user.home}/.accessibility.properties and
+ * ${java.home}/conf/accessibility.properties where the text on the
+ * assistive.technologies= line is a fully qualified class name. As of Java 9
+ * class names are no longer used to identify assistive technology implementations.
+ * If the properties file exists the installer will not replace it thus the
+ * need for compatibility.
+ */
+ private final String name = "com.sun.java.accessibility.AccessBridge";
+
+ public ProviderImpl() {}
+
+ public String getName() {
+ return name;
+ }
+
+ public void activate() {
+ /**
+ * Note that the AccessBridge is instantiated here rather than in the
+ * constructor. If the caller determines that this object is named
+ * "com.sun.java.accessibility.AccessBridge" then the caller will call
+ * start to instantiate the AccessBridge which will in turn activate it.
+ */
+ new AccessBridge();
+ }
+
+}
--- a/jdk/src/jdk.accessibility/windows/native/libjabsysinfo/AccessBridgeSysInfo.cpp Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/jdk.accessibility/windows/native/libjabsysinfo/AccessBridgeSysInfo.cpp Fri Aug 14 13:59:40 2015 -0500
@@ -37,7 +37,7 @@
// Determine bitness of Win OS
JNIEXPORT jboolean JNICALL
-Java_com_sun_java_accessibility_AccessBridge_isSysWow(JNIEnv *env, jobject callingObj) {
+Java_com_sun_java_accessibility_internal_AccessBridge_isSysWow(JNIEnv *env, jobject callingObj) {
BOOL bIsWow64 = FALSE;
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
--- a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp Fri Aug 14 13:59:40 2015 -0500
@@ -103,7 +103,7 @@
PrintDebugString("Calling BuildJavaEntryPoints():");
- FIND_CLASS(bridgeClass, "com/sun/java/accessibility/AccessBridge");
+ FIND_CLASS(bridgeClass, "com/sun/java/accessibility/internal/AccessBridge");
// ------- general methods
--- a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp Thu Aug 13 13:30:15 2015 -0700
+++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp Fri Aug 14 13:59:40 2015 -0500
@@ -30,7 +30,7 @@
#include "AccessBridgeDebug.h"
#include "JavaAccessBridge.h"
-#include "com_sun_java_accessibility_AccessBridge.h" // programatically generated by JNI
+#include "com_sun_java_accessibility_internal_AccessBridge.h" // programatically generated by JNI
#include "accessBridgeResource.h"
#include "accessBridgeCallbacks.h"
#include "AccessBridgeMessages.h"
@@ -84,7 +84,7 @@
*
*/
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) {
+ Java_com_sun_java_accessibility_internal_AccessBridge_runDLL(JNIEnv *env, jobject obj) {
PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called");
theJavaAccessBridge->javaRun(env, obj);
}
@@ -1711,7 +1711,7 @@
jobject event, jobject source,
jint oldValue, jint newValue) {
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)",
env, callingObj, event,
source, oldValue, newValue);
@@ -1765,7 +1765,7 @@
jobject event, jobject source,
jstring oldValue, jstring newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -1851,7 +1851,7 @@
jobject event, jobject source,
jstring oldValue, jstring newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -1937,7 +1937,7 @@
JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)",
env, callingObj, event, source);
// sanity check
@@ -1988,7 +1988,7 @@
jobject event, jobject source,
jstring oldValue, jstring newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -2074,7 +2074,7 @@
JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyTextChanged(%p, %p, %p, %p)",
env, callingObj, event, source);
// sanity check
@@ -2125,7 +2125,7 @@
jobject event, jobject source,
jstring oldValue, jstring newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -2210,7 +2210,7 @@
JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)",
env, callingObj, event, source);
// sanity check
@@ -2261,7 +2261,7 @@
jobject event, jobject source,
jobject oldValue, jobject newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -2319,7 +2319,7 @@
jobject event, jobject source,
jobject oldValue, jobject newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -2376,7 +2376,7 @@
jobject event, jobject source,
jstring oldValue, jstring newValue){
- PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
+ PrintDebugString("\r\nJava_com_sun_java_accessibility_internal_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)",
env, callingObj, event,
source, oldValue, newValue);
@@ -2557,7 +2557,7 @@
extern "C" { // event stuff from AccessBridge.h, generated by JNI
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) {
+ Java_com_sun_java_accessibility_internal_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) {
const wchar_t *stringBytes;
stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0);
@@ -2575,7 +2575,7 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jint oldValue, jint newValue) {
theJavaAccessBridge->firePropertyCaretChange(env, callingObj,
@@ -2584,7 +2584,7 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jstring oldValue, jstring newValue) {
theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj,
@@ -2593,7 +2593,7 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jstring oldValue, jstring newValue) {
theJavaAccessBridge->firePropertyNameChange(env, callingObj,
@@ -2602,14 +2602,14 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
theJavaAccessBridge->firePropertySelectionChange(env, callingObj,
event, source);
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jstring oldValue, jstring newValue) {
theJavaAccessBridge->firePropertyStateChange(env, callingObj,
@@ -2618,14 +2618,14 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
theJavaAccessBridge->firePropertyTextChange(env, callingObj,
event, source);
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jstring oldValue, jstring newValue) {
theJavaAccessBridge->firePropertyValueChange(env, callingObj,
@@ -2634,14 +2634,14 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source) {
theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj,
event, source);
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jobject oldValue, jobject newValue) {
theJavaAccessBridge->firePropertyChildChange(env, callingObj,
@@ -2650,7 +2650,7 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jobject oldValue,
jobject newValue) {
@@ -2660,7 +2660,7 @@
}
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj,
+ Java_com_sun_java_accessibility_internal_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj,
jobject event, jobject source,
jstring oldValue, jstring newValue) {
@@ -2677,34 +2677,34 @@
JNIEXPORT void JNICALL
- Java_com_sun_java_accessibility_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) {
+ Java_com_sun_java_accessibility_internal_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) {
theJavaAccessBridge->javaShutdown(env, callingObj);
}
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusGained, fireFocusGained)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusLost, fireFocusLost)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_caretUpdate, fireCaretUpdate)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseClicked, fireMouseClicked)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseEntered, fireMouseEntered)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseExited, fireMouseExited)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mousePressed, fireMousePressed)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseReleased, fireMouseReleased)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuCanceled, fireMenuCanceled)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuDeselected, fireMenuDeselected)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuSelected, fireMenuSelected)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuCanceled, firePopupMenuCanceled)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible)
- HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_focusGained, fireFocusGained)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_focusLost, fireFocusLost)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_caretUpdate, fireCaretUpdate)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseClicked, fireMouseClicked)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseEntered, fireMouseEntered)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseExited, fireMouseExited)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mousePressed, fireMousePressed)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_mouseReleased, fireMouseReleased)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuCanceled, fireMenuCanceled)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuDeselected, fireMenuDeselected)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_menuSelected, fireMenuSelected)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuCanceled, firePopupMenuCanceled)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible)
+ HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_internal_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible)
/*
* Map a HWND to a Java component
*
- * Class: com_sun_java_accessibility_AccessBridge
+ * Class: com_sun_java_accessibility_internal_AccessBridge
* Method: jawtGetComponentFromNativeWindowHandle
* Signature: (I)Ljava/awt/Component;
*/
JNIEXPORT jobject JNICALL
- Java_com_sun_java_accessibility_AccessBridge_jawtGetComponentFromNativeWindowHandle
+ Java_com_sun_java_accessibility_internal_AccessBridge_jawtGetComponentFromNativeWindowHandle
(JNIEnv *env, jobject callingObj, jint windowHandle) {
JAWT awt;
@@ -2726,12 +2726,12 @@
/*
* Map a Java component to a HWND
*
- * Class: com_sun_java_accessibility_AccessBridge
+ * Class: com_sun_java_accessibility_internal_AccessBridge
* Method: jawtGetNativeWindowHandleFromComponent
* Signature: (Ljava/awt/Component;)I
*/
JNIEXPORT jint JNICALL
- Java_com_sun_java_accessibility_AccessBridge_jawtGetNativeWindowHandleFromComponent
+ Java_com_sun_java_accessibility_internal_AccessBridge_jawtGetNativeWindowHandleFromComponent
(JNIEnv *env, jobject callingObj, jobject component) {
JAWT awt;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/java/accessibility/util/8051626/Bug8051626.java Fri Aug 14 13:59:40 2015 -0500
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8051626
+ * @summary Ensure no failure when using Java Accessibility Utility with security manager
+ * @modules java.desktop jdk.accessibility
+ *
+ * @run main/othervm Bug8051626
+ */
+
+import com.sun.java.accessibility.util.AWTEventMonitor;
+import java.awt.Dimension;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class Bug8051626 {
+
+ public static void main(final String[] args) throws InterruptedException,
+ InvocationTargetException {
+ final Bug8051626 app = new Bug8051626();
+ app.test();
+ }
+
+ private void test() throws InterruptedException, InvocationTargetException {
+ System.setSecurityManager(new SecurityManager());
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ final JFrame frame = new JFrame("Bug 8051626");
+ try {
+ final JPanel panel = new JPanel();
+ final JButton okButton = new JButton("OK");
+ panel.add(okButton);
+ frame.getContentPane().add(panel);
+ frame.setMinimumSize(new Dimension(300, 180));
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.pack();
+ frame.setLocation(400, 300);
+ frame.setVisible(true);
+ // If the security manager is on this should not cause an exception.
+ // Prior to the 8051626 fix it would as follows:
+ // java.security.AccessControlException:
+ // access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.java.accessibility.util")
+ AWTEventMonitor.getComponentWithFocus();
+ } finally {
+ frame.dispose();
+ }
+ }
+ });
+ }
+
+}