/* * TableComponent.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.ui.Field; 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; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.VerticalFieldManager; /** * Sample implementation of a tabular accessible UI component. The table cells * consist of instances of the AccessibleLabel inner class arranged in columns * and rows. This particular table is equivalent to an HTML type table in that * the cells can not be selected individually. */ public final class TableComponent extends HorizontalFieldManager implements AccessibleContext, AccessibleTable { private final int _columnCount; private final int _rowCount; private final String[] _columnNames; private final String[][] _cells; /** * Constructs a new TableComponent * * @param columnCount * The number of columns in the table * @param rowCount * The number of rows in the table */ public TableComponent(final int columnCount, final int rowCount) { super(Field.USE_ALL_WIDTH); _columnCount = columnCount; _rowCount = rowCount; // Initialize the table _columnNames = new String[_columnCount]; _cells = new String[_rowCount][_columnCount]; final VerticalFieldManager[] columns = new VerticalFieldManager[columnCount]; for (int i = 0; i < _columnCount; i++) { columns[i] = new VerticalFieldManager(); for (int j = 0; j < _rowCount; j++) { final HorizontalFieldManager hfm = new HorizontalFieldManager(); final String text = "TC" + "(" + i + ", " + j + ")"; _cells[j][i] = text; hfm.add(new LabelField(text)); hfm.add(new LabelField(" | ")); columns[i].add(hfm); } add(columns[i]); } } /** * @see Manager#getAccessibleContext() */ public AccessibleContext getAccessibleContext() { return this; } // ***************** AccessibleTable implementation ************************ /** * @see AccessibleTable#getAccessibleAt(int, int) */ public AccessibleContext getAccessibleAt(final int r, final int c) { // Check whether the cell is selected final boolean cellSelected = isAccessibleSelected(r, c); // Wrap the cell value into a label return new AccessibleLabel(_cells[r][c], cellSelected); } /** * @see AccessibleTable#getAccessibleColumnCount() */ public int getAccessibleColumnCount() { // Number of columns in the table return _columnCount; } /** * @see AccessibleTable#getAccessibleRowCount() */ public int getAccessibleRowCount() { // Return number of rows in the table return _rowCount; } /** * @see AccessibleTable#getAccessibleColumnHeader() */ public AccessibleContext[] getAccessibleColumnHeader() { // Return an array of column names as collection of labels final AccessibleContext[] result = new AccessibleContext[_columnNames.length]; for (int i = 0; i < result.length; i++) { result[i] = new AccessibleLabel(_columnNames[i], false); } return result; } /** * @see AccessibleTable#getAccessibleRowHeader() */ public AccessibleContext[] getAccessibleRowHeader() { // There are no labels for table rows, only columns have labels return null; } /** * @see AccessibleTable#getSelectedAccessibleColumns() */ public int[] getSelectedAccessibleColumns() { return new int[] { -1 }; } /** * @see AccessibleTable#getSelectedAccessibleRows() */ public int[] getSelectedAccessibleRows() { return new int[] { -1 }; } /** * @see AccessibleTable#isAccessibleSelected(int, int) */ public boolean isAccessibleSelected(final int r, final int c) { // Table cells are not selectable return false; } /** * Implementation of an accessible label, used as table cell or column * header label */ private class AccessibleLabel implements AccessibleContext { private final String _label; private final boolean _selected; // True if the label is selected - // applicable for table cells only /** * Creates a new AccessibleLabel object * * @param label * Text to display on the label * @param selected * True if the label is selected, otherwise false */ private AccessibleLabel(final String label, final boolean selected) { _label = label; _selected = selected; } // ***************** AccessibleContext implementation // ******************** /** * @see AccessibleContext#getAccessibleName() */ public String getAccessibleName() { // Return label text. return _label; } /** * @see AccessibleContext#getAccessibleChildAt(int) */ public AccessibleContext getAccessibleChildAt(final int index) { // No children in the label. return null; } /** * @see AccessibleContext#getAccessibleChildCount() */ public int getAccessibleChildCount() { // No children in the label return 0; } /** * @see AccessibleContext#getAccessibleParent() */ public AccessibleContext getAccessibleParent() { // Return table component as parent return TableComponent.this; } /** * @see AccessibleContext#getAccessibleRole() */ public int getAccessibleRole() { // This accessible element should be treated as a label return AccessibleRole.LABEL; } /** * @see AccessibleContext#getAccessibleSelectionAt(int) */ public AccessibleContext getAccessibleSelectionAt(final int index) { // No children in the label return null; } /** * @see AccessibleContext#getAccessibleSelectionCount() */ public int getAccessibleSelectionCount() { // No children in the label return 0; } /** * @see AccessibleContext#getAccessibleStateSet() */ public int getAccessibleStateSet() { // User can select the label if (_selected) { return AccessibleState.SELECTABLE | AccessibleState.SELECTED; } else { return AccessibleState.SELECTABLE; } } /** * @see AccessibleContext#getAccessibleTable() */ public AccessibleTable getAccessibleTable() { // Label doesn't have another table inside return null; } /** * @see AccessibleContext#getAccessibleText() */ public AccessibleText getAccessibleText() { // No text return null; } /** * @see AccessibleContext#getAccessibleValue() */ public AccessibleValue getAccessibleValue() { // No numerical value return null; } /** * @see AccessibleContext#isAccessibleChildSelected(int) */ public boolean isAccessibleChildSelected(final int index) { // No children in the label return false; } /** * @see AccessibleContext#isAccessibleStateSet(int) */ public boolean isAccessibleStateSet(final int state) { return (getAccessibleStateSet() & state) != 0; } } // ******* AccessibleContext implementation for the TableComponent ******* /** * @see AccessibleContext#getAccessibleTable() */ public AccessibleTable getAccessibleTable() { // Return accessible table element return this; } /** * @see AccessibleContext#getAccessibleChildAt(int) */ public AccessibleContext getAccessibleChildAt(final int index) { // Table component doesn't have any children, // AccessibleTable interface should be used for tabular data. return null; } /** * @see AccessibleContext#getAccessibleChildCount() */ public int getAccessibleChildCount() { // Table component exposes its child cells through the // AccessibleTable interface. return 0; } /** * @see AccessibleContext#getAccessibleName() */ public String getAccessibleName() { // Will be provided to screen reader return " My Table "; } /** * @see AccessibleContext#getAccessibleParent() */ public AccessibleContext getAccessibleParent() { // Return manager where table component was added final Manager manager = getManager(); return manager != null ? manager.getAccessibleContext() : null; } /** * @see AccessibleContext#getAccessibleRole() */ public int getAccessibleRole() { // This is a table component, screen reader will get its info // through getAccessibleTable() method. return AccessibleRole.TABLE; } /** * @see AccessibleContext#getAccessibleSelectionAt(int) */ public AccessibleContext getAccessibleSelectionAt(final int index) { // Table component doesn't have any children, // AccessibleTable interface should be used for tabular selection data. return null; } /** * @see AccessibleContext#getAccessibleSelectionCount() */ public int getAccessibleSelectionCount() { // Table component doesn't have any children, // AccessibleTable interface should be used for tabular selection data. return 0; } /** * @see AccessibleContext#getAccessibleStateSet() */ public int getAccessibleStateSet() { // Table can be focused final boolean focused = isFocus(); if (focused) { return AccessibleState.FOCUSABLE | AccessibleState.FOCUSED; } else { return AccessibleState.FOCUSABLE; } } /** * @see AccessibleContext#isAccessibleStateSet(int) */ public boolean isAccessibleStateSet(final int state) { return (state & getAccessibleStateSet()) != 0; } /** * @see AccessibleContext#getAccessibleText() */ public AccessibleText getAccessibleText() { // Table has no text return null; } /** * @see AccessibleContext#getAccessibleValue() */ public AccessibleValue getAccessibleValue() { // Table has no numerical value return null; } /** * @see AccessibleContext#isAccessibleChildSelected(int) */ public boolean isAccessibleChildSelected(final int index) { // Table component doesn't have any children, // AccessibleTable interface should be used for tabular selection data. return false; } }