1 /*
2  * Copyright (c) 1995, 2013, 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.Vector;
28 import java.util.Locale;
29 import java.util.EventListener;
30 import java.awt.peer.ListPeer;
31 import java.awt.event.*;
32 import java.io.ObjectOutputStream;
33 import java.io.ObjectInputStream;
34 import java.io.IOException;
35 import javax.accessibility.*;
36 
37 
38 /**
39  * The <code>List</code> component presents the user with a
40  * scrolling list of text items. The list can be set up so that
41  * the user can choose either one item or multiple items.
42  * <p>
43  * For example, the code&nbsp;.&nbsp;.&nbsp;.
44  *
45  * <hr><blockquote><pre>
46  * List lst = new List(4, false);
47  * lst.add("Mercury");
48  * lst.add("Venus");
49  * lst.add("Earth");
50  * lst.add("JavaSoft");
51  * lst.add("Mars");
52  * lst.add("Jupiter");
53  * lst.add("Saturn");
54  * lst.add("Uranus");
55  * lst.add("Neptune");
56  * lst.add("Pluto");
57  * cnt.add(lst);
58  * </pre></blockquote><hr>
59  * <p>
60  * where <code>cnt</code> is a container, produces the following
61  * scrolling list:
62  * <p>
63  * <img src="doc-files/List-1.gif"
64  * alt="Shows a list containing: Venus, Earth, JavaSoft, and Mars. Javasoft is selected." style="float:center; margin: 7px 10px;">
65  * <p>
66  * If the List allows multiple selections, then clicking on
67  * an item that is already selected deselects it. In the preceding
68  * example, only one item from the scrolling list can be selected
69  * at a time, since the second argument when creating the new scrolling
70  * list is <code>false</code>. If the List does not allow multiple
71  * selections, selecting an item causes any other selected item
72  * to be deselected.
73  * <p>
74  * Note that the list in the example shown was created with four visible
75  * rows.  Once the list has been created, the number of visible rows
76  * cannot be changed.  A default <code>List</code> is created with
77  * four rows, so that <code>lst = new List()</code> is equivalent to
78  * <code>list = new List(4, false)</code>.
79  * <p>
80  * Beginning with Java&nbsp;1.1, the Abstract Window Toolkit
81  * sends the <code>List</code> object all mouse, keyboard, and focus events
82  * that occur over it. (The old AWT event model is being maintained
83  * only for backwards compatibility, and its use is discouraged.)
84  * <p>
85  * When an item is selected or deselected by the user, AWT sends an instance
86  * of <code>ItemEvent</code> to the list.
87  * When the user double-clicks on an item in a scrolling list,
88  * AWT sends an instance of <code>ActionEvent</code> to the
89  * list following the item event. AWT also generates an action event
90  * when the user presses the return key while an item in the
91  * list is selected.
92  * <p>
93  * If an application wants to perform some action based on an item
94  * in this list being selected or activated by the user, it should implement
95  * <code>ItemListener</code> or <code>ActionListener</code>
96  * as appropriate and register the new listener to receive
97  * events from this list.
98  * <p>
99  * For multiple-selection scrolling lists, it is considered a better
100  * user interface to use an external gesture (such as clicking on a
101  * button) to trigger the action.
102  * @author      Sami Shaio
103  * @see         java.awt.event.ItemEvent
104  * @see         java.awt.event.ItemListener
105  * @see         java.awt.event.ActionEvent
106  * @see         java.awt.event.ActionListener
107  * @since       JDK1.0
108  */
109 public class List extends Component implements ItemSelectable, Accessible {
110     /**
111      * A vector created to contain items which will become
112      * part of the List Component.
113      *
114      * @serial
115      * @see #addItem(String)
116      * @see #getItem(int)
117      */
118     Vector<String>      items = new Vector<>();
119 
120     /**
121      * This field will represent the number of visible rows in the
122      * <code>List</code> Component.  It is specified only once, and
123      * that is when the list component is actually
124      * created.  It will never change.
125      *
126      * @serial
127      * @see #getRows()
128      */
129     int         rows = 0;
130 
131     /**
132      * <code>multipleMode</code> is a variable that will
133      * be set to <code>true</code> if a list component is to be set to
134      * multiple selection mode, that is where the user can
135      * select more than one item in a list at one time.
136      * <code>multipleMode</code> will be set to false if the
137      * list component is set to single selection, that is where
138      * the user can only select one item on the list at any
139      * one time.
140      *
141      * @serial
142      * @see #isMultipleMode()
143      * @see #setMultipleMode(boolean)
144      */
145     boolean     multipleMode = false;
146 
147     /**
148      * <code>selected</code> is an array that will contain
149      * the indices of items that have been selected.
150      *
151      * @serial
152      * @see #getSelectedIndexes()
153      * @see #getSelectedIndex()
154      */
155     int         selected[] = new int[0];
156 
157     /**
158      * This variable contains the value that will be used
159      * when trying to make a particular list item visible.
160      *
161      * @serial
162      * @see #makeVisible(int)
163      */
164     int         visibleIndex = -1;
165 
166     transient ActionListener actionListener;
167     transient ItemListener itemListener;
168 
169     private static final String base = "list";
170     private static int nameCounter = 0;
171 
172     /*
173      * JDK 1.1 serialVersionUID
174      */
175      private static final long serialVersionUID = -3304312411574666869L;
176 
177     /**
178      * Creates a new scrolling list.
179      * By default, there are four visible lines and multiple selections are
180      * not allowed.  Note that this is a convenience method for
181      * <code>List(0, false)</code>.  Also note that the number of visible
182      * lines in the list cannot be changed after it has been created.
183      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
184      * returns true.
185      * @see java.awt.GraphicsEnvironment#isHeadless
186      */
List()187     public List() throws HeadlessException {
188         this(0, false);
189     }
190 
191     /**
192      * Creates a new scrolling list initialized with the specified
193      * number of visible lines. By default, multiple selections are
194      * not allowed.  Note that this is a convenience method for
195      * <code>List(rows, false)</code>.  Also note that the number
196      * of visible rows in the list cannot be changed after it has
197      * been created.
198      * @param       rows the number of items to show.
199      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
200      * returns true.
201      * @see java.awt.GraphicsEnvironment#isHeadless
202      * @since       JDK1.1
203      */
List(int rows)204     public List(int rows) throws HeadlessException {
205         this(rows, false);
206     }
207 
208     /**
209      * The default number of visible rows is 4.  A list with
210      * zero rows is unusable and unsightly.
211      */
212     final static int    DEFAULT_VISIBLE_ROWS = 4;
213 
214     /**
215      * Creates a new scrolling list initialized to display the specified
216      * number of rows. Note that if zero rows are specified, then
217      * the list will be created with a default of four rows.
218      * Also note that the number of visible rows in the list cannot
219      * be changed after it has been created.
220      * If the value of <code>multipleMode</code> is
221      * <code>true</code>, then the user can select multiple items from
222      * the list. If it is <code>false</code>, only one item at a time
223      * can be selected.
224      * @param       rows   the number of items to show.
225      * @param       multipleMode   if <code>true</code>,
226      *                     then multiple selections are allowed;
227      *                     otherwise, only one item can be selected at a time.
228      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
229      * returns true.
230      * @see java.awt.GraphicsEnvironment#isHeadless
231      */
List(int rows, boolean multipleMode)232     public List(int rows, boolean multipleMode) throws HeadlessException {
233         GraphicsEnvironment.checkHeadless();
234         this.rows = (rows != 0) ? rows : DEFAULT_VISIBLE_ROWS;
235         this.multipleMode = multipleMode;
236     }
237 
238     /**
239      * Construct a name for this component.  Called by
240      * <code>getName</code> when the name is <code>null</code>.
241      */
constructComponentName()242     String constructComponentName() {
243         synchronized (List.class) {
244             return base + nameCounter++;
245         }
246     }
247 
248     /**
249      * Creates the peer for the list.  The peer allows us to modify the
250      * list's appearance without changing its functionality.
251      */
addNotify()252     public void addNotify() {
253         synchronized (getTreeLock()) {
254             if (peer == null)
255                 peer = getToolkit().createList(this);
256             super.addNotify();
257         }
258     }
259 
260     /**
261      * Removes the peer for this list.  The peer allows us to modify the
262      * list's appearance without changing its functionality.
263      */
removeNotify()264     public void removeNotify() {
265         synchronized (getTreeLock()) {
266             ListPeer peer = (ListPeer)this.peer;
267             if (peer != null) {
268                 selected = peer.getSelectedIndexes();
269             }
270             super.removeNotify();
271         }
272     }
273 
274     /**
275      * Gets the number of items in the list.
276      * @return     the number of items in the list
277      * @see        #getItem
278      * @since      JDK1.1
279      */
getItemCount()280     public int getItemCount() {
281         return countItems();
282     }
283 
284     /**
285      * @deprecated As of JDK version 1.1,
286      * replaced by <code>getItemCount()</code>.
287      */
288     @Deprecated
countItems()289     public int countItems() {
290         return items.size();
291     }
292 
293     /**
294      * Gets the item associated with the specified index.
295      * @return       an item that is associated with
296      *                    the specified index
297      * @param        index the position of the item
298      * @see          #getItemCount
299      */
getItem(int index)300     public String getItem(int index) {
301         return getItemImpl(index);
302     }
303 
304     // NOTE: This method may be called by privileged threads.
305     //       We implement this functionality in a package-private method
306     //       to insure that it cannot be overridden by client subclasses.
307     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
getItemImpl(int index)308     final String getItemImpl(int index) {
309         return items.elementAt(index);
310     }
311 
312     /**
313      * Gets the items in the list.
314      * @return       a string array containing items of the list
315      * @see          #select
316      * @see          #deselect
317      * @see          #isIndexSelected
318      * @since        JDK1.1
319      */
getItems()320     public synchronized String[] getItems() {
321         String itemCopies[] = new String[items.size()];
322         items.copyInto(itemCopies);
323         return itemCopies;
324     }
325 
326     /**
327      * Adds the specified item to the end of scrolling list.
328      * @param item the item to be added
329      * @since JDK1.1
330      */
add(String item)331     public void add(String item) {
332         addItem(item);
333     }
334 
335     /**
336      * @deprecated      replaced by <code>add(String)</code>.
337      */
338     @Deprecated
addItem(String item)339     public void addItem(String item) {
340         addItem(item, -1);
341     }
342 
343     /**
344      * Adds the specified item to the the scrolling list
345      * at the position indicated by the index.  The index is
346      * zero-based.  If the value of the index is less than zero,
347      * or if the value of the index is greater than or equal to
348      * the number of items in the list, then the item is added
349      * to the end of the list.
350      * @param       item   the item to be added;
351      *              if this parameter is <code>null</code> then the item is
352      *              treated as an empty string, <code>""</code>
353      * @param       index  the position at which to add the item
354      * @since       JDK1.1
355      */
add(String item, int index)356     public void add(String item, int index) {
357         addItem(item, index);
358     }
359 
360     /**
361      * @deprecated      replaced by <code>add(String, int)</code>.
362      */
363     @Deprecated
addItem(String item, int index)364     public synchronized void addItem(String item, int index) {
365         if (index < -1 || index >= items.size()) {
366             index = -1;
367         }
368 
369         if (item == null) {
370             item = "";
371         }
372 
373         if (index == -1) {
374             items.addElement(item);
375         } else {
376             items.insertElementAt(item, index);
377         }
378 
379         ListPeer peer = (ListPeer)this.peer;
380         if (peer != null) {
381             peer.add(item, index);
382         }
383     }
384 
385     /**
386      * Replaces the item at the specified index in the scrolling list
387      * with the new string.
388      * @param       newValue   a new string to replace an existing item
389      * @param       index      the position of the item to replace
390      * @exception ArrayIndexOutOfBoundsException if <code>index</code>
391      *          is out of range
392      */
replaceItem(String newValue, int index)393     public synchronized void replaceItem(String newValue, int index) {
394         remove(index);
395         add(newValue, index);
396     }
397 
398     /**
399      * Removes all items from this list.
400      * @see #remove
401      * @see #delItems
402      * @since JDK1.1
403      */
removeAll()404     public void removeAll() {
405         clear();
406     }
407 
408     /**
409      * @deprecated As of JDK version 1.1,
410      * replaced by <code>removeAll()</code>.
411      */
412     @Deprecated
clear()413     public synchronized void clear() {
414         ListPeer peer = (ListPeer)this.peer;
415         if (peer != null) {
416             peer.removeAll();
417         }
418         items = new Vector<>();
419         selected = new int[0];
420     }
421 
422     /**
423      * Removes the first occurrence of an item from the list.
424      * If the specified item is selected, and is the only selected
425      * item in the list, the list is set to have no selection.
426      * @param        item  the item to remove from the list
427      * @exception    IllegalArgumentException
428      *                     if the item doesn't exist in the list
429      * @since        JDK1.1
430      */
remove(String item)431     public synchronized void remove(String item) {
432         int index = items.indexOf(item);
433         if (index < 0) {
434             throw new IllegalArgumentException("item " + item +
435                                                " not found in list");
436         } else {
437             remove(index);
438         }
439     }
440 
441     /**
442      * Removes the item at the specified position
443      * from this scrolling list.
444      * If the item with the specified position is selected, and is the
445      * only selected item in the list, the list is set to have no selection.
446      * @param      position   the index of the item to delete
447      * @see        #add(String, int)
448      * @since      JDK1.1
449      * @exception    ArrayIndexOutOfBoundsException
450      *               if the <code>position</code> is less than 0 or
451      *               greater than <code>getItemCount()-1</code>
452      */
remove(int position)453     public void remove(int position) {
454         delItem(position);
455     }
456 
457     /**
458      * @deprecated     replaced by <code>remove(String)</code>
459      *                         and <code>remove(int)</code>.
460      */
461     @Deprecated
delItem(int position)462     public void delItem(int position) {
463         delItems(position, position);
464     }
465 
466     /**
467      * Gets the index of the selected item on the list,
468      *
469      * @return        the index of the selected item;
470      *                if no item is selected, or if multiple items are
471      *                selected, <code>-1</code> is returned.
472      * @see           #select
473      * @see           #deselect
474      * @see           #isIndexSelected
475      */
getSelectedIndex()476     public synchronized int getSelectedIndex() {
477         int sel[] = getSelectedIndexes();
478         return (sel.length == 1) ? sel[0] : -1;
479     }
480 
481     /**
482      * Gets the selected indexes on the list.
483      *
484      * @return        an array of the selected indexes on this scrolling list;
485      *                if no item is selected, a zero-length array is returned.
486      * @see           #select
487      * @see           #deselect
488      * @see           #isIndexSelected
489      */
getSelectedIndexes()490     public synchronized int[] getSelectedIndexes() {
491         ListPeer peer = (ListPeer)this.peer;
492         if (peer != null) {
493             selected = peer.getSelectedIndexes();
494         }
495         return selected.clone();
496     }
497 
498     /**
499      * Gets the selected item on this scrolling list.
500      *
501      * @return        the selected item on the list;
502      *                if no item is selected, or if multiple items are
503      *                selected, <code>null</code> is returned.
504      * @see           #select
505      * @see           #deselect
506      * @see           #isIndexSelected
507      */
getSelectedItem()508     public synchronized String getSelectedItem() {
509         int index = getSelectedIndex();
510         return (index < 0) ? null : getItem(index);
511     }
512 
513     /**
514      * Gets the selected items on this scrolling list.
515      *
516      * @return        an array of the selected items on this scrolling list;
517      *                if no item is selected, a zero-length array is returned.
518      * @see           #select
519      * @see           #deselect
520      * @see           #isIndexSelected
521      */
getSelectedItems()522     public synchronized String[] getSelectedItems() {
523         int sel[] = getSelectedIndexes();
524         String str[] = new String[sel.length];
525         for (int i = 0 ; i < sel.length ; i++) {
526             str[i] = getItem(sel[i]);
527         }
528         return str;
529     }
530 
531     /**
532      * Gets the selected items on this scrolling list in an array of Objects.
533      * @return        an array of <code>Object</code>s representing the
534      *                selected items on this scrolling list;
535      *                if no item is selected, a zero-length array is returned.
536      * @see #getSelectedItems
537      * @see ItemSelectable
538      */
getSelectedObjects()539     public Object[] getSelectedObjects() {
540         return getSelectedItems();
541     }
542 
543     /**
544      * Selects the item at the specified index in the scrolling list.
545      *<p>
546      * Note that passing out of range parameters is invalid,
547      * and will result in unspecified behavior.
548      *
549      * <p>Note that this method should be primarily used to
550      * initially select an item in this component.
551      * Programmatically calling this method will <i>not</i> trigger
552      * an <code>ItemEvent</code>.  The only way to trigger an
553      * <code>ItemEvent</code> is by user interaction.
554      *
555      * @param        index the position of the item to select
556      * @see          #getSelectedItem
557      * @see          #deselect
558      * @see          #isIndexSelected
559      */
select(int index)560     public void select(int index) {
561         // Bug #4059614: select can't be synchronized while calling the peer,
562         // because it is called from the Window Thread.  It is sufficient to
563         // synchronize the code that manipulates 'selected' except for the
564         // case where the peer changes.  To handle this case, we simply
565         // repeat the selection process.
566 
567         ListPeer peer;
568         do {
569             peer = (ListPeer)this.peer;
570             if (peer != null) {
571                 peer.select(index);
572                 return;
573             }
574 
575             synchronized(this)
576             {
577                 boolean alreadySelected = false;
578 
579                 for (int i = 0 ; i < selected.length ; i++) {
580                     if (selected[i] == index) {
581                         alreadySelected = true;
582                         break;
583                     }
584                 }
585 
586                 if (!alreadySelected) {
587                     if (!multipleMode) {
588                         selected = new int[1];
589                         selected[0] = index;
590                     } else {
591                         int newsel[] = new int[selected.length + 1];
592                         System.arraycopy(selected, 0, newsel, 0,
593                                          selected.length);
594                         newsel[selected.length] = index;
595                         selected = newsel;
596                     }
597                 }
598             }
599         } while (peer != this.peer);
600     }
601 
602     /**
603      * Deselects the item at the specified index.
604      * <p>
605      * Note that passing out of range parameters is invalid,
606      * and will result in unspecified behavior.
607      * <p>
608      * If the item at the specified index is not selected,
609      * then the operation is ignored.
610      * @param        index the position of the item to deselect
611      * @see          #select
612      * @see          #getSelectedItem
613      * @see          #isIndexSelected
614      */
deselect(int index)615     public synchronized void deselect(int index) {
616         ListPeer peer = (ListPeer)this.peer;
617         if (peer != null) {
618             if (isMultipleMode() || (getSelectedIndex() == index)) {
619                 peer.deselect(index);
620             }
621         }
622 
623         for (int i = 0 ; i < selected.length ; i++) {
624             if (selected[i] == index) {
625                 int newsel[] = new int[selected.length - 1];
626                 System.arraycopy(selected, 0, newsel, 0, i);
627                 System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
628                 selected = newsel;
629                 return;
630             }
631         }
632     }
633 
634     /**
635      * Determines if the specified item in this scrolling list is
636      * selected.
637      * @param      index   the item to be checked
638      * @return     <code>true</code> if the specified item has been
639      *                       selected; <code>false</code> otherwise
640      * @see        #select
641      * @see        #deselect
642      * @since      JDK1.1
643      */
isIndexSelected(int index)644     public boolean isIndexSelected(int index) {
645         return isSelected(index);
646     }
647 
648     /**
649      * @deprecated As of JDK version 1.1,
650      * replaced by <code>isIndexSelected(int)</code>.
651      */
652     @Deprecated
isSelected(int index)653     public boolean isSelected(int index) {
654         int sel[] = getSelectedIndexes();
655         for (int i = 0 ; i < sel.length ; i++) {
656             if (sel[i] == index) {
657                 return true;
658             }
659         }
660         return false;
661     }
662 
663     /**
664      * Gets the number of visible lines in this list.  Note that
665      * once the <code>List</code> has been created, this number
666      * will never change.
667      * @return     the number of visible lines in this scrolling list
668      */
getRows()669     public int getRows() {
670         return rows;
671     }
672 
673     /**
674      * Determines whether this list allows multiple selections.
675      * @return     <code>true</code> if this list allows multiple
676      *                 selections; otherwise, <code>false</code>
677      * @see        #setMultipleMode
678      * @since      JDK1.1
679      */
isMultipleMode()680     public boolean isMultipleMode() {
681         return allowsMultipleSelections();
682     }
683 
684     /**
685      * @deprecated As of JDK version 1.1,
686      * replaced by <code>isMultipleMode()</code>.
687      */
688     @Deprecated
allowsMultipleSelections()689     public boolean allowsMultipleSelections() {
690         return multipleMode;
691     }
692 
693     /**
694      * Sets the flag that determines whether this list
695      * allows multiple selections.
696      * When the selection mode is changed from multiple-selection to
697      * single-selection, the selected items change as follows:
698      * If a selected item has the location cursor, only that
699      * item will remain selected.  If no selected item has the
700      * location cursor, all items will be deselected.
701      * @param       b   if <code>true</code> then multiple selections
702      *                      are allowed; otherwise, only one item from
703      *                      the list can be selected at once
704      * @see         #isMultipleMode
705      * @since       JDK1.1
706      */
setMultipleMode(boolean b)707     public void setMultipleMode(boolean b) {
708         setMultipleSelections(b);
709     }
710 
711     /**
712      * @deprecated As of JDK version 1.1,
713      * replaced by <code>setMultipleMode(boolean)</code>.
714      */
715     @Deprecated
setMultipleSelections(boolean b)716     public synchronized void setMultipleSelections(boolean b) {
717         if (b != multipleMode) {
718             multipleMode = b;
719             ListPeer peer = (ListPeer)this.peer;
720             if (peer != null) {
721                 peer.setMultipleMode(b);
722             }
723         }
724     }
725 
726     /**
727      * Gets the index of the item that was last made visible by
728      * the method <code>makeVisible</code>.
729      * @return      the index of the item that was last made visible
730      * @see         #makeVisible
731      */
getVisibleIndex()732     public int getVisibleIndex() {
733         return visibleIndex;
734     }
735 
736     /**
737      * Makes the item at the specified index visible.
738      * @param       index    the position of the item
739      * @see         #getVisibleIndex
740      */
makeVisible(int index)741     public synchronized void makeVisible(int index) {
742         visibleIndex = index;
743         ListPeer peer = (ListPeer)this.peer;
744         if (peer != null) {
745             peer.makeVisible(index);
746         }
747     }
748 
749     /**
750      * Gets the preferred dimensions for a list with the specified
751      * number of rows.
752      * @param      rows    number of rows in the list
753      * @return     the preferred dimensions for displaying this scrolling list
754      *             given that the specified number of rows must be visible
755      * @see        java.awt.Component#getPreferredSize
756      * @since      JDK1.1
757      */
getPreferredSize(int rows)758     public Dimension getPreferredSize(int rows) {
759         return preferredSize(rows);
760     }
761 
762     /**
763      * @deprecated As of JDK version 1.1,
764      * replaced by <code>getPreferredSize(int)</code>.
765      */
766     @Deprecated
preferredSize(int rows)767     public Dimension preferredSize(int rows) {
768         synchronized (getTreeLock()) {
769             ListPeer peer = (ListPeer)this.peer;
770             return (peer != null) ?
771                        peer.getPreferredSize(rows) :
772                        super.preferredSize();
773         }
774     }
775 
776     /**
777      * Gets the preferred size of this scrolling list.
778      * @return     the preferred dimensions for displaying this scrolling list
779      * @see        java.awt.Component#getPreferredSize
780      * @since      JDK1.1
781      */
getPreferredSize()782     public Dimension getPreferredSize() {
783         return preferredSize();
784     }
785 
786     /**
787      * @deprecated As of JDK version 1.1,
788      * replaced by <code>getPreferredSize()</code>.
789      */
790     @Deprecated
preferredSize()791     public Dimension preferredSize() {
792         synchronized (getTreeLock()) {
793             return (rows > 0) ?
794                        preferredSize(rows) :
795                        super.preferredSize();
796         }
797     }
798 
799     /**
800      * Gets the minimum dimensions for a list with the specified
801      * number of rows.
802      * @param      rows    number of rows in the list
803      * @return     the minimum dimensions for displaying this scrolling list
804      *             given that the specified number of rows must be visible
805      * @see        java.awt.Component#getMinimumSize
806      * @since      JDK1.1
807      */
getMinimumSize(int rows)808     public Dimension getMinimumSize(int rows) {
809         return minimumSize(rows);
810     }
811 
812     /**
813      * @deprecated As of JDK version 1.1,
814      * replaced by <code>getMinimumSize(int)</code>.
815      */
816     @Deprecated
minimumSize(int rows)817     public Dimension minimumSize(int rows) {
818         synchronized (getTreeLock()) {
819             ListPeer peer = (ListPeer)this.peer;
820             return (peer != null) ?
821                        peer.getMinimumSize(rows) :
822                        super.minimumSize();
823         }
824     }
825 
826     /**
827      * Determines the minimum size of this scrolling list.
828      * @return       the minimum dimensions needed
829      *                        to display this scrolling list
830      * @see          java.awt.Component#getMinimumSize()
831      * @since        JDK1.1
832      */
getMinimumSize()833     public Dimension getMinimumSize() {
834         return minimumSize();
835     }
836 
837     /**
838      * @deprecated As of JDK version 1.1,
839      * replaced by <code>getMinimumSize()</code>.
840      */
841     @Deprecated
minimumSize()842     public Dimension minimumSize() {
843         synchronized (getTreeLock()) {
844             return (rows > 0) ? minimumSize(rows) : super.minimumSize();
845         }
846     }
847 
848     /**
849      * Adds the specified item listener to receive item events from
850      * this list.  Item events are sent in response to user input, but not
851      * in response to calls to <code>select</code> or <code>deselect</code>.
852      * If listener <code>l</code> is <code>null</code>,
853      * no exception is thrown and no action is performed.
854      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
855      * >AWT Threading Issues</a> for details on AWT's threading model.
856      *
857      * @param         l the item listener
858      * @see           #removeItemListener
859      * @see           #getItemListeners
860      * @see           #select
861      * @see           #deselect
862      * @see           java.awt.event.ItemEvent
863      * @see           java.awt.event.ItemListener
864      * @since         JDK1.1
865      */
addItemListener(ItemListener l)866     public synchronized void addItemListener(ItemListener l) {
867         if (l == null) {
868             return;
869         }
870         itemListener = AWTEventMulticaster.add(itemListener, l);
871         newEventsOnly = true;
872     }
873 
874     /**
875      * Removes the specified item listener so that it no longer
876      * receives item events from this list.
877      * If listener <code>l</code> is <code>null</code>,
878      * no exception is thrown and no action is performed.
879      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
880      * >AWT Threading Issues</a> for details on AWT's threading model.
881      *
882      * @param           l the item listener
883      * @see             #addItemListener
884      * @see             #getItemListeners
885      * @see             java.awt.event.ItemEvent
886      * @see             java.awt.event.ItemListener
887      * @since           JDK1.1
888      */
removeItemListener(ItemListener l)889     public synchronized void removeItemListener(ItemListener l) {
890         if (l == null) {
891             return;
892         }
893         itemListener = AWTEventMulticaster.remove(itemListener, l);
894     }
895 
896     /**
897      * Returns an array of all the item listeners
898      * registered on this list.
899      *
900      * @return all of this list's <code>ItemListener</code>s
901      *         or an empty array if no item
902      *         listeners are currently registered
903      *
904      * @see             #addItemListener
905      * @see             #removeItemListener
906      * @see             java.awt.event.ItemEvent
907      * @see             java.awt.event.ItemListener
908      * @since 1.4
909      */
getItemListeners()910     public synchronized ItemListener[] getItemListeners() {
911         return getListeners(ItemListener.class);
912     }
913 
914     /**
915      * Adds the specified action listener to receive action events from
916      * this list. Action events occur when a user double-clicks
917      * on a list item or types Enter when the list has the keyboard
918      * focus.
919      * <p>
920      * If listener <code>l</code> is <code>null</code>,
921      * no exception is thrown and no action is performed.
922      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
923      * >AWT Threading Issues</a> for details on AWT's threading model.
924      *
925      * @param         l the action listener
926      * @see           #removeActionListener
927      * @see           #getActionListeners
928      * @see           java.awt.event.ActionEvent
929      * @see           java.awt.event.ActionListener
930      * @since         JDK1.1
931      */
addActionListener(ActionListener l)932     public synchronized void addActionListener(ActionListener l) {
933         if (l == null) {
934             return;
935         }
936         actionListener = AWTEventMulticaster.add(actionListener, l);
937         newEventsOnly = true;
938     }
939 
940     /**
941      * Removes the specified action listener so that it no longer
942      * receives action events from this list. Action events
943      * occur when a user double-clicks on a list item.
944      * If listener <code>l</code> is <code>null</code>,
945      * no exception is thrown and no action is performed.
946      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
947      * >AWT Threading Issues</a> for details on AWT's threading model.
948      *
949      * @param           l     the action listener
950      * @see             #addActionListener
951      * @see             #getActionListeners
952      * @see             java.awt.event.ActionEvent
953      * @see             java.awt.event.ActionListener
954      * @since           JDK1.1
955      */
removeActionListener(ActionListener l)956     public synchronized void removeActionListener(ActionListener l) {
957         if (l == null) {
958             return;
959         }
960         actionListener = AWTEventMulticaster.remove(actionListener, l);
961     }
962 
963     /**
964      * Returns an array of all the action listeners
965      * registered on this list.
966      *
967      * @return all of this list's <code>ActionListener</code>s
968      *         or an empty array if no action
969      *         listeners are currently registered
970      *
971      * @see             #addActionListener
972      * @see             #removeActionListener
973      * @see             java.awt.event.ActionEvent
974      * @see             java.awt.event.ActionListener
975      * @since 1.4
976      */
getActionListeners()977     public synchronized ActionListener[] getActionListeners() {
978         return getListeners(ActionListener.class);
979     }
980 
981     /**
982      * Returns an array of all the objects currently registered
983      * as <code><em>Foo</em>Listener</code>s
984      * upon this <code>List</code>.
985      * <code><em>Foo</em>Listener</code>s are registered using the
986      * <code>add<em>Foo</em>Listener</code> method.
987      *
988      * <p>
989      * You can specify the <code>listenerType</code> argument
990      * with a class literal, such as
991      * <code><em>Foo</em>Listener.class</code>.
992      * For example, you can query a
993      * <code>List</code> <code>l</code>
994      * for its item listeners with the following code:
995      *
996      * <pre>ItemListener[] ils = (ItemListener[])(l.getListeners(ItemListener.class));</pre>
997      *
998      * If no such listeners exist, this method returns an empty array.
999      *
1000      * @param listenerType the type of listeners requested; this parameter
1001      *          should specify an interface that descends from
1002      *          <code>java.util.EventListener</code>
1003      * @return an array of all objects registered as
1004      *          <code><em>Foo</em>Listener</code>s on this list,
1005      *          or an empty array if no such
1006      *          listeners have been added
1007      * @exception ClassCastException if <code>listenerType</code>
1008      *          doesn't specify a class or interface that implements
1009      *          <code>java.util.EventListener</code>
1010      *
1011      * @see #getItemListeners
1012      * @since 1.3
1013      */
getListeners(Class<T> listenerType)1014     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1015         EventListener l = null;
1016         if  (listenerType == ActionListener.class) {
1017             l = actionListener;
1018         } else if  (listenerType == ItemListener.class) {
1019             l = itemListener;
1020         } else {
1021             return super.getListeners(listenerType);
1022         }
1023         return AWTEventMulticaster.getListeners(l, listenerType);
1024     }
1025 
1026     // REMIND: remove when filtering is done at lower level
eventEnabled(AWTEvent e)1027     boolean eventEnabled(AWTEvent e) {
1028         switch(e.id) {
1029           case ActionEvent.ACTION_PERFORMED:
1030             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
1031                 actionListener != null) {
1032                 return true;
1033             }
1034             return false;
1035           case ItemEvent.ITEM_STATE_CHANGED:
1036             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
1037                 itemListener != null) {
1038                 return true;
1039             }
1040             return false;
1041           default:
1042             break;
1043         }
1044         return super.eventEnabled(e);
1045     }
1046 
1047     /**
1048      * Processes events on this scrolling list. If an event is
1049      * an instance of <code>ItemEvent</code>, it invokes the
1050      * <code>processItemEvent</code> method. Else, if the
1051      * event is an instance of <code>ActionEvent</code>,
1052      * it invokes <code>processActionEvent</code>.
1053      * If the event is not an item event or an action event,
1054      * it invokes <code>processEvent</code> on the superclass.
1055      * <p>Note that if the event parameter is <code>null</code>
1056      * the behavior is unspecified and may result in an
1057      * exception.
1058      *
1059      * @param        e the event
1060      * @see          java.awt.event.ActionEvent
1061      * @see          java.awt.event.ItemEvent
1062      * @see          #processActionEvent
1063      * @see          #processItemEvent
1064      * @since        JDK1.1
1065      */
processEvent(AWTEvent e)1066     protected void processEvent(AWTEvent e) {
1067         if (e instanceof ItemEvent) {
1068             processItemEvent((ItemEvent)e);
1069             return;
1070         } else if (e instanceof ActionEvent) {
1071             processActionEvent((ActionEvent)e);
1072             return;
1073         }
1074         super.processEvent(e);
1075     }
1076 
1077     /**
1078      * Processes item events occurring on this list by
1079      * dispatching them to any registered
1080      * <code>ItemListener</code> objects.
1081      * <p>
1082      * This method is not called unless item events are
1083      * enabled for this component. Item events are enabled
1084      * when one of the following occurs:
1085      * <ul>
1086      * <li>An <code>ItemListener</code> object is registered
1087      * via <code>addItemListener</code>.
1088      * <li>Item events are enabled via <code>enableEvents</code>.
1089      * </ul>
1090      * <p>Note that if the event parameter is <code>null</code>
1091      * the behavior is unspecified and may result in an
1092      * exception.
1093      *
1094      * @param       e the item event
1095      * @see         java.awt.event.ItemEvent
1096      * @see         java.awt.event.ItemListener
1097      * @see         #addItemListener
1098      * @see         java.awt.Component#enableEvents
1099      * @since       JDK1.1
1100      */
processItemEvent(ItemEvent e)1101     protected void processItemEvent(ItemEvent e) {
1102         ItemListener listener = itemListener;
1103         if (listener != null) {
1104             listener.itemStateChanged(e);
1105         }
1106     }
1107 
1108     /**
1109      * Processes action events occurring on this component
1110      * by dispatching them to any registered
1111      * <code>ActionListener</code> objects.
1112      * <p>
1113      * This method is not called unless action events are
1114      * enabled for this component. Action events are enabled
1115      * when one of the following occurs:
1116      * <ul>
1117      * <li>An <code>ActionListener</code> object is registered
1118      * via <code>addActionListener</code>.
1119      * <li>Action events are enabled via <code>enableEvents</code>.
1120      * </ul>
1121      * <p>Note that if the event parameter is <code>null</code>
1122      * the behavior is unspecified and may result in an
1123      * exception.
1124      *
1125      * @param       e the action event
1126      * @see         java.awt.event.ActionEvent
1127      * @see         java.awt.event.ActionListener
1128      * @see         #addActionListener
1129      * @see         java.awt.Component#enableEvents
1130      * @since       JDK1.1
1131      */
processActionEvent(ActionEvent e)1132     protected void processActionEvent(ActionEvent e) {
1133         ActionListener listener = actionListener;
1134         if (listener != null) {
1135             listener.actionPerformed(e);
1136         }
1137     }
1138 
1139     /**
1140      * Returns the parameter string representing the state of this
1141      * scrolling list. This string is useful for debugging.
1142      * @return    the parameter string of this scrolling list
1143      */
paramString()1144     protected String paramString() {
1145         return super.paramString() + ",selected=" + getSelectedItem();
1146     }
1147 
1148     /**
1149      * @deprecated As of JDK version 1.1,
1150      * Not for public use in the future.
1151      * This method is expected to be retained only as a package
1152      * private method.
1153      */
1154     @Deprecated
delItems(int start, int end)1155     public synchronized void delItems(int start, int end) {
1156         for (int i = end; i >= start; i--) {
1157             items.removeElementAt(i);
1158         }
1159         ListPeer peer = (ListPeer)this.peer;
1160         if (peer != null) {
1161             peer.delItems(start, end);
1162         }
1163     }
1164 
1165     /*
1166      * Serialization support.  Since the value of the selected
1167      * field isn't necessarily up to date, we sync it up with the
1168      * peer before serializing.
1169      */
1170 
1171     /**
1172      * The <code>List</code> component's
1173      * Serialized Data Version.
1174      *
1175      * @serial
1176      */
1177     private int listSerializedDataVersion = 1;
1178 
1179     /**
1180      * Writes default serializable fields to stream.  Writes
1181      * a list of serializable <code>ItemListeners</code>
1182      * and <code>ActionListeners</code> as optional data.
1183      * The non-serializable listeners are detected and
1184      * no attempt is made to serialize them.
1185      *
1186      * @serialData <code>null</code> terminated sequence of 0
1187      *  or more pairs; the pair consists of a <code>String</code>
1188      *  and an <code>Object</code>; the <code>String</code>
1189      *  indicates the type of object and is one of the
1190      *  following:
1191      *  <code>itemListenerK</code> indicating an
1192      *    <code>ItemListener</code> object;
1193      *  <code>actionListenerK</code> indicating an
1194      *    <code>ActionListener</code> object
1195      *
1196      * @param s the <code>ObjectOutputStream</code> to write
1197      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1198      * @see java.awt.Component#itemListenerK
1199      * @see java.awt.Component#actionListenerK
1200      * @see #readObject(ObjectInputStream)
1201      */
writeObject(ObjectOutputStream s)1202     private void writeObject(ObjectOutputStream s)
1203       throws IOException
1204     {
1205       synchronized (this) {
1206         ListPeer peer = (ListPeer)this.peer;
1207         if (peer != null) {
1208           selected = peer.getSelectedIndexes();
1209         }
1210       }
1211       s.defaultWriteObject();
1212 
1213       AWTEventMulticaster.save(s, itemListenerK, itemListener);
1214       AWTEventMulticaster.save(s, actionListenerK, actionListener);
1215       s.writeObject(null);
1216     }
1217 
1218     /**
1219      * Reads the <code>ObjectInputStream</code> and if it
1220      * isn't <code>null</code> adds a listener to receive
1221      * both item events and action events (as specified
1222      * by the key stored in the stream) fired by the
1223      * <code>List</code>.
1224      * Unrecognized keys or values will be ignored.
1225      *
1226      * @param s the <code>ObjectInputStream</code> to write
1227      * @exception HeadlessException if
1228      *   <code>GraphicsEnvironment.isHeadless</code> returns
1229      *   <code>true</code>
1230      * @see #removeItemListener(ItemListener)
1231      * @see #addItemListener(ItemListener)
1232      * @see java.awt.GraphicsEnvironment#isHeadless
1233      * @see #writeObject(ObjectOutputStream)
1234      */
readObject(ObjectInputStream s)1235     private void readObject(ObjectInputStream s)
1236       throws ClassNotFoundException, IOException, HeadlessException
1237     {
1238       GraphicsEnvironment.checkHeadless();
1239       s.defaultReadObject();
1240 
1241       Object keyOrNull;
1242       while(null != (keyOrNull = s.readObject())) {
1243         String key = ((String)keyOrNull).intern();
1244 
1245         if (itemListenerK == key)
1246           addItemListener((ItemListener)(s.readObject()));
1247 
1248         else if (actionListenerK == key)
1249           addActionListener((ActionListener)(s.readObject()));
1250 
1251         else // skip value for unrecognized key
1252           s.readObject();
1253       }
1254     }
1255 
1256 
1257 /////////////////
1258 // Accessibility support
1259 ////////////////
1260 
1261 
1262     /**
1263      * Gets the <code>AccessibleContext</code> associated with this
1264      * <code>List</code>. For lists, the <code>AccessibleContext</code>
1265      * takes the form of an <code>AccessibleAWTList</code>.
1266      * A new <code>AccessibleAWTList</code> instance is created, if necessary.
1267      *
1268      * @return an <code>AccessibleAWTList</code> that serves as the
1269      *         <code>AccessibleContext</code> of this <code>List</code>
1270      * @since 1.3
1271      */
getAccessibleContext()1272     public AccessibleContext getAccessibleContext() {
1273         if (accessibleContext == null) {
1274             accessibleContext = new AccessibleAWTList();
1275         }
1276         return accessibleContext;
1277     }
1278 
1279     /**
1280      * This class implements accessibility support for the
1281      * <code>List</code> class.  It provides an implementation of the
1282      * Java Accessibility API appropriate to list user-interface elements.
1283      * @since 1.3
1284      */
1285     protected class AccessibleAWTList extends AccessibleAWTComponent
1286         implements AccessibleSelection, ItemListener, ActionListener
1287     {
1288         /*
1289          * JDK 1.3 serialVersionUID
1290          */
1291         private static final long serialVersionUID = 7924617370136012829L;
1292 
AccessibleAWTList()1293         public AccessibleAWTList() {
1294             super();
1295             List.this.addActionListener(this);
1296             List.this.addItemListener(this);
1297         }
1298 
actionPerformed(ActionEvent event)1299         public void actionPerformed(ActionEvent event)  {
1300         }
1301 
itemStateChanged(ItemEvent event)1302         public void itemStateChanged(ItemEvent event)  {
1303         }
1304 
1305         /**
1306          * Get the state set of this object.
1307          *
1308          * @return an instance of AccessibleState containing the current state
1309          * of the object
1310          * @see AccessibleState
1311          */
getAccessibleStateSet()1312         public AccessibleStateSet getAccessibleStateSet() {
1313             AccessibleStateSet states = super.getAccessibleStateSet();
1314             if (List.this.isMultipleMode())  {
1315                 states.add(AccessibleState.MULTISELECTABLE);
1316             }
1317             return states;
1318         }
1319 
1320         /**
1321          * Get the role of this object.
1322          *
1323          * @return an instance of AccessibleRole describing the role of the
1324          * object
1325          * @see AccessibleRole
1326          */
getAccessibleRole()1327         public AccessibleRole getAccessibleRole() {
1328             return AccessibleRole.LIST;
1329         }
1330 
1331         /**
1332          * Returns the Accessible child contained at the local coordinate
1333          * Point, if one exists.
1334          *
1335          * @return the Accessible at the specified location, if it exists
1336          */
getAccessibleAt(Point p)1337         public Accessible getAccessibleAt(Point p) {
1338             return null; // fredxFIXME Not implemented yet
1339         }
1340 
1341         /**
1342          * Returns the number of accessible children in the object.  If all
1343          * of the children of this object implement Accessible, than this
1344          * method should return the number of children of this object.
1345          *
1346          * @return the number of accessible children in the object.
1347          */
getAccessibleChildrenCount()1348         public int getAccessibleChildrenCount() {
1349             return List.this.getItemCount();
1350         }
1351 
1352         /**
1353          * Return the nth Accessible child of the object.
1354          *
1355          * @param i zero-based index of child
1356          * @return the nth Accessible child of the object
1357          */
getAccessibleChild(int i)1358         public Accessible getAccessibleChild(int i) {
1359             synchronized(List.this)  {
1360                 if (i >= List.this.getItemCount()) {
1361                     return null;
1362                 } else {
1363                     return new AccessibleAWTListChild(List.this, i);
1364                 }
1365             }
1366         }
1367 
1368         /**
1369          * Get the AccessibleSelection associated with this object.  In the
1370          * implementation of the Java Accessibility API for this class,
1371          * return this object, which is responsible for implementing the
1372          * AccessibleSelection interface on behalf of itself.
1373          *
1374          * @return this object
1375          */
getAccessibleSelection()1376         public AccessibleSelection getAccessibleSelection() {
1377             return this;
1378         }
1379 
1380     // AccessibleSelection methods
1381 
1382         /**
1383          * Returns the number of items currently selected.
1384          * If no items are selected, the return value will be 0.
1385          *
1386          * @return the number of items currently selected.
1387          */
getAccessibleSelectionCount()1388          public int getAccessibleSelectionCount() {
1389              return List.this.getSelectedIndexes().length;
1390          }
1391 
1392         /**
1393          * Returns an Accessible representing the specified selected item
1394          * in the object.  If there isn't a selection, or there are
1395          * fewer items selected than the integer passed in, the return
1396          * value will be null.
1397          *
1398          * @param i the zero-based index of selected items
1399          * @return an Accessible containing the selected item
1400          */
getAccessibleSelection(int i)1401          public Accessible getAccessibleSelection(int i) {
1402              synchronized(List.this)  {
1403                  int len = getAccessibleSelectionCount();
1404                  if (i < 0 || i >= len) {
1405                      return null;
1406                  } else {
1407                      return getAccessibleChild(List.this.getSelectedIndexes()[i]);
1408                  }
1409              }
1410          }
1411 
1412         /**
1413          * Returns true if the current child of this object is selected.
1414          *
1415          * @param i the zero-based index of the child in this Accessible
1416          * object.
1417          * @see AccessibleContext#getAccessibleChild
1418          */
isAccessibleChildSelected(int i)1419         public boolean isAccessibleChildSelected(int i) {
1420             return List.this.isIndexSelected(i);
1421         }
1422 
1423         /**
1424          * Adds the specified selected item in the object to the object's
1425          * selection.  If the object supports multiple selections,
1426          * the specified item is added to any existing selection, otherwise
1427          * it replaces any existing selection in the object.  If the
1428          * specified item is already selected, this method has no effect.
1429          *
1430          * @param i the zero-based index of selectable items
1431          */
addAccessibleSelection(int i)1432          public void addAccessibleSelection(int i) {
1433              List.this.select(i);
1434          }
1435 
1436         /**
1437          * Removes the specified selected item in the object from the object's
1438          * selection.  If the specified item isn't currently selected, this
1439          * method has no effect.
1440          *
1441          * @param i the zero-based index of selectable items
1442          */
removeAccessibleSelection(int i)1443          public void removeAccessibleSelection(int i) {
1444              List.this.deselect(i);
1445          }
1446 
1447         /**
1448          * Clears the selection in the object, so that nothing in the
1449          * object is selected.
1450          */
clearAccessibleSelection()1451          public void clearAccessibleSelection() {
1452              synchronized(List.this)  {
1453                  int selectedIndexes[] = List.this.getSelectedIndexes();
1454                  if (selectedIndexes == null)
1455                      return;
1456                  for (int i = selectedIndexes.length - 1; i >= 0; i--) {
1457                      List.this.deselect(selectedIndexes[i]);
1458                  }
1459              }
1460          }
1461 
1462         /**
1463          * Causes every selected item in the object to be selected
1464          * if the object supports multiple selections.
1465          */
selectAllAccessibleSelection()1466          public void selectAllAccessibleSelection() {
1467              synchronized(List.this)  {
1468                  for (int i = List.this.getItemCount() - 1; i >= 0; i--) {
1469                      List.this.select(i);
1470                  }
1471              }
1472          }
1473 
1474        /**
1475         * This class implements accessibility support for
1476         * List children.  It provides an implementation of the
1477         * Java Accessibility API appropriate to list children
1478         * user-interface elements.
1479         * @since 1.3
1480         */
1481         protected class AccessibleAWTListChild extends AccessibleAWTComponent
1482             implements Accessible
1483         {
1484             /*
1485              * JDK 1.3 serialVersionUID
1486              */
1487             private static final long serialVersionUID = 4412022926028300317L;
1488 
1489         // [[[FIXME]]] need to finish implementing this!!!
1490 
1491             private List parent;
1492             private int  indexInParent;
1493 
AccessibleAWTListChild(List parent, int indexInParent)1494             public AccessibleAWTListChild(List parent, int indexInParent)  {
1495                 this.parent = parent;
1496                 this.setAccessibleParent(parent);
1497                 this.indexInParent = indexInParent;
1498             }
1499 
1500             //
1501             // required Accessible methods
1502             //
1503           /**
1504            * Gets the AccessibleContext for this object.  In the
1505            * implementation of the Java Accessibility API for this class,
1506            * return this object, which acts as its own AccessibleContext.
1507            *
1508            * @return this object
1509            */
getAccessibleContext()1510             public AccessibleContext getAccessibleContext() {
1511                 return this;
1512             }
1513 
1514             //
1515             // required AccessibleContext methods
1516             //
1517 
1518             /**
1519              * Get the role of this object.
1520              *
1521              * @return an instance of AccessibleRole describing the role of
1522              * the object
1523              * @see AccessibleRole
1524              */
getAccessibleRole()1525             public AccessibleRole getAccessibleRole() {
1526                 return AccessibleRole.LIST_ITEM;
1527             }
1528 
1529             /**
1530              * Get the state set of this object.  The AccessibleStateSet of an
1531              * object is composed of a set of unique AccessibleState's.  A
1532              * change in the AccessibleStateSet of an object will cause a
1533              * PropertyChangeEvent to be fired for the
1534              * ACCESSIBLE_STATE_PROPERTY property.
1535              *
1536              * @return an instance of AccessibleStateSet containing the
1537              * current state set of the object
1538              * @see AccessibleStateSet
1539              * @see AccessibleState
1540              * @see #addPropertyChangeListener
1541              */
getAccessibleStateSet()1542             public AccessibleStateSet getAccessibleStateSet() {
1543                 AccessibleStateSet states = super.getAccessibleStateSet();
1544                 if (parent.isIndexSelected(indexInParent)) {
1545                     states.add(AccessibleState.SELECTED);
1546                 }
1547                 return states;
1548             }
1549 
1550             /**
1551              * Gets the locale of the component. If the component does not
1552              * have a locale, then the locale of its parent is returned.
1553              *
1554              * @return This component's locale.  If this component does not have
1555              * a locale, the locale of its parent is returned.
1556              *
1557              * @exception IllegalComponentStateException
1558              * If the Component does not have its own locale and has not yet
1559              * been added to a containment hierarchy such that the locale can
1560              * be determined from the containing parent.
1561              */
getLocale()1562             public Locale getLocale() {
1563                 return parent.getLocale();
1564             }
1565 
1566             /**
1567              * Get the 0-based index of this object in its accessible parent.
1568              *
1569              * @return the 0-based index of this object in its parent; -1 if
1570              * this object does not have an accessible parent.
1571              *
1572              * @see #getAccessibleParent
1573              * @see #getAccessibleChildrenCount
1574              * @see #getAccessibleChild
1575              */
getAccessibleIndexInParent()1576             public int getAccessibleIndexInParent() {
1577                 return indexInParent;
1578             }
1579 
1580             /**
1581              * Returns the number of accessible children of the object.
1582              *
1583              * @return the number of accessible children of the object.
1584              */
getAccessibleChildrenCount()1585             public int getAccessibleChildrenCount() {
1586                 return 0;       // list elements can't have children
1587             }
1588 
1589             /**
1590              * Return the specified Accessible child of the object.  The
1591              * Accessible children of an Accessible object are zero-based,
1592              * so the first child of an Accessible child is at index 0, the
1593              * second child is at index 1, and so on.
1594              *
1595              * @param i zero-based index of child
1596              * @return the Accessible child of the object
1597              * @see #getAccessibleChildrenCount
1598              */
getAccessibleChild(int i)1599             public Accessible getAccessibleChild(int i) {
1600                 return null;    // list elements can't have children
1601             }
1602 
1603 
1604             //
1605             // AccessibleComponent delegatation to parent List
1606             //
1607 
1608             /**
1609              * Get the background color of this object.
1610              *
1611              * @return the background color, if supported, of the object;
1612              * otherwise, null
1613              * @see #setBackground
1614              */
getBackground()1615             public Color getBackground() {
1616                 return parent.getBackground();
1617             }
1618 
1619             /**
1620              * Set the background color of this object.
1621              *
1622              * @param c the new Color for the background
1623              * @see #setBackground
1624              */
setBackground(Color c)1625             public void setBackground(Color c) {
1626                 parent.setBackground(c);
1627             }
1628 
1629             /**
1630              * Get the foreground color of this object.
1631              *
1632              * @return the foreground color, if supported, of the object;
1633              * otherwise, null
1634              * @see #setForeground
1635              */
getForeground()1636             public Color getForeground() {
1637                 return parent.getForeground();
1638             }
1639 
1640             /**
1641              * Set the foreground color of this object.
1642              *
1643              * @param c the new Color for the foreground
1644              * @see #getForeground
1645              */
setForeground(Color c)1646             public void setForeground(Color c) {
1647                 parent.setForeground(c);
1648             }
1649 
1650             /**
1651              * Get the Cursor of this object.
1652              *
1653              * @return the Cursor, if supported, of the object; otherwise, null
1654              * @see #setCursor
1655              */
getCursor()1656             public Cursor getCursor() {
1657                 return parent.getCursor();
1658             }
1659 
1660             /**
1661              * Set the Cursor of this object.
1662              * <p>
1663              * The method may have no visual effect if the Java platform
1664              * implementation and/or the native system do not support
1665              * changing the mouse cursor shape.
1666              * @param cursor the new Cursor for the object
1667              * @see #getCursor
1668              */
setCursor(Cursor cursor)1669             public void setCursor(Cursor cursor) {
1670                 parent.setCursor(cursor);
1671             }
1672 
1673             /**
1674              * Get the Font of this object.
1675              *
1676              * @return the Font,if supported, for the object; otherwise, null
1677              * @see #setFont
1678              */
getFont()1679             public Font getFont() {
1680                 return parent.getFont();
1681             }
1682 
1683             /**
1684              * Set the Font of this object.
1685              *
1686              * @param f the new Font for the object
1687              * @see #getFont
1688              */
setFont(Font f)1689             public void setFont(Font f) {
1690                 parent.setFont(f);
1691             }
1692 
1693             /**
1694              * Get the FontMetrics of this object.
1695              *
1696              * @param f the Font
1697              * @return the FontMetrics, if supported, the object; otherwise, null
1698              * @see #getFont
1699              */
getFontMetrics(Font f)1700             public FontMetrics getFontMetrics(Font f) {
1701                 return parent.getFontMetrics(f);
1702             }
1703 
1704             /**
1705              * Determine if the object is enabled.  Objects that are enabled
1706              * will also have the AccessibleState.ENABLED state set in their
1707              * AccessibleStateSet.
1708              *
1709              * @return true if object is enabled; otherwise, false
1710              * @see #setEnabled
1711              * @see AccessibleContext#getAccessibleStateSet
1712              * @see AccessibleState#ENABLED
1713              * @see AccessibleStateSet
1714              */
isEnabled()1715             public boolean isEnabled() {
1716                 return parent.isEnabled();
1717             }
1718 
1719             /**
1720              * Set the enabled state of the object.
1721              *
1722              * @param b if true, enables this object; otherwise, disables it
1723              * @see #isEnabled
1724              */
setEnabled(boolean b)1725             public void setEnabled(boolean b) {
1726                 parent.setEnabled(b);
1727             }
1728 
1729             /**
1730              * Determine if the object is visible.  Note: this means that the
1731              * object intends to be visible; however, it may not be
1732              * showing on the screen because one of the objects that this object
1733              * is contained by is currently not visible.  To determine if an
1734              * object is showing on the screen, use isShowing().
1735              * <p>Objects that are visible will also have the
1736              * AccessibleState.VISIBLE state set in their AccessibleStateSet.
1737              *
1738              * @return true if object is visible; otherwise, false
1739              * @see #setVisible
1740              * @see AccessibleContext#getAccessibleStateSet
1741              * @see AccessibleState#VISIBLE
1742              * @see AccessibleStateSet
1743              */
isVisible()1744             public boolean isVisible() {
1745                 // [[[FIXME]]] needs to work like isShowing() below
1746                 return false;
1747                 // return parent.isVisible();
1748             }
1749 
1750             /**
1751              * Set the visible state of the object.
1752              *
1753              * @param b if true, shows this object; otherwise, hides it
1754              * @see #isVisible
1755              */
setVisible(boolean b)1756             public void setVisible(boolean b) {
1757                 // [[[FIXME]]] should scroll to item to make it show!
1758                 parent.setVisible(b);
1759             }
1760 
1761             /**
1762              * Determine if the object is showing.  This is determined by
1763              * checking the visibility of the object and visibility of the
1764              * object ancestors.
1765              * Note: this will return true even if the object is obscured
1766              * by another (for example, it to object is underneath a menu
1767              * that was pulled down).
1768              *
1769              * @return true if object is showing; otherwise, false
1770              */
isShowing()1771             public boolean isShowing() {
1772                 // [[[FIXME]]] only if it's showing!!!
1773                 return false;
1774                 // return parent.isShowing();
1775             }
1776 
1777             /**
1778              * Checks whether the specified point is within this object's
1779              * bounds, where the point's x and y coordinates are defined to
1780              * be relative to the coordinate system of the object.
1781              *
1782              * @param p the Point relative to the coordinate system of the
1783              * object
1784              * @return true if object contains Point; otherwise false
1785              * @see #getBounds
1786              */
contains(Point p)1787             public boolean contains(Point p) {
1788                 // [[[FIXME]]] - only if p is within the list element!!!
1789                 return false;
1790                 // return parent.contains(p);
1791             }
1792 
1793             /**
1794              * Returns the location of the object on the screen.
1795              *
1796              * @return location of object on screen; null if this object
1797              * is not on the screen
1798              * @see #getBounds
1799              * @see #getLocation
1800              */
getLocationOnScreen()1801             public Point getLocationOnScreen() {
1802                 // [[[FIXME]]] sigh
1803                 return null;
1804             }
1805 
1806             /**
1807              * Gets the location of the object relative to the parent in the
1808              * form of a point specifying the object's top-left corner in the
1809              * screen's coordinate space.
1810              *
1811              * @return An instance of Point representing the top-left corner of
1812              * the objects's bounds in the coordinate space of the screen; null
1813              * if this object or its parent are not on the screen
1814              * @see #getBounds
1815              * @see #getLocationOnScreen
1816              */
getLocation()1817             public Point getLocation() {
1818                 // [[[FIXME]]]
1819                 return null;
1820             }
1821 
1822             /**
1823              * Sets the location of the object relative to the parent.
1824              * @param p the new position for the top-left corner
1825              * @see #getLocation
1826              */
setLocation(Point p)1827             public void setLocation(Point p) {
1828                 // [[[FIXME]]] maybe - can simply return as no-op
1829             }
1830 
1831             /**
1832              * Gets the bounds of this object in the form of a Rectangle object.
1833              * The bounds specify this object's width, height, and location
1834              * relative to its parent.
1835              *
1836              * @return A rectangle indicating this component's bounds; null if
1837              * this object is not on the screen.
1838              * @see #contains
1839              */
getBounds()1840             public Rectangle getBounds() {
1841                 // [[[FIXME]]]
1842                 return null;
1843             }
1844 
1845             /**
1846              * Sets the bounds of this object in the form of a Rectangle
1847              * object.  The bounds specify this object's width, height, and
1848              * location relative to its parent.
1849              *
1850              * @param r rectangle indicating this component's bounds
1851              * @see #getBounds
1852              */
setBounds(Rectangle r)1853             public void setBounds(Rectangle r) {
1854                 // no-op; not supported
1855             }
1856 
1857             /**
1858              * Returns the size of this object in the form of a Dimension
1859              * object.  The height field of the Dimension object contains this
1860              * objects's height, and the width field of the Dimension object
1861              * contains this object's width.
1862              *
1863              * @return A Dimension object that indicates the size of this
1864              * component; null if this object is not on the screen
1865              * @see #setSize
1866              */
getSize()1867             public Dimension getSize() {
1868                 // [[[FIXME]]]
1869                 return null;
1870             }
1871 
1872             /**
1873              * Resizes this object so that it has width and height.
1874              *
1875              * @param d - The dimension specifying the new size of the object.
1876              * @see #getSize
1877              */
setSize(Dimension d)1878             public void setSize(Dimension d) {
1879                 // not supported; no-op
1880             }
1881 
1882             /**
1883              * Returns the <code>Accessible</code> child, if one exists,
1884              * contained at the local coordinate <code>Point</code>.
1885              *
1886              * @param p the point relative to the coordinate system of this
1887              *     object
1888              * @return the <code>Accessible</code>, if it exists,
1889              *     at the specified location; otherwise <code>null</code>
1890              */
getAccessibleAt(Point p)1891             public Accessible getAccessibleAt(Point p) {
1892                 return null;    // object cannot have children!
1893             }
1894 
1895             /**
1896              * Returns whether this object can accept focus or not.   Objects
1897              * that can accept focus will also have the
1898              * <code>AccessibleState.FOCUSABLE</code> state set in their
1899              * <code>AccessibleStateSet</code>.
1900              *
1901              * @return true if object can accept focus; otherwise false
1902              * @see AccessibleContext#getAccessibleStateSet
1903              * @see AccessibleState#FOCUSABLE
1904              * @see AccessibleState#FOCUSED
1905              * @see AccessibleStateSet
1906              */
isFocusTraversable()1907             public boolean isFocusTraversable() {
1908                 return false;   // list element cannot receive focus!
1909             }
1910 
1911             /**
1912              * Requests focus for this object.  If this object cannot accept
1913              * focus, nothing will happen.  Otherwise, the object will attempt
1914              * to take focus.
1915              * @see #isFocusTraversable
1916              */
requestFocus()1917             public void requestFocus() {
1918                 // nothing to do; a no-op
1919             }
1920 
1921             /**
1922              * Adds the specified focus listener to receive focus events from
1923              * this component.
1924              *
1925              * @param l the focus listener
1926              * @see #removeFocusListener
1927              */
addFocusListener(FocusListener l)1928             public void addFocusListener(FocusListener l) {
1929                 // nothing to do; a no-op
1930             }
1931 
1932             /**
1933              * Removes the specified focus listener so it no longer receives
1934              * focus events from this component.
1935              *
1936              * @param l the focus listener
1937              * @see #addFocusListener
1938              */
removeFocusListener(FocusListener l)1939             public void removeFocusListener(FocusListener l) {
1940                 // nothing to do; a no-op
1941             }
1942 
1943 
1944 
1945         } // inner class AccessibleAWTListChild
1946 
1947     } // inner class AccessibleAWTList
1948 
1949 }
1950