Class AccessibleNode

java.lang.Object
limn.accessibility.AccessibleNode

public final class AccessibleNode extends Object
One element of an AccessibleTree: a role, a name with its provenance, a description, a language, a set of states, a rectangle, relations, and zero or more typed facets.

It is a value and holds no widget. Not a simplification: a client on the other side of a platform boundary can hold one element for minutes, and a node that pinned the widget it was described from would keep a detached subtree alive with nothing on screen referring to it and nothing able to see the leak.

Its links to its parent and siblings are indices into its own tree rather than references, because sibling navigation is a first-class operation on one of the three platforms and a children-list model makes every step of it scan a list.

  • Field Details

    • NONE

      public static final int NONE
      Neither a parent, a child nor a sibling: the value every absent link carries.
      See Also:
  • Method Details

    • id

      public long id()
      Returns:
      this node's process-wide identifier, stable across publishes for as long as the thing it describes stays in the widget tree. Never 0, which is what an absent identifier is.
    • identifier

      public String identifier()
      What a tool that drives the application from outside finds this node by: the id the application gave the widget (Widget.setId), and where it gave none, id() in decimal. It is what each platform's bridge publishes as the element's identifier. Nobody hears it. An application's id is as unique as the application made it; the number always is.
      Returns:
      the identifier; never empty
    • role

      public Accessible.Role role()
      Returns:
      what this node is; never null
    • name

      public String name()
      Returns:
      this node's name, already resolved under locale(); empty when it has none. Never null, and never resolved by a reader: a bridge reads this string from a thread where no locale scope is open, and resolving there would answer in the process language rather than the subtree's.
    • nameFrom

      public Accessible.NameFrom nameFrom()
      Returns:
      where name() came from; never null. One platform maps a name that is the control's own text and a name that describes it to different attributes, and publishes into exactly one of them.
    • description

      public String description()
      Returns:
      this node's longer description, already resolved; empty when it has none
    • locale

      public Locale locale()
      Returns:
      the language this node's text is in; never null. Per node and not per process, because a subtree can declare its own: a Hebrew interface holding an English code pane must reach the screen reader's pronunciation intact.
    • has

      public boolean has(Accessible.State state)
      Parameters:
      state - the state to test
      Returns:
      whether it is set on this node
    • states

      public Set<Accessible.State> states()
      Returns:
      every state set on this node. Builds a fresh set on each call; has(Accessible.State) is the one to ask in a loop.
    • x

      public float x()
      Returns:
      the left edge of this node's box, in its scene's logical points. Already physical and left-origin in a right-to-left interface as in a left-to-right one, because the toolkit mirrors by placing rather than by transforming. Converting to the screen is the reader's, once, from AccessibleTree's window stamp.
    • y

      public float y()
      Returns:
      the top edge of this node's box, in its scene's logical points
    • width

      public float width()
      Returns:
      the width of this node's box, in logical points
    • height

      public float height()
      Returns:
      the height of this node's box, in logical points
    • bounds

      public Rect bounds()
      Returns:
      this node's box as a rectangle. Allocates; the four accessors above do not.
    • relations

      public List<AccessibleRelation> relations()
      Returns:
      this node's relations; empty when it has none, and never modifiable
    • toggle

      public @Nullable ToggleFacet toggle()
      Returns:
      this node's checked state, or null when it has none
    • value

      public @Nullable ValueFacet value()
      Returns:
      this node's numeric value, or null when it has none
    • selection

      public @Nullable SelectionFacet selection()
      Returns:
      this node's selection, or null when it holds none
    • selectionItem

      public @Nullable SelectionItemFacet selectionItem()
      Returns:
      this node's membership of a selection, or null when it is in none
    • expand

      public @Nullable ExpandFacet expand()
      Returns:
      whether this node is open, or null when it does not open
    • text

      public @Nullable TextFacet text()
      Returns:
      this node's text, or null when it has none
    • scroll

      public @Nullable ScrollFacet scroll()
      Returns:
      this node's scroll position, or null when it does not scroll
    • window

      public @Nullable WindowFacet window()
      Returns:
      this node's window, or null when it is not one
    • table

      public @Nullable TableFacet table()
      Returns:
      this node's grid shape, or null when it is not a table
    • cell

      public @Nullable CellFacet cell()
      Returns:
      where this node sits in a table, or null when it is not a cell
    • hierarchy

      public @Nullable HierarchyFacet hierarchy()
      Returns:
      where this node stands in an outline, or null when it is not a row of one
    • actions

      public @Nullable ActionFacet actions()
      Returns:
      the verbs this node offers, or null when it offers none
    • accepts

      public boolean accepts(Accessible.Action action)
      Whether this node accepts a verb now, read off the snapshot alone, in the one place a bridge and a test ask it.

      A parameterless verb is accepted exactly when this node's ActionFacet publishes it. A setter is implied by a facet, and only on a node that is Accessible.State.ENABLED and Accessible.State.VISIBLE (the paragraph below): Accessible.Action.SET_VALUE by a ValueFacet that is not read-only, Accessible.Action.SET_TEXT by a TextFacet on a node without Accessible.State.READ_ONLY, and Accessible.Action.SET_CARET and Accessible.Action.SET_SELECTION by any TextFacet: moving the caret or selecting is reading, which read-only text allows and which every text widget performs through its own caret whether or not it may be written.

      ENABLED and VISIBLE together are the operable bit, on all three of the axes the scene refuses on. The walk clears ENABLED on a disabled widget and under a disabled ancestor, on a synthetic child its owner narrowed, and on every node outside the layer that owns input; it clears VISIBLE on a widget whose own flag or an ancestor's is false — an unselected tab's contents, a collapsed panel — which Scene's gate refuses as squarely as it refuses a disabled one. Not SHOWING: a node that is visible and merely clipped out of a scroll viewport keeps every setter, because the scene reveals it and performs (the free verbs' path). So a disabled text field keeps EDITABLE and never gains READ_ONLY (the two are never conflated), and still accepts no SET_TEXT; and a slider in a tab nobody selected keeps its writable value and accepts no SET_VALUE. The parameterless half needs no test of either bit: the walk takes every verb off such a node (Accessibility#inoperableAt), so the published list is already empty there, and this one reading is what Scene#performAccessibleAction re-checks on live widgets. Allocates nothing.

      Parameters:
      action - the verb
      Returns:
      whether a platform may post it to this node; a bridge refuses it synchronously otherwise
    • parent

      public int parent()
      Returns:
      the index of this node's parent, or NONE at a root
    • firstChild

      public int firstChild()
      Returns:
      the index of this node's first child, or NONE when it has none
    • lastChild

      public int lastChild()
      Returns:
      the index of this node's last child, or NONE when it has none
    • nextSibling

      public int nextSibling()
      Returns:
      the index of the sibling after this one, or NONE when it is the last
    • previousSibling

      public int previousSibling()
      Returns:
      the index of the sibling before this one, or NONE when it is the first
    • selectionContainer

      public int selectionContainer()
      The container whose selection this node is a member of: the nearest ancestor carrying a SelectionFacet, reached from this node's published parent by climbing only through synthetic ancestors that lack one — so a calendar day belongs to the grid and not to the week row it hangs under, a tab header to the strip, a list row to the list. Resolved once at publish; what the differ addresses SELECTION_CHANGED to, and what a bridge answers for the member's container and the container's members.
      Returns:
      the container's index, or NONE when this node carries no SelectionItemFacet, declared itself containerless, or the climb reached a widget node or the root without finding a container
    • toString

      public String toString()
      Overrides:
      toString in class Object