1 /*
2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package java.awt;
26 
27 import java.util.*;
28 import java.awt.peer.ChoicePeer;
29 import java.awt.event.*;
30 import java.util.EventListener;
31 import java.io.ObjectOutputStream;
32 import java.io.ObjectInputStream;
33 import java.io.IOException;
34 
35 import javax.accessibility.*;
36 
37 
38 /**
39  * The {@code Choice} class presents a pop-up menu of choices.
40  * The current choice is displayed as the title of the menu.
41  * <p>
42  * The following code example produces a pop-up menu:
43  *
44  * <hr><blockquote><pre>
45  * Choice ColorChooser = new Choice();
46  * ColorChooser.add("Green");
47  * ColorChooser.add("Red");
48  * ColorChooser.add("Blue");
49  * </pre></blockquote><hr>
50  * <p>
51  * After this choice menu has been added to a panel,
52  * it appears as follows in its normal state:
53  * <p>
54  * <img src="doc-files/Choice-1.gif" alt="The following text describes the
55  * graphic" style="margin: 7px 10px;">
56  * <p>
57  * In the picture, {@code "Green"} is the current choice.
58  * Pushing the mouse button down on the object causes a menu to
59  * appear with the current choice highlighted.
60  * <p>
61  * Some native platforms do not support arbitrary resizing of
62  * {@code Choice} components and the behavior of
63  * {@code setSize()/getSize()} is bound by
64  * such limitations.
65  * Native GUI {@code Choice} components' size are often bound by such
66  * attributes as font size and length of items contained within
67  * the {@code Choice}.
68  *
69  * @author      Sami Shaio
70  * @author      Arthur van Hoff
71  * @since       1.0
72  */
73 public class Choice extends Component implements ItemSelectable, Accessible {
74     /**
75      * The items for the {@code Choice}.
76      * This can be a {@code null} value.
77      * @serial
78      * @see #add(String)
79      * @see #addItem(String)
80      * @see #getItem(int)
81      * @see #getItemCount()
82      * @see #insert(String, int)
83      * @see #remove(String)
84      */
85     Vector<String> pItems;
86 
87     /**
88      * The index of the current choice for this {@code Choice}
89      * or -1 if nothing is selected.
90      * @serial
91      * @see #getSelectedItem()
92      * @see #select(int)
93      */
94     int selectedIndex = -1;
95 
96     transient ItemListener itemListener;
97 
98     private static final String base = "choice";
99     private static int nameCounter = 0;
100 
101     /*
102      * JDK 1.1 serialVersionUID
103      */
104     private static final long serialVersionUID = -4075310674757313071L;
105 
106     static {
107         /* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries()108         Toolkit.loadLibraries();
109         /* initialize JNI field and method ids */
110         if (!GraphicsEnvironment.isHeadless()) {
initIDs()111             initIDs();
112         }
113     }
114 
115     /**
116      * Creates a new choice menu. The menu initially has no items in it.
117      * <p>
118      * By default, the first item added to the choice menu becomes the
119      * selected item, until a different selection is made by the user
120      * by calling one of the {@code select} methods.
121      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
122      * returns true
123      * @see       java.awt.GraphicsEnvironment#isHeadless
124      * @see       #select(int)
125      * @see       #select(java.lang.String)
126      */
Choice()127     public Choice() throws HeadlessException {
128         GraphicsEnvironment.checkHeadless();
129         pItems = new Vector<>();
130     }
131 
132     /**
133      * Constructs a name for this component.  Called by
134      * {@code getName} when the name is {@code null}.
135      */
constructComponentName()136     String constructComponentName() {
137         synchronized (Choice.class) {
138             return base + nameCounter++;
139         }
140     }
141 
142     /**
143      * Creates the {@code Choice}'s peer.  This peer allows us
144      * to change the look
145      * of the {@code Choice} without changing its functionality.
146      * @see     java.awt.Component#getToolkit()
147      */
addNotify()148     public void addNotify() {
149         synchronized (getTreeLock()) {
150             if (peer == null)
151                 peer = getComponentFactory().createChoice(this);
152             super.addNotify();
153         }
154     }
155 
156     /**
157      * Returns the number of items in this {@code Choice} menu.
158      *
159      * @return the number of items in this {@code Choice} menu
160      * @see     #getItem
161      * @since   1.1
162      */
getItemCount()163     public int getItemCount() {
164         return countItems();
165     }
166 
167     /**
168      * Returns the number of items in this {@code Choice} menu.
169      *
170      * @return the number of items in this {@code Choice} menu
171      * @deprecated As of JDK version 1.1,
172      * replaced by {@code getItemCount()}.
173      */
174     @Deprecated
countItems()175     public int countItems() {
176         return pItems.size();
177     }
178 
179     /**
180      * Gets the string at the specified index in this
181      * {@code Choice} menu.
182      *
183      * @param  index the index at which to begin
184      * @return the item at the specified index
185      * @see    #getItemCount
186      */
getItem(int index)187     public String getItem(int index) {
188         return getItemImpl(index);
189     }
190 
191     /*
192      * This is called by the native code, so client code can't
193      * be called on the toolkit thread.
194      */
getItemImpl(int index)195     final String getItemImpl(int index) {
196         return pItems.elementAt(index);
197     }
198 
199     /**
200      * Adds an item to this {@code Choice} menu.
201      * @param      item    the item to be added
202      * @exception  NullPointerException   if the item's value is
203      *                  {@code null}
204      * @since      1.1
205      */
add(String item)206     public void add(String item) {
207         addItem(item);
208     }
209 
210     /**
211      * Obsolete as of Java 2 platform v1.1.  Please use the
212      * {@code add} method instead.
213      * <p>
214      * Adds an item to this {@code Choice} menu.
215      * @param item the item to be added
216      * @exception NullPointerException if the item's value is equal to
217      *          {@code null}
218      */
addItem(String item)219     public void addItem(String item) {
220         synchronized (this) {
221             insertNoInvalidate(item, pItems.size());
222         }
223 
224         // This could change the preferred size of the Component.
225         invalidateIfValid();
226     }
227 
228     /**
229      * Inserts an item to this {@code Choice},
230      * but does not invalidate the {@code Choice}.
231      * Client methods must provide their own synchronization before
232      * invoking this method.
233      * @param item the item to be added
234      * @param index the new item position
235      * @exception NullPointerException if the item's value is equal to
236      *          {@code null}
237      */
insertNoInvalidate(String item, int index)238     private void insertNoInvalidate(String item, int index) {
239         if (item == null) {
240             throw new
241                 NullPointerException("cannot add null item to Choice");
242         }
243         pItems.insertElementAt(item, index);
244         ChoicePeer peer = (ChoicePeer)this.peer;
245         if (peer != null) {
246             peer.add(item, index);
247         }
248         // no selection or selection shifted up
249         if (selectedIndex < 0 || selectedIndex >= index) {
250             select(0);
251         }
252     }
253 
254 
255     /**
256      * Inserts the item into this choice at the specified position.
257      * Existing items at an index greater than or equal to
258      * {@code index} are shifted up by one to accommodate
259      * the new item.  If {@code index} is greater than or
260      * equal to the number of items in this choice,
261      * {@code item} is added to the end of this choice.
262      * <p>
263      * If the item is the first one being added to the choice,
264      * then the item becomes selected.  Otherwise, if the
265      * selected item was one of the items shifted, the first
266      * item in the choice becomes the selected item.  If the
267      * selected item was no among those shifted, it remains
268      * the selected item.
269      * @param item the non-{@code null} item to be inserted
270      * @param index the position at which the item should be inserted
271      * @exception IllegalArgumentException if index is less than 0
272      */
insert(String item, int index)273     public void insert(String item, int index) {
274         synchronized (this) {
275             if (index < 0) {
276                 throw new IllegalArgumentException("index less than zero.");
277             }
278             /* if the index greater than item count, add item to the end */
279             index = Math.min(index, pItems.size());
280 
281             insertNoInvalidate(item, index);
282         }
283 
284         // This could change the preferred size of the Component.
285         invalidateIfValid();
286     }
287 
288     /**
289      * Removes the first occurrence of {@code item}
290      * from the {@code Choice} menu.  If the item
291      * being removed is the currently selected item,
292      * then the first item in the choice becomes the
293      * selected item.  Otherwise, the currently selected
294      * item remains selected (and the selected index is
295      * updated accordingly).
296      * @param      item  the item to remove from this {@code Choice} menu
297      * @exception  IllegalArgumentException  if the item doesn't
298      *                     exist in the choice menu
299      * @since      1.1
300      */
remove(String item)301     public void remove(String item) {
302         synchronized (this) {
303             int index = pItems.indexOf(item);
304             if (index < 0) {
305                 throw new IllegalArgumentException("item " + item +
306                                                    " not found in choice");
307             } else {
308                 removeNoInvalidate(index);
309             }
310         }
311 
312         // This could change the preferred size of the Component.
313         invalidateIfValid();
314     }
315 
316     /**
317      * Removes an item from the choice menu
318      * at the specified position.  If the item
319      * being removed is the currently selected item,
320      * then the first item in the choice becomes the
321      * selected item.  Otherwise, the currently selected
322      * item remains selected (and the selected index is
323      * updated accordingly).
324      * @param      position the position of the item
325      * @throws IndexOutOfBoundsException if the specified
326      *          position is out of bounds
327      * @since      1.1
328      */
remove(int position)329     public void remove(int position) {
330         synchronized (this) {
331             removeNoInvalidate(position);
332         }
333 
334         // This could change the preferred size of the Component.
335         invalidateIfValid();
336     }
337 
338     /**
339      * Removes an item from the {@code Choice} at the
340      * specified position, but does not invalidate the {@code Choice}.
341      * Client methods must provide their
342      * own synchronization before invoking this method.
343      * @param      position   the position of the item
344      */
removeNoInvalidate(int position)345     private void removeNoInvalidate(int position) {
346         pItems.removeElementAt(position);
347         ChoicePeer peer = (ChoicePeer)this.peer;
348         if (peer != null) {
349             peer.remove(position);
350         }
351         /* Adjust selectedIndex if selected item was removed. */
352         if (pItems.size() == 0) {
353             selectedIndex = -1;
354         } else if (selectedIndex == position) {
355             select(0);
356         } else if (selectedIndex > position) {
357             select(selectedIndex-1);
358         }
359     }
360 
361 
362     /**
363      * Removes all items from the choice menu.
364      * @see       #remove
365      * @since     1.1
366      */
removeAll()367     public void removeAll() {
368         synchronized (this) {
369             if (peer != null) {
370                 ((ChoicePeer)peer).removeAll();
371             }
372             pItems.removeAllElements();
373             selectedIndex = -1;
374         }
375 
376         // This could change the preferred size of the Component.
377         invalidateIfValid();
378     }
379 
380     /**
381      * Gets a representation of the current choice as a string.
382      * @return    a string representation of the currently
383      *                     selected item in this choice menu
384      * @see       #getSelectedIndex
385      */
getSelectedItem()386     public synchronized String getSelectedItem() {
387         return (selectedIndex >= 0) ? getItem(selectedIndex) : null;
388     }
389 
390     /**
391      * Returns an array (length 1) containing the currently selected
392      * item.  If this choice has no items, returns {@code null}.
393      * @see ItemSelectable
394      */
getSelectedObjects()395     public synchronized Object[] getSelectedObjects() {
396         if (selectedIndex >= 0) {
397             Object[] items = new Object[1];
398             items[0] = getItem(selectedIndex);
399             return items;
400         }
401         return null;
402     }
403 
404     /**
405      * Returns the index of the currently selected item.
406      * If nothing is selected, returns -1.
407      *
408      * @return the index of the currently selected item, or -1 if nothing
409      *  is currently selected
410      * @see #getSelectedItem
411      */
getSelectedIndex()412     public int getSelectedIndex() {
413         return selectedIndex;
414     }
415 
416     /**
417      * Sets the selected item in this {@code Choice} menu to be the
418      * item at the specified position.
419      *
420      * <p>Note that this method should be primarily used to
421      * initially select an item in this component.
422      * Programmatically calling this method will <i>not</i> trigger
423      * an {@code ItemEvent}.  The only way to trigger an
424      * {@code ItemEvent} is by user interaction.
425      *
426      * @param      pos      the position of the selected item
427      * @exception  IllegalArgumentException if the specified
428      *                            position is greater than the
429      *                            number of items or less than zero
430      * @see        #getSelectedItem
431      * @see        #getSelectedIndex
432      */
select(int pos)433     public synchronized void select(int pos) {
434         if ((pos >= pItems.size()) || (pos < 0)) {
435             throw new IllegalArgumentException("illegal Choice item position: " + pos);
436         }
437         if (pItems.size() > 0) {
438             selectedIndex = pos;
439             ChoicePeer peer = (ChoicePeer)this.peer;
440             if (peer != null) {
441                 peer.select(pos);
442             }
443         }
444     }
445 
446     /**
447      * Sets the selected item in this {@code Choice} menu
448      * to be the item whose name is equal to the specified string.
449      * If more than one item matches (is equal to) the specified string,
450      * the one with the smallest index is selected.
451      *
452      * <p>Note that this method should be primarily used to
453      * initially select an item in this component.
454      * Programmatically calling this method will <i>not</i> trigger
455      * an {@code ItemEvent}.  The only way to trigger an
456      * {@code ItemEvent} is by user interaction.
457      *
458      * @param       str     the specified string
459      * @see         #getSelectedItem
460      * @see         #getSelectedIndex
461      */
select(String str)462     public synchronized void select(String str) {
463         int index = pItems.indexOf(str);
464         if (index >= 0) {
465             select(index);
466         }
467     }
468 
469     /**
470      * Adds the specified item listener to receive item events from
471      * this {@code Choice} menu.  Item events are sent in response
472      * to user input, but not in response to calls to {@code select}.
473      * If l is {@code null}, no exception is thrown and no action
474      * is performed.
475      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
476      * >AWT Threading Issues</a> for details on AWT's threading model.
477      * @param         l    the item listener
478      * @see           #removeItemListener
479      * @see           #getItemListeners
480      * @see           #select
481      * @see           java.awt.event.ItemEvent
482      * @see           java.awt.event.ItemListener
483      * @since         1.1
484      */
addItemListener(ItemListener l)485     public synchronized void addItemListener(ItemListener l) {
486         if (l == null) {
487            return;
488         }
489         itemListener = AWTEventMulticaster.add(itemListener, l);
490         newEventsOnly = true;
491     }
492 
493     /**
494      * Removes the specified item listener so that it no longer receives
495      * item events from this {@code Choice} menu.
496      * If l is {@code null}, no exception is thrown and no
497      * action is performed.
498      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
499      * >AWT Threading Issues</a> for details on AWT's threading model.
500      * @param         l    the item listener
501      * @see           #addItemListener
502      * @see           #getItemListeners
503      * @see           java.awt.event.ItemEvent
504      * @see           java.awt.event.ItemListener
505      * @since         1.1
506      */
removeItemListener(ItemListener l)507     public synchronized void removeItemListener(ItemListener l) {
508         if (l == null) {
509             return;
510         }
511         itemListener = AWTEventMulticaster.remove(itemListener, l);
512     }
513 
514     /**
515      * Returns an array of all the item listeners
516      * registered on this choice.
517      *
518      * @return all of this choice's {@code ItemListener}s
519      *         or an empty array if no item
520      *         listeners are currently registered
521      *
522      * @see           #addItemListener
523      * @see           #removeItemListener
524      * @see           java.awt.event.ItemEvent
525      * @see           java.awt.event.ItemListener
526      * @since 1.4
527      */
getItemListeners()528     public synchronized ItemListener[] getItemListeners() {
529         return getListeners(ItemListener.class);
530     }
531 
532     /**
533      * Returns an array of all the objects currently registered
534      * as <code><em>Foo</em>Listener</code>s
535      * upon this {@code Choice}.
536      * <code><em>Foo</em>Listener</code>s are registered using the
537      * <code>add<em>Foo</em>Listener</code> method.
538      *
539      * <p>
540      * You can specify the {@code listenerType} argument
541      * with a class literal, such as
542      * <code><em>Foo</em>Listener.class</code>.
543      * For example, you can query a
544      * {@code Choice c}
545      * for its item listeners with the following code:
546      *
547      * <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>
548      *
549      * If no such listeners exist, this method returns an empty array.
550      *
551      * @param listenerType the type of listeners requested; this parameter
552      *          should specify an interface that descends from
553      *          {@code java.util.EventListener}
554      * @return an array of all objects registered as
555      *          <code><em>Foo</em>Listener</code>s on this choice,
556      *          or an empty array if no such
557      *          listeners have been added
558      * @exception ClassCastException if {@code listenerType}
559      *          doesn't specify a class or interface that implements
560      *          {@code java.util.EventListener}
561      *
562      * @see #getItemListeners
563      * @since 1.3
564      */
getListeners(Class<T> listenerType)565     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
566         EventListener l = null;
567         if  (listenerType == ItemListener.class) {
568             l = itemListener;
569         } else {
570             return super.getListeners(listenerType);
571         }
572         return AWTEventMulticaster.getListeners(l, listenerType);
573     }
574 
575     // REMIND: remove when filtering is done at lower level
eventEnabled(AWTEvent e)576     boolean eventEnabled(AWTEvent e) {
577         if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
578             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
579                 itemListener != null) {
580                 return true;
581             }
582             return false;
583         }
584         return super.eventEnabled(e);
585     }
586 
587     /**
588      * Processes events on this choice. If the event is an
589      * instance of {@code ItemEvent}, it invokes the
590      * {@code processItemEvent} method. Otherwise, it calls its
591      * superclass's {@code processEvent} method.
592      * <p>Note that if the event parameter is {@code null}
593      * the behavior is unspecified and may result in an
594      * exception.
595      *
596      * @param      e the event
597      * @see        java.awt.event.ItemEvent
598      * @see        #processItemEvent
599      * @since      1.1
600      */
processEvent(AWTEvent e)601     protected void processEvent(AWTEvent e) {
602         if (e instanceof ItemEvent) {
603             processItemEvent((ItemEvent)e);
604             return;
605         }
606         super.processEvent(e);
607     }
608 
609     /**
610      * Processes item events occurring on this {@code Choice}
611      * menu by dispatching them to any registered
612      * {@code ItemListener} objects.
613      * <p>
614      * This method is not called unless item events are
615      * enabled for this component. Item events are enabled
616      * when one of the following occurs:
617      * <ul>
618      * <li>An {@code ItemListener} object is registered
619      * via {@code addItemListener}.
620      * <li>Item events are enabled via {@code enableEvents}.
621      * </ul>
622      * <p>Note that if the event parameter is {@code null}
623      * the behavior is unspecified and may result in an
624      * exception.
625      *
626      * @param       e the item event
627      * @see         java.awt.event.ItemEvent
628      * @see         java.awt.event.ItemListener
629      * @see         #addItemListener(ItemListener)
630      * @see         java.awt.Component#enableEvents
631      * @since       1.1
632      */
processItemEvent(ItemEvent e)633     protected void processItemEvent(ItemEvent e) {
634         ItemListener listener = itemListener;
635         if (listener != null) {
636             listener.itemStateChanged(e);
637         }
638     }
639 
640     /**
641      * Returns a string representing the state of this {@code Choice}
642      * menu. This method is intended to be used only for debugging purposes,
643      * and the content and format of the returned string may vary between
644      * implementations. The returned string may be empty but may not be
645      * {@code null}.
646      *
647      * @return    the parameter string of this {@code Choice} menu
648      */
paramString()649     protected String paramString() {
650         return super.paramString() + ",current=" + getSelectedItem();
651     }
652 
653 
654     /* Serialization support.
655      */
656 
657     /*
658      * Choice Serial Data Version.
659      * @serial
660      */
661     private int choiceSerializedDataVersion = 1;
662 
663     /**
664      * Writes default serializable fields to stream.  Writes
665      * a list of serializable {@code ItemListeners}
666      * as optional data. The non-serializable
667      * {@code ItemListeners} are detected and
668      * no attempt is made to serialize them.
669      *
670      * @param s the {@code ObjectOutputStream} to write
671      * @serialData {@code null} terminated sequence of 0
672      *   or more pairs; the pair consists of a {@code String}
673      *   and an {@code Object}; the {@code String} indicates
674      *   the type of object and is one of the following:
675      *   {@code itemListenerK} indicating an
676      *     {@code ItemListener} object
677      *
678      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
679      * @see java.awt.Component#itemListenerK
680      * @see #readObject(ObjectInputStream)
681      */
writeObject(ObjectOutputStream s)682     private void writeObject(ObjectOutputStream s)
683       throws java.io.IOException
684     {
685       s.defaultWriteObject();
686 
687       AWTEventMulticaster.save(s, itemListenerK, itemListener);
688       s.writeObject(null);
689     }
690 
691     /**
692      * Reads the {@code ObjectInputStream} and if it
693      * isn't {@code null} adds a listener to receive
694      * item events fired by the {@code Choice} item.
695      * Unrecognized keys or values will be ignored.
696      *
697      * @param s the {@code ObjectInputStream} to read
698      * @exception HeadlessException if
699      *   {@code GraphicsEnvironment.isHeadless} returns
700      *   {@code true}
701      * @serial
702      * @see #removeItemListener(ItemListener)
703      * @see #addItemListener(ItemListener)
704      * @see java.awt.GraphicsEnvironment#isHeadless
705      * @see #writeObject(ObjectOutputStream)
706      */
readObject(ObjectInputStream s)707     private void readObject(ObjectInputStream s)
708       throws ClassNotFoundException, IOException, HeadlessException
709     {
710       GraphicsEnvironment.checkHeadless();
711       s.defaultReadObject();
712 
713       Object keyOrNull;
714       while(null != (keyOrNull = s.readObject())) {
715         String key = ((String)keyOrNull).intern();
716 
717         if (itemListenerK == key)
718           addItemListener((ItemListener)(s.readObject()));
719 
720         else // skip value for unrecognized key
721           s.readObject();
722       }
723     }
724 
725     /**
726      * Initialize JNI field and method IDs
727      */
initIDs()728     private static native void initIDs();
729 
730 /////////////////
731 // Accessibility support
732 ////////////////
733 
734 
735     /**
736      * Gets the {@code AccessibleContext} associated with this
737      * {@code Choice}. For {@code Choice} components,
738      * the {@code AccessibleContext} takes the form of an
739      * {@code AccessibleAWTChoice}. A new {@code AccessibleAWTChoice}
740      * instance is created if necessary.
741      *
742      * @return an {@code AccessibleAWTChoice} that serves as the
743      *         {@code AccessibleContext} of this {@code Choice}
744      * @since 1.3
745      */
getAccessibleContext()746     public AccessibleContext getAccessibleContext() {
747         if (accessibleContext == null) {
748             accessibleContext = new AccessibleAWTChoice();
749         }
750         return accessibleContext;
751     }
752 
753     /**
754      * This class implements accessibility support for the
755      * {@code Choice} class.  It provides an implementation of the
756      * Java Accessibility API appropriate to choice user-interface elements.
757      * @since 1.3
758      */
759     protected class AccessibleAWTChoice extends AccessibleAWTComponent
760         implements AccessibleAction
761     {
762         /*
763          * JDK 1.3 serialVersionUID
764          */
765         private static final long serialVersionUID = 7175603582428509322L;
766 
767         /**
768          * Constructor for {@code AccessibleAWTChoice}
769          */
AccessibleAWTChoice()770         public AccessibleAWTChoice() {
771             super();
772         }
773 
774         /**
775          * Get the AccessibleAction associated with this object.  In the
776          * implementation of the Java Accessibility API for this class,
777          * return this object, which is responsible for implementing the
778          * AccessibleAction interface on behalf of itself.
779          *
780          * @return this object
781          * @see AccessibleAction
782          */
getAccessibleAction()783         public AccessibleAction getAccessibleAction() {
784             return this;
785         }
786 
787         /**
788          * Get the role of this object.
789          *
790          * @return an instance of AccessibleRole describing the role of the
791          * object
792          * @see AccessibleRole
793          */
getAccessibleRole()794         public AccessibleRole getAccessibleRole() {
795             return AccessibleRole.COMBO_BOX;
796         }
797 
798         /**
799          * Returns the number of accessible actions available in this object
800          * If there are more than one, the first one is considered the "default"
801          * action of the object.
802          *
803          * @return the zero-based number of Actions in this object
804          */
getAccessibleActionCount()805         public int getAccessibleActionCount() {
806             return 0;  //  To be fully implemented in a future release
807         }
808 
809         /**
810          * Returns a description of the specified action of the object.
811          *
812          * @param i zero-based index of the actions
813          * @return a String description of the action
814          * @see #getAccessibleActionCount
815          */
getAccessibleActionDescription(int i)816         public String getAccessibleActionDescription(int i) {
817             return null;  //  To be fully implemented in a future release
818         }
819 
820         /**
821          * Perform the specified Action on the object
822          *
823          * @param i zero-based index of actions
824          * @return true if the action was performed; otherwise false.
825          * @see #getAccessibleActionCount
826          */
doAccessibleAction(int i)827         public boolean doAccessibleAction(int i) {
828             return false;  //  To be fully implemented in a future release
829         }
830 
831     } // inner class AccessibleAWTChoice
832 
833 }
834