/* * ValueComponent.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.customcomponentsdemo; import net.rim.device.api.system.Display; import net.rim.device.api.ui.AccessibleEventDispatcher; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.accessibility.AccessibleContext; import net.rim.device.api.ui.accessibility.AccessibleRole; import net.rim.device.api.ui.accessibility.AccessibleState; import net.rim.device.api.ui.accessibility.AccessibleTable; import net.rim.device.api.ui.accessibility.AccessibleText; import net.rim.device.api.ui.accessibility.AccessibleValue; /** * Sample implementation of a numerical accessible component. Provides the * screen reader application with information on the numerical data the field * contains. A user can change the value by pressing the U (up )and D (down) * keys. */ public final class ValueComponent extends Field implements AccessibleContext, AccessibleValue { private final int _min; private int _current; private final int _max; private int _state; /** * Constructs a new ValueComponent * * @param min * The minimum numerical value to be displayed in the field * @param current * The initial numerical value to be displayed in the field * @param max * The minimum numerical value to be displayed in the field */ public ValueComponent(final int min, final int current, final int max) { super(Field.FOCUSABLE); _min = min; _current = current; _max = max; // The component can recieve focused _state = AccessibleState.FOCUSABLE; } // ********************Field implementation ******************************** /** * @see Field#getAccessibleContext() */ public AccessibleContext getAccessibleContext() { return this; } /** * @see Field#getPreferredWidth() */ public int getPreferredWidth() { return Display.getWidth(); } /** * @see Field#getPreferredHeight() */ public int getPreferredHeight() { return getFont().getHeight(); } /** * @see Field#layout(int, int) */ protected void layout(final int width, final int height) { setExtent(getPreferredWidth(), getPreferredHeight()); } /** * @see Field#paint(Graphics) */ protected void paint(final Graphics graphics) { // Draw the current value. graphics.drawText(String.valueOf(_current), getPreferredWidth() / 2, 0); } /** * @see Field#keyChar(char, int, int) */ protected boolean keyChar(final char character, final int status, final int time) { final int previous = _current; // U key increases the value, D decreases if (character == 'u') { if (_current < _max) { _current++; } invalidate(); // Notify screen reader that value has changed if (previous != _current) { AccessibleEventDispatcher.dispatchAccessibleEvent( AccessibleContext.ACCESSIBLE_VALUE_CHANGED, new Integer(previous), new Integer(_current), this); } return true; } else if (character == 'd') { if (_current > _min) { _current--; } invalidate(); // Notify screen reader that value has changed if (previous != _current) { AccessibleEventDispatcher.dispatchAccessibleEvent( AccessibleContext.ACCESSIBLE_VALUE_CHANGED, new Integer(previous), new Integer(_current), this); } return true; } else { return super.keyChar(character, status, time); } } /** * @see Field#onFocus(int) */ protected void onFocus(final int direction) { super.onFocus(direction); // Update accessible state and notify screen reader final int oldState = _state; _state = _state | AccessibleState.FOCUSED; AccessibleEventDispatcher.dispatchAccessibleEvent( AccessibleContext.ACCESSIBLE_STATE_CHANGED, new Integer( oldState), new Integer(_state), this); } /** * @see Field#onUnfocus() */ protected void onUnfocus() { super.onUnfocus(); // Update accessible state and notify screen reader final int oldState = _state; _state = _state & ~AccessibleState.FOCUSED; AccessibleEventDispatcher.dispatchAccessibleEvent( AccessibleContext.ACCESSIBLE_STATE_CHANGED, new Integer( oldState), new Integer(_state), this); } // ********************** AccessibleContext implementation ***************** /** * @see AccessibleContext#getAccessibleName() */ public String getAccessibleName() { return " My Gauge Field "; } /** * @see AccessibleContext#getAccessibleValue() */ public AccessibleValue getAccessibleValue() { // The component implements AccessibleValue itself return this; } /** * @see AccessibleContext#getAccessibleParent() */ public AccessibleContext getAccessibleParent() { // Return manager where value component is added final Manager manager = getManager(); return manager != null ? manager.getAccessibleContext() : null; } /** * @see AccessibleContext#getAccessibleRole() */ public int getAccessibleRole() { // This is a gauge field, user can change its value by // pressing U (up) and D (down) keys. return AccessibleRole.GAUGE; } /** * @see AccessibleContext#getAccessibleStateSet() */ public int getAccessibleStateSet() { return _state; } /** * @see AccessibleContext#isAccessibleStateSet(int) */ public boolean isAccessibleStateSet(final int state) { return (getAccessibleStateSet() & state) != 0; } /** * @see AccessibleContext#getAccessibleChildAt(int) */ public AccessibleContext getAccessibleChildAt(final int index) { // No children in the value component return null; } /** * @see AccessibleContext#getAccessibleChildCount() */ public int getAccessibleChildCount() { // No children in the value component return 0; } /** * @see AccessibleContext#getAccessibleSelectionAt(int) */ public AccessibleContext getAccessibleSelectionAt(final int index) { // No children in the value component return null; } /** * @see AccessibleContext#getAccessibleSelectionCount() */ public int getAccessibleSelectionCount() { // No children in the value component return 0; } /** * @see AccessibleContext#isAccessibleChildSelected(int) */ public boolean isAccessibleChildSelected(final int index) { // No children in the value component return false; } /** * @see AccessibleContext#getAccessibleTable() */ public AccessibleTable getAccessibleTable() { // This is a numerical component, not a table return null; } /** * @see AccessibleContext#getAccessibleText() */ public AccessibleText getAccessibleText() { // This is a numerical component, not text return null; } // *************************************** AccessibleValue implementation /** * @see AccessibleValue#getCurrentAccessibleValue() */ public int getCurrentAccessibleValue() { // Return current value for this field return _current; } /** * @see AccessibleValue#getMaxAccessibleValue() */ public int getMaxAccessibleValue() { // Return maximum value for this field return _max; } /** * @see AccessibleValue#getMinAccessibleValue() */ public int getMinAccessibleValue() { // Return minimum value for this field return _min; } }