/*
* ScreenReaderHandler.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.accessibilitydemo.screenreaderdemo;
import net.rim.device.api.ui.accessibility.AccessibleContext;
import net.rim.device.api.ui.accessibility.AccessibleDateField;
import net.rim.device.api.ui.accessibility.AccessibleState;
import net.rim.device.api.ui.accessibility.AccessibleTable;
import net.rim.device.api.ui.accessibility.AccessibleText;
/**
* This class provides methods that handle the various accessible events
* specific to components defined by the AccessibleRole interface.
*/
public final class ScreenReaderHandler {
private static AccessibleContext _currentScreen;
/**
* Handles event generated by accessible component with role
* AccessibleRole.APP_ICON
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleAppIcon(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
final String appName = context.getAccessibleName();
Util.speak(appName + " icon focused");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.ICON
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleIcon(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
final String appName = context.getAccessibleName();
Util.speak(appName + " icon focused");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.CHECKBOX
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleCheckBox(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
String checkBoxLabel = context.getAccessibleName();
if (checkBoxLabel == null) {
checkBoxLabel = "";
}
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
final boolean checked =
(newValue & AccessibleState.CHECKED) != 0;
final String checkedSpeech = checked ? "checked" : "unchecked";
Util.speak("Check box " + checkBoxLabel + " focused "
+ checkedSpeech);
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.CHECKED)) {
Util.speak("Check box " + checkBoxLabel + " checked");
} else if (Util.hasTransitionedFromState(oldValue, newValue,
AccessibleState.CHECKED)) {
Util.speak("Check box " + checkBoxLabel + " unchecked");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("Mouse over check box " + checkBoxLabel);
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.DATE
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleDate(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
String dateFieldLabel = context.getAccessibleName();
if (dateFieldLabel == null) {
dateFieldLabel = "";
}
final AccessibleText text = context.getAccessibleText();
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak("Date field " + dateFieldLabel + " focused");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak("Date field " + dateFieldLabel + " expanded");
} else if (Util.hasTransitionedFromState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak("Date field " + dateFieldLabel + " collapsed");
}
if (text != null) {
Util.speak("Current value " + text.getWholeText());
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.DATE_FIELD
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleDateField(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
final AccessibleDateField dateField =
(AccessibleDateField) context;
final String dateSubfieldString =
Util.getDateSubfieldString(dateField.getDateFieldType());
Util.speak(dateSubfieldString + " focused");
}
break;
case AccessibleContext.ACCESSIBLE_VALUE_CHANGED:
final AccessibleDateField dateField = (AccessibleDateField) context;
final String dateSubfieldString =
Util.getDateSubfieldString(dateField.getDateFieldType());
Util.speak(dateSubfieldString + " value changed");
Util.speak("New value " + context.getAccessibleName());
break;
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.DIALOG
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleDialog(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.ACTIVE)) {
// Dialog became active, read it.
Util.speak("New dialog opened " + context.getAccessibleName());
for (int i = 0; i < context.getAccessibleChildCount(); i++) {
final AccessibleContext child =
context.getAccessibleChildAt(i);
ChildReader.readChildElement(child);
}
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.PANEL
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handlePanel(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.AVAILABLE)) {
Util.speak("Page Loaded");
ChildReader.readChildElement(context);
}
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak(context.getAccessibleName() + " focused");
ChildReader.readChildElement(context);
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.CHOICE
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleChoice(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.EXPANDED)) {
final int childCount = context.getAccessibleChildCount();
Util.speak("Choice field " + name + " expanded with "
+ childCount + " elements");
// Read a maximum of 10 items.
final int maxRead = Math.min(10, childCount);
for (int i = 0; i < maxRead; i++) {
final AccessibleContext child =
context.getAccessibleChildAt(i);
if (child != null) {
final int childState = child.getAccessibleStateSet();
final boolean childSelected =
(childState & AccessibleState.SELECTED) != 0;
Util.speak(child.getAccessibleName()
+ (childSelected ? " selected" : ""));
}
}
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.COLLAPSED)) {
Util.speak("Choice field " + name + " collapsed ");
final AccessibleContext child =
context.getAccessibleSelectionAt(0);
if (child != null) {
Util.speak(child.getAccessibleName() + " selected");
}
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak("Choice field " + name + " focused");
final AccessibleContext child =
context.getAccessibleSelectionAt(0);
if (child != null) {
Util.speak("Current value " + child.getAccessibleName());
}
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("Mouse over choice field " + name);
}
break;
case AccessibleContext.ACCESSIBLE_SELECTION_CHANGED:
final AccessibleContext child = context.getAccessibleSelectionAt(0);
if (child != null) {
Util.speak(child.getAccessibleName() + " selected");
}
break;
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.COMBO
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleCombo(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak("combo box " + name + " focused");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak("combo box " + name + " expanded");
} else if (Util.hasTransitionedFromState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak("combo box " + name + " collapsed");
}
break;
case AccessibleContext.ACCESSIBLE_CHILD_CHANGED:
// New values in the combo box drop-down list.
final AccessibleContext comboDropDownList =
context.getAccessibleChildAt(1);
final int childCount =
comboDropDownList != null ? comboDropDownList
.getAccessibleChildCount() : 0;
final int maxCount = Math.min(childCount, 10);
Util.speak("combo box " + name + " drop down values changed");
for (int i = 0; i < maxCount; i++) {
final AccessibleContext child =
comboDropDownList.getAccessibleChildAt(i);
ChildReader.readChildElement(child);
}
break;
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.BITMAP
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleBitmap(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
Util.speak("Mouse over image " + name);
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.TABLE
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleTable(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
final AccessibleTable table = context.getAccessibleTable();
if (table == null) {
System.out
.println("Accessible Table doesn't provide table interface");
return;
}
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.AVAILABLE)) {
Util.speak("Table " + name + " loaded");
ChildReader.readTableElement(context);
}
break;
case AccessibleContext.ACCESSIBLE_SELECTION_CHANGED:
handleTableSelection(table);
break;
case AccessibleContext.ACCESSIBLE_CHILD_CHANGED:
Util.speak("table " + name + " changed");
ChildReader.readChildElement(context);
break;
}
}
/**
* Helper method for handleTable()
*/
static void handleTableSelection(final AccessibleTable table) {
final AccessibleContext[] tableColumns =
table.getAccessibleColumnHeader();
final AccessibleContext[] tableRows = table.getAccessibleRowHeader();
final int[] selectedRows = table.getSelectedAccessibleRows();
final int[] selectedColumns = table.getSelectedAccessibleColumns();
if (selectedRows.length == 0 || selectedColumns.length == 0) {
// No cells selected.
Util.speak("no table cells selected");
} else if (selectedRows.length == 1 && selectedColumns.length == 1) {
// One cell selected.
final int row = selectedRows[0];
final int col = selectedColumns[0];
String rowCaption =
tableRows != null ? tableRows[row].getAccessibleName() : ""
+ (row + 1);
String colCaption =
tableColumns != null ? tableColumns[col]
.getAccessibleName() : "" + (col + 1);
if (rowCaption == null) {
rowCaption = "" + (row + 1);
}
if (colCaption == null) {
colCaption = "" + (col + 1);
}
Util.speak("One cell selected column " + colCaption + " row "
+ rowCaption);
final AccessibleContext cell = table.getAccessibleAt(row, col);
if (cell != null) {
ChildReader.readChildElement(cell);
} else {
Util.speak("cell empty");
}
} else if (selectedColumns.length == 1) {
// Multiple rows in one cell selected.
final int col = selectedColumns[0];
final int rowCount = selectedRows.length;
String startRowCaption =
tableRows != null ? tableRows[selectedRows[0]]
.getAccessibleName() : "" + (selectedRows[0] + 1);
final String endRowCaption =
tableRows != null ? tableRows[selectedRows[rowCount - 1]]
.getAccessibleName() : ""
+ (selectedRows[rowCount - 1] + 1);
String colCaption =
tableColumns != null ? tableColumns[col]
.getAccessibleName() : "column " + (col + 1);
if (startRowCaption == null) {
startRowCaption = "" + (selectedRows[0] + 1);
}
if (colCaption == null) {
colCaption = "" + (selectedRows[rowCount - 1] + 1);
}
Util.speak(rowCount + " cells selected in column " + colCaption);
Util.speak("start row " + startRowCaption + " end row "
+ endRowCaption);
boolean cellFilled = false;
for (int i = 0; i < selectedRows.length; i++) {
final AccessibleContext selected =
table.getAccessibleAt(selectedRows[i], col);
if (selected != null) {
ChildReader.readChildElement(selected);
cellFilled = true;
}
}
if (!cellFilled) {
Util.speak("all selected cells are empty");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.HYPERLINK
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleHyperLink(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("mouse over hyperlink "
+ context.getAccessibleName());
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.GAUGE
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleGauge(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
final String name = context.getAccessibleName();
switch (event) {
case AccessibleContext.ACCESSIBLE_VALUE_CHANGED: {
Util.speak(name + " value changed to "
+ context.getAccessibleValue().getCurrentAccessibleValue());
break;
}
case AccessibleContext.ACCESSIBLE_STATE_CHANGED: {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak(name + " focused ");
Util.speak(name
+ "value "
+ context.getAccessibleValue()
.getCurrentAccessibleValue());
}
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.LABEL
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleLabel(final int event, final int oldValue,
final int newValue, final AccessibleContext label) {
String name = label.getAccessibleName();
name = name != null ? name : "";
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak(name + " focused");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.SELECTED)) {
Util.speak(name + " selected");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak(name + " expanded");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.COLLAPSED)) {
Util.speak(name + " collapsed");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("mouse over " + name);
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.MENU
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleMenu(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.ACTIVE)) {
// Find active menu item.
final int childCount = context.getAccessibleChildCount();
final String orientation =
Util.getOrientation(context.getAccessibleStateSet());
Util.speak(orientation + " menu opened total " + childCount
+ " items");
final int readMax = Math.min(10, childCount);
for (int i = 0; i < readMax; i++) {
final AccessibleContext child =
context.getAccessibleChildAt(i);
ChildReader.readChildElement(child);
}
} else if (Util.hasTransitionedFromState(oldValue, newValue,
AccessibleState.ACTIVE)) {
Util.speak("menu closed");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.MENU_ITEM
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleMenuItem(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.SELECTED)) {
Util.speak(context.getAccessibleName() + " menu item selected");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.PUSH_BUTTON
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handlePushButton(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
Util.speak("button " + name + " focused");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.PUSHED)) {
Util.speak("button " + name + " pushed");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("mouse over button " + name);
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.RADIO_BUTTON
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleRadioButton(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
if (oldValue == AccessibleState.UNSET
&& newValue == AccessibleState.FOCUSED) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
Util.speak("radio button " + name);
}
}
if (oldValue == AccessibleState.FOCUSED
&& newValue == AccessibleState.SELECTED) {
if (event == AccessibleContext.ACCESSIBLE_STATE_CHANGED) {
Util.speak("radio button " + name);
Util.speak("Selected");
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.SCREEN
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleScreen(final int event, final int oldValue,
final int newValue, final AccessibleContext screen) {
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.ACTIVE)) {
// Screen became active, read it.
if (_currentScreen != screen) {
_currentScreen = screen;
Util.speak("new screen activated");
ChildReader.readChildElement(screen);
}
}
break;
case AccessibleContext.ACCESSIBLE_CHILD_CHANGED:
if (_currentScreen == screen) {
// Notify of the change.
Util.speak("screen content changed");
ChildReader.readChildElement(screen);
}
break;
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.LIST
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleList(final int event, final int oldValue,
final int newValue, final AccessibleContext list) {
String name = list.getAccessibleName();
name = name != null ? name : "";
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.FOCUSED)) {
final String orientation =
Util.getOrientation(list.getAccessibleStateSet());
Util.speak(orientation + " list " + name + " focused total "
+ list.getAccessibleChildCount() + " elements");
handleListSelection(list);
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.AVAILABLE)) {
Util.speak("list " + name + " loaded");
ChildReader.readChildElement(list);
}
break;
case AccessibleContext.ACCESSIBLE_CHILD_CHANGED:
Util.speak("list " + name + " changed");
ChildReader.readChildElement(list);
break;
case AccessibleContext.ACCESSIBLE_SELECTION_CHANGED:
handleListSelection(list);
break;
}
}
/**
* Helper method for handleList()
*
* @param list
* Field on which event occured
*/
private static void handleListSelection(final AccessibleContext list) {
final int selectedCount = list.getAccessibleSelectionCount();
String name = list.getAccessibleName();
if (name == null) {
name = "";
}
if (selectedCount == 0) {
Util.speak("no elements selected");
} else if (selectedCount == 1) {
final AccessibleContext selectedChild =
list.getAccessibleSelectionAt(0);
if (selectedChild == null) {
Util.speak("null Selection! in the list " + name);
} else {
Util.speak(selectedChild.getAccessibleName()
+ " selected in the list " + name);
}
} else {
Util.speak(selectedCount + " rows selected");
final int readMax = Math.min(5, selectedCount);
for (int i = 0; i < readMax; i++) {
ChildReader.readChildElement(list.getAccessibleSelectionAt(i));
}
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.SYMBOL
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleSymbol(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
final int count = context.getAccessibleChildCount();
int index;
for (index = count - 1; index >= 0; index--) {
if (context.isAccessibleChildSelected(index)) {
++index;
break;
}
}
final AccessibleContext item = context.getAccessibleSelectionAt(0);
final String output =
"Symbol: " + item.getAccessibleName() + ". " + index
+ " out of " + count;
Util.speak(output);
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.TREE_FIELD
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleTreeField(final int event, final int oldValue,
final int newValue, final AccessibleContext context) {
switch (event) {
case AccessibleContext.ACCESSIBLE_SELECTION_CHANGED:
final AccessibleContext selectedChild =
context.getAccessibleSelectionAt(0);
String name = selectedChild.getAccessibleName();
if (name == null) {
name = "";
}
final int states = selectedChild.getAccessibleStateSet();
final String expandableText =
(states & AccessibleState.EXPANDABLE) != 0 ? " expandable"
: "";
Util.speak(name + " node selected" + expandableText);
break;
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
AccessibleContext item = null;
final int count = context.getAccessibleChildCount();
if (count != 0) {
item = context.getAccessibleSelectionAt(0);
if (item != null) {
String name2 = item.getAccessibleName();
if (name2 == null) {
name2 = "";
}
if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.EXPANDED)) {
Util.speak(name2 + " node expanded");
} else if (Util.hasTransitionedToState(oldValue, newValue,
AccessibleState.COLLAPSED)) {
Util.speak(name2 + " node collapsed");
}
}
}
break;
}
}
/**
* Handles event generated by accessible component with role
* AccessibleRole.TEXT_FIELD
*
* @param event
* Accessible event that occured
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
static void handleTextField(final int event, final Object oldValue,
final Object newValue, final AccessibleContext context) {
int _oldValue = AccessibleState.UNSET;
int _newValue = AccessibleState.UNSET;
if (oldValue instanceof Integer) {
_oldValue = ((Integer) oldValue).intValue();
}
if (newValue instanceof Integer) {
_newValue = ((Integer) newValue).intValue();
}
String name = context.getAccessibleName();
if (name == null) {
name = "";
}
final AccessibleText aText = context.getAccessibleText();
switch (event) {
case AccessibleContext.ACCESSIBLE_STATE_CHANGED:
if (Util.hasTransitionedToState(_oldValue, _newValue,
AccessibleState.FOCUSED)) {
final boolean editable =
(_newValue & AccessibleState.EDITABLE) != 0;
final boolean selectable =
(_newValue & AccessibleState.SELECTABLE) != 0;
final String editableString = editable ? " editable" : "";
String value;
if (selectable) {
value =
aText != null ? aText.getAtIndex(
AccessibleText.LINE, aText
.getCaretPosition()) : null;
} else {
value = aText.getWholeText();
}
Util.speak(name + " focused " + editableString);
if (value != null) {
Util.speak(name + " text " + value);
}
} else if (Util.hasTransitionedToState(_oldValue, _newValue,
AccessibleState.SELECTED)) {
Util.speak("text field " + name + " enable selecting mode");
} else if (Util.hasTransitionedFromState(_oldValue, _newValue,
AccessibleState.SELECTED)) {
Util.speak("text field " + name + " disable selecting mode");
} else if (Util.hasTransitionedToState(_oldValue, _newValue,
AccessibleState.MOUSE_OVER)) {
Util.speak("mouse over text field " + name);
}
break;
case AccessibleContext.ACCESSIBLE_TEXT_CHANGED:
handleTextChanged((String) oldValue, (String) newValue, context);
break;
case AccessibleContext.ACCESSIBLE_CARET_CHANGED:
final String oldLine =
aText.getAtIndex(AccessibleText.LINE, _oldValue + 1);
if (Math.abs(_oldValue - _newValue) == 1 && oldLine.length() != 0) {
// Sample handling indicates horizontal scroll occurred - says
// the char.
Util.speak(aText.getAtIndex(AccessibleText.CHAR, aText
.getCaretPosition()));
} else {
// Sample handling indicates vertical scroll occurred - says the
// line.
Util.speak(aText.getAtIndex(AccessibleText.LINE, ++_newValue));
}
break;
}
}
/**
* Helper method for handleTextField()
*
* @param oldValue
* Depends on event type
* @param newValue
* Depends on event type
* @param context
* Field on which event occured
*/
private static void handleTextChanged(final String oldValue,
final String newValue, final AccessibleContext context) {
final AccessibleText aText = context.getAccessibleText();
if (aText != null) {
if (oldValue == null && newValue != null) {
System.out.println("Text: Insert: " + newValue);
System.out.println("Word At: "
+ aText.getAtIndex(AccessibleText.WORD, aText
.getCaretPosition()));
} else if (oldValue != null && newValue == null) {
System.out.println("Text: Delete: " + oldValue);
} else if (oldValue != null && newValue != null) {
System.out.println("Text: Replace: " + oldValue + " with "
+ newValue);
}
}
}
}