javauis/lcdui_qt/src/javax/microedition/lcdui/ChoiceImpl.java
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 03 May 2010 12:27:20 +0300
changeset 21 2a9601315dfc
child 23 98ccebc37403
permissions -rw-r--r--
Revision: v2.1.22 Kit: 201018

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

}