/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package javax.microedition.lcdui;
import java.util.Vector;
/**
* ChoiceImpl class implements the basic functionality of the Choice interface.
* <br> List and ChoiceGroup class use this class as their member to implement
* their own functionality.
*/
final class ChoiceImpl {
/**
* Internal class for storing Choice data.
*/
private class ChoiceData {
String text;
Image img;
Font font;
boolean sel;
ChoiceData(String text, Image img, Font font, boolean sel) {
this.text = text;
this.img = img;
this.font = font;
this.sel = sel;
}
}
/**
* Array of ChoiceData items.
*/
private Vector items = new Vector();
/**
* Fit policy flag.
*/
private int fitPolicy;
/**
* Stores if the choice allows single or multiple selections.
*/
private boolean multiSel;
/**
* Constructor.
*
* @param multiSel multi or single selection
*/
ChoiceImpl(boolean multiSel) {
this.multiSel = multiSel;
}
/**
* Check if the arrays are valid.
*
* @param textElements string array
* @param imgElements image array
*/
void check(String[] textElements, Image[] imgElements) {
// check textElements
if (textElements == null) {
throw new NullPointerException(
MsgRepository.CHOICE_EXCEPTION_TEXT_ARRAY_NULL);
}
// check every text element
for (int i = 0; i < textElements.length; i++) {
if (textElements[i] == null) {
throw new NullPointerException(
MsgRepository.CHOICE_EXCEPTION_ITEM_NULL + i);
}
}
// check imgElements array length
if (imgElements != null && imgElements.length != textElements.length) {
throw new IllegalArgumentException(
MsgRepository.CHOICE_EXCEPTION_INVALID_ARRAY_LENGTHS);
}
}
/**
* Append item with specified text and image.
*/
int append(String text, Image image) {
validateString(text);
ChoiceData data = new ChoiceData(text, image, Font.getDefaultFont(),
(!multiSel && size() == 0));
items.addElement(data);
// return index of added element
return size() - 1;
}
/**
* Insert item with specified text and image.
*/
void insert(int elementNum, String text, Image image) {
validateString(text);
validatePosition(elementNum, size() + 1);
ChoiceData data = new ChoiceData(text, image, Font.getDefaultFont(),
(!multiSel && size() == 0));
items.insertElementAt(data, elementNum);
}
/**
* Set item with specified text and image.
*/
void set(int elementNum, String text, Image image) {
validateString(text);
validatePosition(elementNum, size());
ChoiceData data = (ChoiceData) items.elementAt(elementNum);
data.text = text;
data.img = image;
}
/**
* Set item's font.
*/
void setFont(int elementNum, Font font) {
validatePosition(elementNum, size());
Font checkedFont = (font == null ? Font.getDefaultFont() : font);
((ChoiceData) items.elementAt(elementNum)).font = checkedFont;
}
/**
* Delete item from specified position.
*/
void delete(int elementNum) {
validatePosition(elementNum, size());
if (!multiSel && isSelected(elementNum) && size() > 1) {
// we are removing the selected item and there are more
if (elementNum == size() - 1) {
// select previous item
setSelected(elementNum - 1, true);
}
else {
// select next item
setSelected(elementNum + 1, true);
}
}
items.removeElementAt(elementNum);
}
/**
* Delete all items.
*/
void deleteAll() {
items.removeAllElements();
}
/**
* Get fit policy.
*/
int getFitPolicy() {
return fitPolicy;
}
/**
* Get the Font of a given item.
*/
Font getFont(int elementNum) {
validatePosition(elementNum, size());
return ((ChoiceData) items.elementAt(elementNum)).font;
}
/**
* Get the image of a given item.
*/
Image getImage(int elementNum) {
validatePosition(elementNum, size());
return ((ChoiceData) items.elementAt(elementNum)).img;
}
/**
* Get the text of a given item.
*/
String getString(int elementNum) {
validatePosition(elementNum, size());
return ((ChoiceData) items.elementAt(elementNum)).text;
}
/**
* Set fit policy.
*/
void setFitPolicy(int newFitPolicy) {
switch (newFitPolicy) {
case Choice.TEXT_WRAP_DEFAULT:
case Choice.TEXT_WRAP_OFF:
case Choice.TEXT_WRAP_ON:
fitPolicy = newFitPolicy;
break;
default:
throw new IllegalArgumentException(
MsgRepository.CHOICE_EXCEPTION_INVALID_FIT_POLICY);
}
}
/**
* Get the selection index. Returns the first selection index if multiple
* selection is allowed.
*/
int getSelectedIndex() {
final int size = size();
if (!multiSel) {
for (int i = 0; i < size; i++) {
if (isSelected(i)) {
return i;
}
}
}
return -1;
}
/**
* Checks if an item is selected.
*/
boolean isSelected(int elementNum) {
validatePosition(elementNum, size());
return ((ChoiceData) items.elementAt(elementNum)).sel;
}
/**
* Sets an item's selection.
*/
void setSelected(int elementNum, boolean select) {
validatePosition(elementNum, size());
if (multiSel) {
((ChoiceData) items.elementAt(elementNum)).sel = select;
}
else {
if (select) {
// clear all
final int size = size();
for (int i = 0; i < size; i++) {
((ChoiceData) items.elementAt(i)).sel = false;
}
// set just one
((ChoiceData) items.elementAt(elementNum)).sel = true;
}
}
}
/**
* Get selection flags.
*/
int getSelectedFlags(boolean[] selectedArray) {
validateSelectedArray(selectedArray);
final int size = size();
int numSelected = 0;
for (int i = 0; i < size; i++) {
if (((ChoiceData) items.elementAt(i)).sel) {
selectedArray[i] = true;
numSelected++;
}
else {
selectedArray[i] = false;
}
}
return numSelected;
}
/**
* Set selection flags.
*/
void setSelectedFlags(boolean[] selectedArray) {
validateSelectedArray(selectedArray);
final int size = size();
if (size > 0) {
if (multiSel) {
for (int i = 0; i < size; i++) {
((ChoiceData) items.elementAt(i)).sel = selectedArray[i];
}
}
else {
int firstSelected = 0;
for (int i = 0; i < size; i++) {
if (selectedArray[i]) {
firstSelected = i;
break;
}
}
setSelected(firstSelected, true);
}
}
}
/**
* Returns the size of the list.
*
* @return the lists size
*/
int size() {
return items.size();
}
/**
* Validates position.
*
* @param position an index of the text array
* @param upperBoundary upper boundary for position
*/
private void validatePosition(int position, int upperBoundary) {
if (position < 0 || position >= upperBoundary) {
throw new IndexOutOfBoundsException(
MsgRepository.CHOICE_EXCEPTION_INVALID_ITEM_INDEX);
}
}
/**
* Validates a string.
*
* @param str string
*/
private void validateString(String str) {
if (str == null) {
throw new NullPointerException(
MsgRepository.CHOICE_EXCEPTION_STRING_NULL);
}
}
/**
* Validates an array containing selections.
*
* @param selectedArray selected array
*/
private void validateSelectedArray(boolean[] selectedArray) {
if (selectedArray == null) {
throw new NullPointerException(
MsgRepository.CHOICE_EXCEPTION_ARRAY_NULL);
}
if (selectedArray.length < size()) {
throw new IllegalArgumentException(
MsgRepository.CHOICE_EXCEPTION_INVALID_ARRAY_SIZE);
}
}
}