Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

 

Public API

...

Types

  • enum javafx.scene.AccessibleAction
  • enum javafx.scene.AccessibleAttribute
  • enum javafx.scene.AccessibleRole

Properties

  • Node#role
  • Node#roleDescription
  • Node#accessibleText
  • Node#accessibleHelp

Methods

  • Node#queryAccessibleAttribute(AccessibleAttribute, Object...)
    • Call

...

    • by the AT to returned the current value for the given attribute

...

  • Node#notifyAccessibleAttributeChanged(AccessibleAttribute)
        • Call by the Node to notify the AT that attribute has

      ...

        • changed

      ...

      • Node#executeAccessibleAction(AccessibleAction, Object)
            • Call by the AT to

          ...

            • execute the given action

          Node#queryAccessibleAttribute() and Node#executeAccessibleAction() are often over-ridden to handle additional attributes

          Scene#getAccessible() - This is the “root accessible”, it is special case, more on it later. It shouldn’t matter for control developer anyway.

          Node#getAccessible() - lazily create an accessible and forward all its requested to the Node, for example:

          Accessible#getAttribute -> Node#accGetAttribute, Accessible#executeAction -> Node#accExecuteAction,  and so on
          Subclasses of node override #accGetAttribute() to add more attributes to itFor example, Parent overrides accGetAttributequeryAccessibleAttribute() to answer to “Children”“CHILDREN”, Button override accGetAttributeoverrides queryAccessibleAttribute() to answer to “Title”“TITILE”When accGetAttribute is overwritten it queryAccessibleAttribute() is over-ridden it is important to call super at the end. Excepted by Node, no other Nodes reference Accessible directly.

           

          the super for attributes that are not handled so that the default value for the attribute is returned.

          Node#notifyAccessibleAttributeChanged() is final.

          Implementation (low level)

           

          The first time the OS operating system requests JavaFX for accessibility we forward this request all the way to any accessibility functionality, Scene#getAccessible() is called:

          On Windows:In Win32, 

          • GlassWindow.cpp#WindowProc for WM_GETOBJECT
            • ViewContainer.cpp#HandleViewGetAccessible()
              • View.java#getAccessible()
                • (GlassViewEventHandler)EventHandler#getSceneAccessible()
                  • GlassScene#TKSceneListener#getSceneAccessible()
                    • Scene#ScenePeerListener#getSceneAccessible()
                      • Scene#getAccessible()

           

          In On Mac:

          • GlassView3D.m#accessibilityAttributeName (as well other methods defined in NSAccessible)
            • GlassViewDelegate.m#getAccessible
              • View.java#getAccessible()
                • (GlassViewEventHandler)EventHandler#getSceneAccessible()
                  • GlassScene#TKSceneListener#getSceneAccessible()
                    • Scene#ScenePeerListener#getSceneAccessible()
                      • Scene#getAccessible()

           

          Note that in In GlassView3D.m the accessibilityAttributeName() is sent to the NSView , which correctly answers the AT.
          the first time accessibility functionality is needed.  We don’t need to change anything on the way NSView handles accessibilityAttributeName(). We just use it as hook to initialize our a11y. 

           We do, however, need to get in the way of intercept “accessibilityAttributeValue()” when the attribute is “NSAccessibilityChildrenAttribute” in order to add the operating system accessible of Scene#getRoot() to the otherwise empty list of children known by the NSView. This happens in Scene#getAccessible(), in the handling of the CHILDREN case, is where it happens.

          Note that For any element Node in the scene graph (Node and its subclasses and Scene) are always handle the same type of Accessible, which is always handled by the same type of PlatformAccessible, which is always handled by the same type of GlassAccessible. The mapping of these types is always 1 to 1:, there is exactly one operating system accessible object.

          Scene GraphSceneGlass JavaGlass Native
          Node->AccessiblePlatformAccessible:Nodes/SceneMacAccessible.java, WinAccessible.javaGlassAccessible
          GlassAccessible.m, GlassAccessible.cpp

           

          ...

          FX does not have different

          ...

          implementations of operating system accessible objects for

          ...

          different nodes.  A button or a list control each have a different instance of the operating system object, but these are all instances of Accessible (ie. there is no ButtonAccessible or ListAccessible).

          There is, however, one important difference. The PlatformAccessible that Accessible linked to the Scene is the only one where "getView() != null”, and it answer answers back to the OS operating system differently in some cases . It is only real object the OS sees (as it has a native element associated wit with it, a an HWND or a NSView).

          All the other PlatformAccessible (Accessible objects, which return NULL in getView() == NULL), starting at the scene’s root, are lightweight as far the OS is concerned.

          Another design decision:

          All the logics logic about how to handle OS operating system request is implemented in PlatformAccessible, here it does whatever dance is necessary to map Accessible.  Accessible maps these requests into calls to the public API and to map the results back to native object that the operating system requires.

          The GlassAccessible (the native side) has no control FX Control logic in it, it basically .  It gets requests from the OSoperating system, convert data types, call PlatformAccessible and convert calls into Java using the Accessible class and converts the result back.

          As much as possible in the implementation, using basic types. One , there is a one to one JNI mapping between names and concepts that the operating system uses.

          Note that GlassAccessible.m/MacAccessible shall implement NSAccessible entirely so that it can handle any request from the OSoperating system.  

          The same is true for GlassAccessible.cpp/WinAccessible, it implements IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRoot, IInvokeProvider, ISelectionProvider, ISelectionItemProvider, etc (whatever is needed to cover JavaFX).

          Accessible objects are created by the Node, only when requested by the screenreader, in #getAccessible(). Node releases the Accessible object when the node is removed from the Scene.