alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (JavaAccessibilityUtilities.m)

This example Java source code file (JavaAccessibilityUtilities.m) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributewithoutaxprefix, awt_threading, awtrunloopmode, bool, javaaccessibilityissupportedattribute, javaaccessibilityraiseunimplementedattributeexception, jnf_class_cache, jnf_member_cache, jnf_static_member_cache, jnfcallstaticobjectmethod, ljavax\/accessibility\/accessiblestate, nsstring, safe, sel

The JavaAccessibilityUtilities.m Java example source code

/*
 * Copyright (c) 2011, 2012, 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.
 */

#import "JavaAccessibilityUtilities.h"

#import <AppKit/AppKit.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>


static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute);
static void JavaAccessibilityLogError(NSString *message);
static void _JavaAccessibilityRaiseException(NSString *reason, SInt32 errorCode);
static NSString *AttributeWithoutAXPrefix(NSString *attribute);
static SEL JavaAccessibilityAttributeGetter(NSString *attribute);
static SEL JavaAccessibilityAttributeSettableTester(NSString *attribute);
static SEL JavaAccessibilityAttributeSetter(NSString *attribute);

NSString *const JavaAccessibilityIgnore = @"JavaAxIgnore";

NSMutableDictionary *sRoles = nil;
void initializeRoles();

// Unique
static JNF_CLASS_CACHE(sjc_AccessibleState, "javax/accessibility/AccessibleState");

// Duplicate
JNF_CLASS_CACHE(sjc_CAccessibility, "sun/lwawt/macosx/CAccessibility");
JNF_CLASS_CACHE(sjc_AccessibleComponent, "javax/accessibility/AccessibleComponent");
JNF_CLASS_CACHE(sjc_AccessibleContext, "javax/accessibility/AccessibleContext");
JNF_CLASS_CACHE(sjc_Accessible, "javax/accessibility/Accessible");
JNF_CLASS_CACHE(sjc_AccessibleRole, "javax/accessibility/AccessibleRole");
JNF_CLASS_CACHE(sjc_Point, "java/awt/Point");
JNF_CLASS_CACHE(sjc_AccessibleText, "javax/accessibility/AccessibleText");

JNF_MEMBER_CACHE(sjf_key, sjc_AccessibleRole, "key", "Ljava/lang/String;");
JNF_MEMBER_CACHE(sjf_X, sjc_Point, "x", "I");
JNF_MEMBER_CACHE(sjf_Y, sjc_Point, "y", "I");

NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
{
    static JNF_CLASS_CACHE(jc_Dimension, "java/awt/Dimension");
    static JNF_MEMBER_CACHE(jf_width, jc_Dimension, "width", "I");
    static JNF_MEMBER_CACHE(jf_height, jc_Dimension, "height", "I");
    static JNF_STATIC_MEMBER_CACHE(jm_getSize, sjc_CAccessibility, "getSize", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Dimension;");

    jobject dimension = JNFCallStaticObjectMethod(env, jm_getSize, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)

    if (dimension == NULL) return NSZeroSize;
    return NSMakeSize(JNFGetIntField(env, dimension, jf_width), JNFGetIntField(env, dimension, jf_height));
}

NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleRole, sjc_CAccessibility, "getAccessibleRole", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
    jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
    if (axRole == NULL) return @"unknown";

    return JNFJavaToNSString(env, axRole);
}

jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleSelection, sjc_CAccessibility, "getAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleSelection;");
    return JNFCallStaticObjectMethod(env, jm_getAccessibleSelection, axContext, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

jobject getAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_ax_getAccessibleSelection, sjc_CAccessibility, "ax_getAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)Ljavax/accessibility/Accessible;");
    return JNFCallStaticObjectMethod(env, jm_ax_getAccessibleSelection, axContext, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

void setAxContextSelection(JNIEnv *env, jobject axContext, jint index, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_addAccessibleSelection, sjc_CAccessibility, "addAccessibleSelection", "(Ljavax/accessibility/AccessibleContext;ILjava/awt/Component;)V");
    JNFCallStaticVoidMethod(env, jm_addAccessibleSelection, axContext, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

jobject getAxContext(JNIEnv *env, jobject accessible, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleContext, sjc_CAccessibility, "getAccessibleContext", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleContext;");
    return JNFCallStaticObjectMethod(env, jm_getAccessibleContext, accessible, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

BOOL isChildSelected(JNIEnv *env, jobject accessible, jint index, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_isAccessibleChildSelected, sjc_CAccessibility, "isAccessibleChildSelected", "(Ljavax/accessibility/Accessible;ILjava/awt/Component;)Z");
    return JNFCallStaticBooleanMethod(env, jm_isAccessibleChildSelected, accessible, index, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

jobject getAxStateSet(JNIEnv *env, jobject axContext, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleStateSet, sjc_CAccessibility, "getAccessibleStateSet", "(Ljavax/accessibility/AccessibleContext;Ljava/awt/Component;)Ljavax/accessibility/AccessibleStateSet;");
    return JNFCallStaticObjectMethod(env, jm_getAccessibleStateSet, axContext, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

BOOL containsAxState(JNIEnv *env, jobject axContext, jobject axState, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_contains, sjc_CAccessibility, "contains", "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleState;Ljava/awt/Component;)Z");
    return JNFCallStaticBooleanMethod(env, jm_contains, axContext, axState, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

BOOL isVertical(JNIEnv *env, jobject axContext, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;");
    jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL);
    return containsAxState(env, axContext, axVertState, component);
}

BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;");
    jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL);
    return containsAxState(env, axContext, axHorizState, component);
}

BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;");
    jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING);
    return containsAxState(env, axContext, axVisibleState, component);
}

NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_getLocationOnScreen, sjc_CAccessibility, "getLocationOnScreen", "(Ljavax/accessibility/AccessibleComponent;Ljava/awt/Component;)Ljava/awt/Point;");
    jobject jpoint = JNFCallStaticObjectMethod(env, jm_getLocationOnScreen, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
    if (jpoint == NULL) return NSZeroPoint;
    return NSMakePoint(JNFGetIntField(env, jpoint, sjf_X), JNFGetIntField(env, jpoint, sjf_Y));
}

jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)
{
    static JNF_STATIC_MEMBER_CACHE(jm_getCharCount, sjc_CAccessibility, "getCharCount", "(Ljavax/accessibility/AccessibleText;Ljava/awt/Component;)I");
    return JNFCallStaticIntMethod(env, jm_getCharCount, axText, component); // AWT_THREADING Safe (AWTRunLoopMode)
}

// The following JavaAccessibility methods are copied from the corresponding
// NSAccessibility methods in NSAccessibility.m.
//
// They implement a key-value-like coding scheme to transform messages like
//        [self accessibilityAttributeValue:NSAccessibilityEnabledAttribute]
// into calls on to specific methods like
//        [self accessibilityEnabledAttribute].

static NSString *AttributeWithoutAXPrefix(NSString *attribute)
{
    return [attribute hasPrefix:@"AX"] ? [attribute substringFromIndex:2] : attribute;
}

static SEL JavaAccessibilityAttributeGetter(NSString *attribute)
{
    return NSSelectorFromString([NSString stringWithFormat:@"accessibility%@Attribute", AttributeWithoutAXPrefix(attribute)]);
}

static SEL JavaAccessibilityAttributeSettableTester(NSString *attribute)
{
    return NSSelectorFromString([NSString stringWithFormat:@"accessibilityIs%@AttributeSettable", AttributeWithoutAXPrefix(attribute)]);
}

static SEL JavaAccessibilityAttributeSetter(NSString *attribute)
{
    return NSSelectorFromString([NSString stringWithFormat:@"accessibilitySet%@Attribute:", AttributeWithoutAXPrefix(attribute)]);
}

id JavaAccessibilityAttributeValue(id element, NSString *attribute)
{
    if (!JavaAccessibilityIsSupportedAttribute(element, attribute)) return nil;

    SEL getter = JavaAccessibilityAttributeGetter(attribute);
#ifdef JAVA_AX_DEBUG_PARMS
    if (![element respondsToSelector:getter]) {
        JavaAccessibilityRaiseUnimplementedAttributeException(__FUNCTION__, element, attribute);
        return nil;
    }
#endif

    return [element performSelector:getter];
}

BOOL JavaAccessibilityIsAttributeSettable(id element, NSString *attribute)
{
    if (!JavaAccessibilityIsSupportedAttribute(element, attribute)) return NO;

    SEL tester = JavaAccessibilityAttributeSettableTester(attribute);
#ifdef JAVA_AX_DEBUG_PARMS
    if (![element respondsToSelector:tester]) {
        JavaAccessibilityRaiseUnimplementedAttributeException(__FUNCTION__, element, attribute);
        return NO;
    }
#endif

    return [element performSelector:tester] != nil;
}

void JavaAccessibilitySetAttributeValue(id element, NSString *attribute ,id value)
{
    if (!JavaAccessibilityIsSupportedAttribute(element, attribute)) return;

    SEL setter = JavaAccessibilityAttributeSetter(attribute);
    if (![element accessibilityIsAttributeSettable:attribute]) return;

#ifdef JAVA_AX_DEBUG_PARMS
    if (![element respondsToSelector:setter]) {
        JavaAccessibilityRaiseUnimplementedAttributeException(__FUNCTION__, element, attribute);
        return;
    }
#endif

    [element performSelector:setter withObject:value];
}

static BOOL JavaAccessibilityIsSupportedAttribute(id element, NSString *attribute)
{
    return [[element accessibilityAttributeNames] indexOfObject:attribute] != NSNotFound;
}

/*
 * Class:     sun_lwawt_macosx_CAccessibility
 * Method:    roleKey
 * Signature: (Ljavax/accessibility/AccessibleRole;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_lwawt_macosx_CAccessibility_roleKey
(JNIEnv *env, jclass clz, jobject axRole)
{
    return JNFGetObjectField(env, axRole, sjf_key);
}


// errors from NSAccessibilityErrors
void JavaAccessibilityRaiseSetAttributeToIllegalTypeException(const char *functionName, id element, NSString *attribute, id value)
{
    NSString *reason = [NSString stringWithFormat:@"%s: Attempt set \"%@\" attribute to illegal type of value (%@:%@) for element: %@", functionName, attribute, [value class], value, element];
    _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
}

void JavaAccessibilityRaiseUnimplementedAttributeException(const char *functionName, id element, NSString *attribute)
{
    NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" attribute unimplemented by element: %@", functionName, attribute, element];
    _JavaAccessibilityRaiseException(reason, kAXErrorFailure);
}

void JavaAccessibilityRaiseIllegalParameterTypeException(const char *functionName, id element, NSString *attribute, id parameter)
{
    NSString *reason = [NSString stringWithFormat:@"%s: \"%@\" parameterized attribute passed illegal type of parameter (%@:%@) for element: %@", functionName, attribute, [parameter class], parameter, element];
    _JavaAccessibilityRaiseException(reason, kAXErrorIllegalArgument);
}

static void _JavaAccessibilityRaiseException(NSString *reason, SInt32 errorCode)
{
    JavaAccessibilityLogError(reason);
    [[NSException exceptionWithName:NSAccessibilityException reason:reason userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:errorCode], NSAccessibilityErrorCodeExceptionInfo, nil]] raise];
}

static void JavaAccessibilityLogError(NSString *message)
{
    NSLog(@"!!! %@", message);
}

// end appKit copies

/*
 To get the roles below, verify the perl has table below called macRoleCodes is correct.
 Then copy the perl code into a perl script called makeAxTables.pl (make
 sure to chmod +x makeAxTables.pl). Then run the perl script like this:

 ./makeAxTables.pl /Builds/jdk1_4_1/

 It will then write the void initializeRoles() method below to stdout.

 Any new AccessibleRole items that aren't in the perl hash table will be written out as follows:
 // Unknown AccessibleRole: <role>

 Add these unknowns to the perl hash table and re-run the script, and use the new generated table.
*/

// NOTE: Don't modify this directly. It is machine generated. See below
void initializeRoles()
{
    sRoles = [[NSMutableDictionary alloc] initWithCapacity:56];

    [sRoles setObject:JavaAccessibilityIgnore forKey:@"alert"];
    [sRoles setObject:NSAccessibilityGroupRole forKey:@"awtcomponent"];
    [sRoles setObject:NSAccessibilityGroupRole forKey:@"canvas"];
    [sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"checkbox"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"colorchooser"];
    [sRoles setObject:NSAccessibilityColumnRole forKey:@"columnheader"];
    [sRoles setObject:NSAccessibilityComboBoxRole forKey:@"combobox"];
    [sRoles setObject:NSAccessibilityTextFieldRole forKey:@"dateeditor"];
    [sRoles setObject:NSAccessibilityImageRole forKey:@"desktopicon"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"desktoppane"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"dialog"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"directorypane"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"filechooser"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"filler"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"fontchooser"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"frame"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"glasspane"];
    [sRoles setObject:NSAccessibilityGroupRole forKey:@"groupbox"];
    [sRoles setObject:NSAccessibilityStaticTextRole forKey:@"hyperlink"]; //maybe a group?
    [sRoles setObject:NSAccessibilityImageRole forKey:@"icon"];
    [sRoles setObject:NSAccessibilityGroupRole forKey:@"internalframe"];
    [sRoles setObject:NSAccessibilityStaticTextRole forKey:@"label"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"layeredpane"];
    [sRoles setObject:NSAccessibilityListRole forKey:@"list"]; // maybe a group? AccessibleRole.java says a list is: "An object that presents a list of objects to the user and allows the user to select one or more of them."
    [sRoles setObject:NSAccessibilityListRole forKey:@"listitem"];
    [sRoles setObject:NSAccessibilityMenuRole forKey:@"menu"];
    [sRoles setObject:NSAccessibilityMenuBarRole forKey:@"menubar"];
    [sRoles setObject:NSAccessibilityMenuItemRole forKey:@"menuitem"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"optionpane"];
    [sRoles setObject:NSAccessibilityRadioButtonRole forKey:@"pagetab"]; // cmcnote: cocoa tabs are radio buttons - one selected button out of a group of options
    [sRoles setObject:NSAccessibilityTabGroupRole forKey:@"pagetablist"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"panel"];
    [sRoles setObject:NSAccessibilityTextFieldRole forKey:@"passwordtext"];
    [sRoles setObject:NSAccessibilityPopUpButtonRole forKey:@"popupmenu"];
    [sRoles setObject:NSAccessibilityProgressIndicatorRole forKey:@"progressbar"];
    [sRoles setObject:NSAccessibilityButtonRole forKey:@"pushbutton"];
    [sRoles setObject:NSAccessibilityRadioButtonRole forKey:@"radiobutton"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"rootpane"];
    [sRoles setObject:NSAccessibilityRowRole forKey:@"rowheader"];
    [sRoles setObject:NSAccessibilityScrollBarRole forKey:@"scrollbar"];
    [sRoles setObject:NSAccessibilityScrollAreaRole forKey:@"scrollpane"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"separator"];
    [sRoles setObject:NSAccessibilitySliderRole forKey:@"slider"];
    [sRoles setObject:NSAccessibilityIncrementorRole forKey:@"spinbox"];
    [sRoles setObject:NSAccessibilitySplitGroupRole forKey:@"splitpane"];
    [sRoles setObject:NSAccessibilityValueIndicatorRole forKey:@"statusbar"];
    [sRoles setObject:NSAccessibilityGroupRole forKey:@"swingcomponent"];
    [sRoles setObject:NSAccessibilityTableRole forKey:@"table"];
    [sRoles setObject:NSAccessibilityTextFieldRole forKey:@"text"];
    [sRoles setObject:NSAccessibilityTextAreaRole forKey:@"textarea"]; // supports top/bottom of document notifications: CAccessability.getAccessibleRole()
    [sRoles setObject:NSAccessibilityCheckBoxRole forKey:@"togglebutton"];
    [sRoles setObject:NSAccessibilityToolbarRole forKey:@"toolbar"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"tooltip"];
    [sRoles setObject:NSAccessibilityBrowserRole forKey:@"tree"];
    [sRoles setObject:NSAccessibilityUnknownRole forKey:@"unknown"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"viewport"];
    [sRoles setObject:JavaAccessibilityIgnore forKey:@"window"];
}

Other Java examples (source code examples)

Here is a short list of links related to this Java JavaAccessibilityUtilities.m source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.