Package com.rim.samples.device.accessibilitydemo.screenreaderdemo

Source Code of com.rim.samples.device.accessibilitydemo.screenreaderdemo.ScreenReaderHandler

/*
* 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);
            }
        }
    }
}
TOP

Related Classes of com.rim.samples.device.accessibilitydemo.screenreaderdemo.ScreenReaderHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.