| /* Choice.java -- Java choice button widget. | |
| Copyright (C) 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package java.awt; | |
| import java.awt.event.ItemEvent; | |
| import java.awt.event.ItemListener; | |
| import java.awt.peer.ChoicePeer; | |
| import java.io.Serializable; | |
| import java.util.EventListener; | |
| import java.util.Vector; | |
| import javax.accessibility.Accessible; | |
| import javax.accessibility.AccessibleAction; | |
| import javax.accessibility.AccessibleContext; | |
| import javax.accessibility.AccessibleRole; | |
| /** | |
| * This class implements a drop down choice list. | |
| * | |
| * @author Aaron M. Renn (arenn@urbanophile.com) | |
| */ | |
| public class Choice extends Component | |
| implements ItemSelectable, Serializable, Accessible | |
| { | |
| /** | |
| * The number used to generate the name returned by getName. | |
| */ | |
| private static transient long next_choice_number; | |
| // Serialization constant | |
| private static final long serialVersionUID = -4075310674757313071L; | |
| /** | |
| * @serial A list of items for the choice box, which can be <code>null</code>. | |
| * This is package-private to avoid an accessor method. | |
| */ | |
| Vector pItems = new Vector(); | |
| /** | |
| * @serial The index of the selected item in the choice box. | |
| */ | |
| private int selectedIndex = -1; | |
| /** | |
| * ItemListener chain | |
| */ | |
| private ItemListener item_listeners; | |
| /** | |
| * This class provides accessibility support for the | |
| * combo box. | |
| * | |
| * @author Jerry Quinn (jlquinn@optonline.net) | |
| * @author Andrew John Hughes (gnu_andrew@member.fsf.org) | |
| */ | |
| protected class AccessibleAWTChoice | |
| extends AccessibleAWTComponent | |
| implements AccessibleAction | |
| { | |
| /** | |
| * Serialization constant to match JDK 1.5 | |
| */ | |
| private static final long serialVersionUID = 7175603582428509322L; | |
| /** | |
| * Default constructor which simply calls the | |
| * super class for generic component accessibility | |
| * handling. | |
| */ | |
| public AccessibleAWTChoice() | |
| { | |
| super(); | |
| } | |
| /** | |
| * Returns an implementation of the <code>AccessibleAction</code> | |
| * interface for this accessible object. In this case, the | |
| * current instance is simply returned (with a more appropriate | |
| * type), as it also implements the accessible action as well as | |
| * the context. | |
| * | |
| * @return the accessible action associated with this context. | |
| * @see javax.accessibility.AccessibleAction | |
| */ | |
| public AccessibleAction getAccessibleAction() | |
| { | |
| return this; | |
| } | |
| /** | |
| * Returns the role of this accessible object. | |
| * | |
| * @return the instance of <code>AccessibleRole</code>, | |
| * which describes this object. | |
| * @see javax.accessibility.AccessibleRole | |
| */ | |
| public AccessibleRole getAccessibleRole() | |
| { | |
| return AccessibleRole.COMBO_BOX; | |
| } | |
| /** | |
| * Returns the number of actions associated with this accessible | |
| * object. In this case, it is the number of choices available. | |
| * | |
| * @return the number of choices available. | |
| * @see javax.accessibility.AccessibleAction#getAccessibleActionCount() | |
| */ | |
| public int getAccessibleActionCount() | |
| { | |
| return pItems.size(); | |
| } | |
| /** | |
| * Returns a description of the action with the supplied id. | |
| * In this case, it is the text used in displaying the particular | |
| * choice on-screen. | |
| * | |
| * @param i the id of the choice whose description should be | |
| * retrieved. | |
| * @return the <code>String</code> used to describe the choice. | |
| * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int) | |
| */ | |
| public String getAccessibleActionDescription(int i) | |
| { | |
| return (String) pItems.get(i); | |
| } | |
| /** | |
| * Executes the action with the specified id. In this case, | |
| * calling this method provides the same behaviour as would | |
| * choosing a choice from the list in a visual manner. | |
| * | |
| * @param i the id of the choice to select. | |
| * @return true if a valid choice was specified. | |
| * @see javax.accessibility.AccessibleAction#doAccessibleAction(int) | |
| */ | |
| public boolean doAccessibleAction(int i) | |
| { | |
| if (i < 0 || i >= pItems.size()) | |
| return false; | |
| Choice.this.select( i ); | |
| return true; | |
| } | |
| } | |
| /** | |
| * Initializes a new instance of <code>Choice</code>. | |
| * | |
| * @exception HeadlessException If GraphicsEnvironment.isHeadless() | |
| * returns true | |
| */ | |
| public Choice() | |
| { | |
| if (GraphicsEnvironment.isHeadless()) | |
| throw new HeadlessException (); | |
| } | |
| /** | |
| * Returns the number of items in the list. | |
| * | |
| * @return The number of items in the list. | |
| */ | |
| public int getItemCount() | |
| { | |
| return countItems (); | |
| } | |
| /** | |
| * Returns the number of items in the list. | |
| * | |
| * @return The number of items in the list. | |
| * | |
| * @deprecated This method is deprecated in favor of <code>getItemCount</code>. | |
| */ | |
| public int countItems() | |
| { | |
| return pItems.size(); | |
| } | |
| /** | |
| * Returns the item at the specified index in the list. | |
| * | |
| * @param index The index into the list to return the item from. | |
| * | |
| * @exception ArrayIndexOutOfBoundsException If the index is invalid. | |
| */ | |
| public String getItem(int index) | |
| { | |
| return (String)pItems.elementAt(index); | |
| } | |
| /** | |
| * Adds the specified item to this choice box. | |
| * | |
| * @param item The item to add. | |
| * | |
| * @exception NullPointerException If the item's value is null | |
| * | |
| * @since 1.1 | |
| */ | |
| public synchronized void add(String item) | |
| { | |
| if (item == null) | |
| throw new NullPointerException ("item must be non-null"); | |
| pItems.addElement(item); | |
| if (peer != null) | |
| ((ChoicePeer) peer).add(item, getItemCount() - 1); | |
| if (selectedIndex == -1) | |
| select( 0 ); | |
| } | |
| /** | |
| * Adds the specified item to this choice box. | |
| * | |
| * This method is oboslete since Java 2 platform 1.1. Please use @see add | |
| * instead. | |
| * | |
| * @param item The item to add. | |
| * | |
| * @exception NullPointerException If the item's value is equal to null | |
| */ | |
| public synchronized void addItem(String item) | |
| { | |
| add(item); | |
| } | |
| /** Inserts an item into this Choice. Existing items are shifted | |
| * upwards. If the new item is the only item, then it is selected. | |
| * If the currently selected item is shifted, then the first item is | |
| * selected. If the currently selected item is not shifted, then it | |
| * remains selected. | |
| * | |
| * @param item The item to add. | |
| * @param index The index at which the item should be inserted. | |
| * | |
| * @exception IllegalArgumentException If index is less than 0 | |
| */ | |
| public synchronized void insert(String item, int index) | |
| { | |
| if (index < 0) | |
| throw new IllegalArgumentException ("index may not be less then 0"); | |
| if (index > getItemCount ()) | |
| index = getItemCount (); | |
| pItems.insertElementAt(item, index); | |
| if (peer != null) | |
| ((ChoicePeer) peer).add (item, index); | |
| if (selectedIndex == -1 || selectedIndex >= index) | |
| select(0); | |
| } | |
| /** | |
| * Removes the specified item from the choice box. | |
| * | |
| * @param item The item to remove. | |
| * | |
| * @exception IllegalArgumentException If the specified item doesn't exist. | |
| */ | |
| public synchronized void remove(String item) | |
| { | |
| int index = pItems.indexOf(item); | |
| if (index == -1) | |
| throw new IllegalArgumentException ("item \"" | |
| + item + "\" not found in Choice"); | |
| remove(index); | |
| } | |
| /** | |
| * Removes the item at the specified index from the choice box. | |
| * | |
| * @param index The index of the item to remove. | |
| * | |
| * @exception IndexOutOfBoundsException If the index is not valid. | |
| */ | |
| public synchronized void remove(int index) | |
| { | |
| if ((index < 0) || (index > getItemCount())) | |
| throw new IllegalArgumentException("Bad index: " + index); | |
| pItems.removeElementAt(index); | |
| if (peer != null) | |
| ((ChoicePeer) peer).remove( index ); | |
| if( getItemCount() == 0 ) | |
| selectedIndex = -1; | |
| else | |
| { | |
| if( selectedIndex > index ) | |
| selectedIndex--; | |
| else if( selectedIndex == index ) | |
| selectedIndex = 0; | |
| if( peer != null ) | |
| ((ChoicePeer)peer).select( selectedIndex ); | |
| } | |
| } | |
| /** | |
| * Removes all of the objects from this choice box. | |
| */ | |
| public synchronized void removeAll() | |
| { | |
| if (getItemCount() <= 0) | |
| return; | |
| pItems.removeAllElements (); | |
| if (peer != null) | |
| { | |
| ChoicePeer cp = (ChoicePeer) peer; | |
| cp.removeAll (); | |
| } | |
| selectedIndex = -1; | |
| } | |
| /** | |
| * Returns the currently selected item, or null if no item is | |
| * selected. | |
| * | |
| * @return The currently selected item. | |
| */ | |
| public synchronized String getSelectedItem() | |
| { | |
| return (selectedIndex == -1 | |
| ? null | |
| : ((String)pItems.elementAt(selectedIndex))); | |
| } | |
| /** | |
| * Returns an array with one row containing the selected item. | |
| * | |
| * @return An array containing the selected item. | |
| */ | |
| public synchronized Object[] getSelectedObjects() | |
| { | |
| if (selectedIndex == -1) | |
| return null; | |
| Object[] objs = new Object[1]; | |
| objs[0] = pItems.elementAt(selectedIndex); | |
| return objs; | |
| } | |
| /** | |
| * Returns the index of the selected item. | |
| * | |
| * @return The index of the selected item. | |
| */ | |
| public int getSelectedIndex() | |
| { | |
| return selectedIndex; | |
| } | |
| /** | |
| * Forces the item at the specified index to be selected. | |
| * | |
| * @param index The index of the row to make selected. | |
| * | |
| * @exception IllegalArgumentException If the specified index is invalid. | |
| */ | |
| public synchronized void select(int index) | |
| { | |
| if ((index < 0) || (index >= getItemCount())) | |
| throw new IllegalArgumentException("Bad index: " + index); | |
| if( selectedIndex == index ) | |
| return; | |
| selectedIndex = index; | |
| if( peer != null ) | |
| ((ChoicePeer)peer).select( index ); | |
| } | |
| /** | |
| * Forces the named item to be selected. | |
| * | |
| * @param item The item to be selected. | |
| * | |
| * @exception IllegalArgumentException If the specified item does not exist. | |
| */ | |
| public synchronized void select(String item) | |
| { | |
| int index = pItems.indexOf(item); | |
| if( index >= 0 ) | |
| select( index ); | |
| } | |
| /** | |
| * Creates the native peer for this object. | |
| */ | |
| public void addNotify() | |
| { | |
| if (peer == null) | |
| peer = getToolkit ().createChoice (this); | |
| super.addNotify (); | |
| } | |
| /** | |
| * Adds the specified listener to the list of registered listeners for | |
| * this object. | |
| * | |
| * @param listener The listener to add. | |
| */ | |
| public synchronized void addItemListener(ItemListener listener) | |
| { | |
| item_listeners = AWTEventMulticaster.add(item_listeners, listener); | |
| } | |
| /** | |
| * Removes the specified listener from the list of registered listeners for | |
| * this object. | |
| * | |
| * @param listener The listener to remove. | |
| */ | |
| public synchronized void removeItemListener(ItemListener listener) | |
| { | |
| item_listeners = AWTEventMulticaster.remove(item_listeners, listener); | |
| } | |
| /** | |
| * Processes this event by invoking <code>processItemEvent()</code> if the | |
| * event is an instance of <code>ItemEvent</code>, otherwise the event | |
| * is passed to the superclass. | |
| * | |
| * @param event The event to process. | |
| */ | |
| protected void processEvent(AWTEvent event) | |
| { | |
| if (event instanceof ItemEvent) | |
| processItemEvent((ItemEvent)event); | |
| else | |
| super.processEvent(event); | |
| } | |
| void dispatchEventImpl(AWTEvent e) | |
| { | |
| super.dispatchEventImpl(e); | |
| if( e.id <= ItemEvent.ITEM_LAST && e.id >= ItemEvent.ITEM_FIRST && | |
| ( item_listeners != null || | |
| ( eventMask & AWTEvent.ITEM_EVENT_MASK ) != 0 ) ) | |
| processEvent(e); | |
| } | |
| /** | |
| * Processes item event by dispatching to any registered listeners. | |
| * | |
| * @param event The event to process. | |
| */ | |
| protected void processItemEvent(ItemEvent event) | |
| { | |
| int index = pItems.indexOf((String) event.getItem()); | |
| if (item_listeners != null) | |
| item_listeners.itemStateChanged(event); | |
| } | |
| /** | |
| * Returns a debugging string for this object. | |
| * | |
| * @return A debugging string for this object. | |
| */ | |
| protected String paramString() | |
| { | |
| return "selectedIndex=" + selectedIndex + "," + super.paramString(); | |
| } | |
| /** | |
| * Returns an array of all the objects currently registered as FooListeners | |
| * upon this Choice. FooListeners are registered using the addFooListener | |
| * method. | |
| * | |
| * @exception ClassCastException If listenerType doesn't specify a class or | |
| * interface that implements java.util.EventListener. | |
| * | |
| * @since 1.3 | |
| */ | |
| public EventListener[] getListeners (Class listenerType) | |
| { | |
| if (listenerType == ItemListener.class) | |
| return AWTEventMulticaster.getListeners (item_listeners, listenerType); | |
| return super.getListeners (listenerType); | |
| } | |
| /** | |
| * Returns all registered item listeners. | |
| * | |
| * @since 1.4 | |
| */ | |
| public ItemListener[] getItemListeners () | |
| { | |
| return (ItemListener[]) getListeners (ItemListener.class); | |
| } | |
| /** | |
| * Gets the AccessibleContext associated with this <code>Choice</code>. | |
| * The context is created, if necessary. | |
| * | |
| * @return the associated context | |
| */ | |
| public AccessibleContext getAccessibleContext() | |
| { | |
| /* Create the context if this is the first request */ | |
| if (accessibleContext == null) | |
| accessibleContext = new AccessibleAWTChoice(); | |
| return accessibleContext; | |
| } | |
| /** | |
| * Generate a unique name for this <code>Choice</code>. | |
| * | |
| * @return A unique name for this <code>Choice</code>. | |
| */ | |
| String generateName() | |
| { | |
| return "choice" + getUniqueLong(); | |
| } | |
| private static synchronized long getUniqueLong() | |
| { | |
| return next_choice_number++; | |
| } | |
| } // class Choice |