001: /*
002: * @(#)Choice.java 1.63 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package java.awt;
028:
029: import java.util.*;
030: import sun.awt.peer.ChoicePeer;
031: import sun.awt.PeerBasedToolkit;
032: import java.awt.event.*;
033: import java.io.ObjectOutputStream;
034: import java.io.ObjectInputStream;
035: import java.io.IOException;
036: import java.awt.AWTEventMulticaster;
037:
038: /**
039: * The <code>Choice</code> class presents a pop-up menu of choices.
040: * The current choice is displayed as the title of the menu.
041: * <p>
042: * The following code example produces a pop-up menu:
043: * <p>
044: * <hr><blockquote><pre>
045: * Choice ColorChooser = new Choice();
046: * ColorChooser.add("Green");
047: * ColorChooser.add("Red");
048: * ColorChooser.add("Blue");
049: * </pre></blockquote><hr>
050: * <p>
051: * After this choice menu has been added to a panel,
052: * it appears as follows in its normal state:
053: * <p>
054: * <img src="images-awt/Choice-1.gif"
055: * ALIGN=center HSPACE=10 VSPACE=7>
056: * <p>
057: * In the picture, <code>"Green"</code> is the current choice.
058: * Pushing the mouse button down on the object causes a menu to
059: * appear with the current choice highlighted.
060: * <p>
061: * @version 1.49 08/10/01
062: * @author Sami Shaio
063: * @author Arthur van Hoff
064: * @since JDK1.0
065: */
066: public class Choice extends Component implements ItemSelectable {
067: /**
068: * The items for the Choice.
069: */
070: Vector pItems;
071: /**
072: * The index of the current choice for this Choice.
073: */
074: int selectedIndex = -1;
075: transient ItemListener itemListener;
076: private static final String base = "choice";
077: private static int nameCounter = 0;
078: /*
079: * JDK 1.1 serialVersionUID
080: */
081: private static final long serialVersionUID = -4075310674757313071L;
082:
083: /**
084: * Creates a new choice menu. The menu initially has no items in it.
085: * <p>
086: * By default, the first item added to the choice menu becomes the
087: * selected item, until a different selection is made by the user
088: * by calling one of the <code>select</code> methods.
089: * @see java.awt.Choice#select(int)
090: * @see java.awt.Choice#select(java.lang.String)
091: * @since JDK1.0
092: */
093: public Choice() {
094: pItems = new Vector();
095: }
096:
097: /**
098: * Construct a name for this component. Called by getName() when the
099: * name is null.
100: */
101: String constructComponentName() {
102: return base + nameCounter++;
103: }
104:
105: /**
106: * Creates the Choice's peer. This peer allows us to change the look
107: * of the Choice without changing its functionality.
108: * @see java.awt.Toolkit#createChoice(java.awt.Choice)
109: * @see java.awt.Component#getToolkit()
110: * @since JDK1.0
111: */
112: public void addNotify() {
113: synchronized (getTreeLock()) {
114: if (peer == null)
115: peer = ((PeerBasedToolkit) getToolkit())
116: .createChoice(this );
117: super .addNotify();
118: }
119: }
120:
121: /**
122: * Returns the number of items in this <code>Choice</code> menu.
123: * @see java.awt.Choice#getItem
124: * @since JDK1.1
125: */
126: public int getItemCount() {
127: return countItems();
128: }
129:
130: /**
131: * @deprecated As of JDK version 1.1,
132: * replaced by <code>getItemCount()</code>.
133: */
134: public int countItems() {
135: return pItems.size();
136: }
137:
138: /**
139: * Gets the string at the specified index in this
140: * <code>Choice</code> menu.
141: * @param index the index at which to begin.
142: * @see java.awt.Choice#getItemCount
143: * @since JDK1.0
144: */
145: public String getItem(int index) {
146: return (String) pItems.elementAt(index);
147: }
148:
149: /**
150: * Adds an item to this <code>Choice</code> menu.
151: * @param item the item to be added
152: * @exception NullPointerException if the item's value is <code>null</code>.
153: * @since JDK1.1
154: */
155: public void add(String item) {
156: addItem(item);
157: }
158:
159: /**
160: * Adds an item to this Choice.
161: * @param item the item to be added
162: * @exception NullPointerException If the item's value is equal to null.
163: */
164: public synchronized void addItem(String item) {
165: if (item == null) {
166: throw new NullPointerException(
167: "cannot add null item to Choice");
168: }
169: pItems.addElement(item);
170: ChoicePeer peer = (ChoicePeer) this .peer;
171: if (peer != null) {
172: peer.add(item, pItems.size() - 1);
173: }
174: if (selectedIndex < 0) {
175: select(0);
176: }
177: }
178:
179: /**
180: * Inserts the item into this choice at the specified position.
181: * @param item the item to be inserted
182: * @param index the position at which the item should be inserted
183: * @exception IllegalArgumentException if index is less than 0.
184: */
185:
186: public synchronized void insert(String item, int index) {
187: if (index < 0) {
188: throw new IllegalArgumentException("index less than zero.");
189: }
190: int nitems = getItemCount();
191: Vector tempItems = new Vector();
192: /* Remove the item at index, nitems-index times
193: storing them in a temporary vector in the
194: order they appear on the choice menu.
195: */
196: for (int i = index; i < nitems; i++) {
197: tempItems.addElement(getItem(index));
198: remove(index);
199: }
200: add(item);
201: /* Add the removed items back to the choice menu, they
202: are already in the correct order in the temp vector.
203: */
204: for (int i = 0; i < tempItems.size(); i++) {
205: add((String) tempItems.elementAt(i));
206: }
207: }
208:
209: /**
210: * Remove the first occurrence of <code>item</code>
211: * from the <code>Choice</code> menu.
212: * @param item the item to remove from this <code>Choice</code> menu.
213: * @exception IllegalArgumentException if the item doesn't
214: * exist in the choice menu.
215: * @since JDK1.1
216: */
217: public synchronized void remove(String item) {
218: int index = pItems.indexOf(item);
219: if (index < 0) {
220: throw new IllegalArgumentException("item " + item
221: + " not found in choice");
222: } else {
223: remove(index);
224: }
225: }
226:
227: /**
228: * Removes an item from the choice menu
229: * at the specified position.
230: * @param position the position of the item.
231: * @since JDK1.1
232: */
233: public synchronized void remove(int position) {
234: pItems.removeElementAt(position);
235: ChoicePeer peer = (ChoicePeer) this .peer;
236: if (peer != null) {
237: peer.remove(position);
238: }
239: /* Adjust selectedIndex if selected item was removed. */
240: if (pItems.size() == 0) {
241: selectedIndex = -1;
242: } else if (selectedIndex == position) {
243: select(0);
244: } else if (selectedIndex > position) {
245: select(selectedIndex - 1);
246: }
247: }
248:
249: /**
250: * Removes all items from the choice menu.
251: * @see java.awt.Choice#remove
252: * @since JDK1.1
253: */
254: public synchronized void removeAll() {
255: int nitems = getItemCount();
256: for (int i = 0; i < nitems; i++) {
257: remove(0);
258: }
259: }
260:
261: /**
262: * Gets a representation of the current choice as a string.
263: * @return a string representation of the currently
264: * selected item in this choice menu.
265: * @see java.awt.Choice#getSelectedIndex
266: * @since JDK1.0
267: */
268: public synchronized String getSelectedItem() {
269: return (selectedIndex >= 0) ? getItem(selectedIndex) : null;
270: }
271:
272: /**
273: * Returns an array (length 1) containing the currently selected
274: * item. If this choice has no items, returns null.
275: * @see ItemSelectable
276: */
277: public synchronized Object[] getSelectedObjects() {
278: if (selectedIndex >= 0) {
279: Object[] items = new Object[1];
280: items[0] = getItem(selectedIndex);
281: return items;
282: }
283: return null;
284: }
285:
286: /**
287: * Returns the index of the currently selected item.
288: * @see #getSelectedItem
289: */
290: public int getSelectedIndex() {
291: return selectedIndex;
292: }
293:
294: /**
295: * Sets the selected item in this <code>Choice</code> menu to be the
296: * item at the specified position.
297: * @param pos the positon of the selected item.
298: * @exception IllegalArgumentException if the specified
299: * position is invalid.
300: * @see java.awt.Choice#getSelectedItem
301: * @see java.awt.Choice#getSelectedIndex
302: * @since JDK1.0
303: */
304: public void select(int pos) {
305: if (pos >= pItems.size() || pos < 0) {
306: throw new IllegalArgumentException(
307: "illegal Choice item position: " + pos);
308: }
309: if (pItems.size() > 0) {
310: selectedIndex = pos;
311: ChoicePeer peer = (ChoicePeer) this .peer;
312: if (peer != null) {
313: peer.select(pos);
314: }
315: }
316: }
317:
318: /**
319: * Sets the selected item in this <code>Choice</code> menu
320: * to be the item whose name is equal to the specified string.
321: * If more than one item matches (is equal to) the specified string,
322: * the one with the smallest index is selected.
323: * @param str the specified string
324: * @see java.awt.Choice#getSelectedItem
325: * @see java.awt.Choice#getSelectedIndex
326: * @since JDK1.0
327: */
328: public synchronized void select(String str) {
329: int index = pItems.indexOf(str);
330: if (index >= 0) {
331: select(index);
332: }
333: }
334:
335: /**
336: * Adds the specified item listener to receive item events from
337: * this <code>Choice</code> menu.
338: * @param l the item listener.
339: * @see java.awt.event.ItemEvent
340: * @see java.awt.event.ItemListener
341: * @see java.awt.Choice#removeItemListener
342: * @since JDK1.1
343: */
344: public synchronized void addItemListener(ItemListener l) {
345: itemListener = AWTEventMulticaster.add(itemListener, l);
346: newEventsOnly = true;
347: }
348:
349: /**
350: * Removes the specified item listener so that it no longer receives
351: * item events from this <code>Choice</code> menu.
352: * @param l the item listener.
353: * @see java.awt.event.ItemEvent
354: * @see java.awt.event.ItemListener
355: * @see java.awt.Choice#addItemListener
356: * @since JDK1.1
357: */
358: public synchronized void removeItemListener(ItemListener l) {
359: itemListener = AWTEventMulticaster.remove(itemListener, l);
360: }
361:
362: /**
363: * Returns an array of all the item listeners
364: * registered on this choice.
365: *
366: * @return all of this choice's <code>ItemListener</code>s
367: * or an empty array if no item
368: * listeners are currently registered
369: *
370: * @see #addItemListener
371: * @see #removeItemListener
372: * @see java.awt.event.ItemEvent
373: * @see java.awt.event.ItemListener
374: * @since 1.4
375: */
376: public synchronized ItemListener[] getItemListeners() {
377: return (ItemListener[]) AWTEventMulticaster.getListeners(
378: (EventListener) itemListener, ItemListener.class);
379: }
380:
381: // NOTE: remove when filtering is done at lower level
382: boolean eventEnabled(AWTEvent e) {
383: if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
384: if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0
385: || itemListener != null) {
386: return true;
387: }
388: return false;
389: }
390: return super .eventEnabled(e);
391: }
392:
393: /**
394: * Processes events on this choice. If the event is an
395: * instance of <code>ItemEvent</code>, it invokes the
396: * <code>processItemEvent</code> method. Otherwise, it calls its
397: * superclass's <code>processEvent</code> method.
398: * @param e the event.
399: * @see java.awt.event.ItemEvent
400: * @see java.awt.Choice#processItemEvent
401: * @since JDK1.1
402: */
403: protected void processEvent(AWTEvent e) {
404: if (e instanceof ItemEvent) {
405: processItemEvent((ItemEvent) e);
406: return;
407: }
408: super .processEvent(e);
409: }
410:
411: /**
412: * Processes item events occurring on this <code>Choice</code>
413: * menu by dispatching them to any registered
414: * <code>ItemListener</code> objects.
415: * <p>
416: * This method is not called unless item events are
417: * enabled for this component. Item events are enabled
418: * when one of the following occurs:
419: * <p><ul>
420: * <li>An <code>ItemListener</code> object is registered
421: * via <code>addItemListener</code>.
422: * <li>Item events are enabled via <code>enableEvents</code>.
423: * </ul>
424: * @param e the item event.
425: * @see java.awt.event.ItemEvent
426: * @see java.awt.event.ItemListener
427: * @see java.awt.Choice#addItemListener
428: * @see java.awt.Component#enableEvents
429: * @since JDK1.1
430: */
431: protected void processItemEvent(ItemEvent e) {
432: if (itemListener != null) {
433: itemListener.itemStateChanged(e);
434: }
435: }
436:
437: /**
438: * Returns the parameter string representing the state of this
439: * choice menu. This string is useful for debugging.
440: * @return the parameter string of this <code>Choice</code> menu.
441: * @since JDK1.0
442: */
443: protected String paramString() {
444: return super .paramString() + ",current=" + getSelectedItem();
445: }
446:
447: /* Serialization support.
448: */
449:
450: private int choiceSerializedDataVersion = 1;
451:
452: private void writeObject(ObjectOutputStream s)
453: throws java.io.IOException {
454: s.defaultWriteObject();
455: AWTEventMulticaster.save(s, itemListenerK, itemListener);
456: s.writeObject(null);
457: }
458:
459: private void readObject(ObjectInputStream s)
460: throws ClassNotFoundException, IOException {
461: s.defaultReadObject();
462: Object keyOrNull;
463: while (null != (keyOrNull = s.readObject())) {
464: String key = ((String) keyOrNull).intern();
465: if (itemListenerK == key)
466: addItemListener((ItemListener) (s.readObject()));
467: else
468: // skip value for unrecognized key
469: s.readObject();
470: }
471: }
472: }
|