OSDN Git Service

2005-02-15 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / List.java
1 /* List.java -- A listbox widget
2    Copyright (C) 1999, 2002, 2004  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.awt;
40
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.ItemEvent;
44 import java.awt.event.ItemListener;
45 import java.awt.peer.ListPeer;
46 import java.util.EventListener;
47 import java.util.Vector;
48
49 import javax.accessibility.Accessible;
50 import javax.accessibility.AccessibleContext;
51 import javax.accessibility.AccessibleRole;
52 import javax.accessibility.AccessibleSelection;
53 import javax.accessibility.AccessibleState;
54 import javax.accessibility.AccessibleStateSet;
55
56 /**
57   * Class that implements a listbox widget
58   *
59   * @author Aaron M. Renn (arenn@urbanophile.com)
60   */
61 public class List extends Component
62   implements ItemSelectable, Accessible
63 {
64
65 /*
66  * Static Variables
67  */
68
69 // Serialization constant
70 private static final long serialVersionUID = -3304312411574666869L;
71
72 /*************************************************************************/
73
74 /*
75  * Instance Variables
76  */
77
78 // FIXME: Need read/writeObject
79
80 /**
81   * @serial The items in the list.
82   */
83 private Vector items = new Vector();
84
85 /**
86   * @serial Indicates whether or not multiple items can be selected
87   * simultaneously.
88   */
89 private boolean multipleMode;
90
91 /**
92   * @serial The number of rows in the list.  This is set on creation
93   * only and cannot be modified.
94   */
95 private int rows;
96
97 /**
98   * @serial An array of the item indices that are selected.
99   */
100 private int[] selected;
101
102 /**
103   * @serial An index value used by <code>makeVisible()</code> and
104   * <code>getVisibleIndex</code>.
105   */
106 private int visibleIndex;
107
108 // The list of ItemListeners for this object.
109 private ItemListener item_listeners;
110
111 // The list of ActionListeners for this object.
112 private ActionListener action_listeners;
113
114
115 /*************************************************************************/
116
117 /*
118  * Constructors
119  */
120
121 /**
122   * Initializes a new instance of <code>List</code> with no visible lines
123   * and multi-select disabled.
124   *
125   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
126   */
127 public
128 List()
129 {
130   this(4, false);
131 }
132
133 /*************************************************************************/
134
135 /**
136   * Initializes a new instance of <code>List</code> with the specified
137   * number of visible lines and multi-select disabled.
138   *
139   * @param rows The number of visible rows in the list.
140   *
141   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
142   */
143 public
144 List(int rows)
145 {
146   this(rows, false);
147 }
148
149 /*************************************************************************/
150
151 /**
152   * Initializes a new instance of <code>List</code> with the specified
153   * number of lines and the specified multi-select setting.
154   *
155   * @param rows The number of visible rows in the list.
156   * @param multipleMode <code>true</code> if multiple lines can be selected
157   * simultaneously, <code>false</code> otherwise.
158   *
159   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
160   */
161 public 
162 List(int rows, boolean multipleMode)
163 {
164   this.rows = rows;
165   this.multipleMode = multipleMode;
166
167   if (GraphicsEnvironment.isHeadless())
168     throw new HeadlessException ();
169 }
170
171 /*************************************************************************/
172
173 /*
174  * Instance Variables
175  */
176
177 /**
178   * Returns the number of items in this list.
179   *
180   * @return The number of items in this list.
181   */
182 public int
183 getItemCount()
184 {
185   return countItems ();
186 }
187
188 /*************************************************************************/
189
190 /**
191   * Returns the number of items in this list.
192   *
193   * @return The number of items in this list.
194   *
195   * @deprecated This method is deprecated in favor of
196   * <code>getItemCount()</code>
197   */
198 public int
199 countItems()
200 {
201   return items.size ();
202 }
203
204 /*************************************************************************/
205
206 /**
207   * Returns the complete list of items.
208   *
209   * @return The complete list of items in the list.
210   */
211 public synchronized String[]
212 getItems()
213 {
214   String[] l_items = new String[getItemCount()];
215  
216   items.copyInto(l_items);
217   return(l_items);
218 }
219
220 /*************************************************************************/
221
222 /**
223   * Returns the item at the specified index.
224   *
225   * @param index The index of the item to retrieve.
226   *
227   * @exception IndexOutOfBoundsException If the index value is not valid.
228   */
229 public String
230 getItem(int index)
231 {
232   return((String)items.elementAt(index));
233 }
234
235 /*************************************************************************/
236
237 /**
238   * Returns the number of visible rows in the list.
239   *
240   * @return The number of visible rows in the list.
241   */
242 public int
243 getRows()
244 {
245   return(rows);
246 }
247
248 /*************************************************************************/
249
250 /**
251   * Tests whether or not multi-select mode is enabled.
252   *
253   * @return <code>true</code> if multi-select mode is enabled,
254   * <code>false</code> otherwise.
255   */
256 public boolean
257 isMultipleMode()
258 {
259   return allowsMultipleSelections ();
260 }
261
262 /*************************************************************************/
263
264 /**
265   * Tests whether or not multi-select mode is enabled.
266   *
267   * @return <code>true</code> if multi-select mode is enabled,
268   * <code>false</code> otherwise.
269   *
270   * @deprecated This method is deprecated in favor of 
271   * <code>isMultipleMode()</code>.
272   */
273 public boolean
274 allowsMultipleSelections()
275 {
276   return multipleMode;
277 }
278
279 /*************************************************************************/
280
281 /**
282   * This method enables or disables multiple selection mode for this
283   * list.
284   *
285   * @param multipleMode <code>true</code> to enable multiple mode,
286   * <code>false</code> otherwise.
287   */
288 public void
289 setMultipleMode(boolean multipleMode)
290 {
291   setMultipleSelections (multipleMode);
292 }
293
294 /*************************************************************************/
295
296 /**
297   * This method enables or disables multiple selection mode for this
298   * list.
299   *
300   * @param multipleMode <code>true</code> to enable multiple mode,
301   * <code>false</code> otherwise.
302   *
303   * @deprecated
304   */
305 public void
306 setMultipleSelections(boolean multipleMode)
307 {
308   this.multipleMode = multipleMode;
309
310   ListPeer peer = (ListPeer) getPeer ();
311   if (peer != null)
312     peer.setMultipleMode (multipleMode);
313 }
314
315 /*************************************************************************/
316
317 /**
318   * Returns the minimum size of this component.
319   *
320   * @return The minimum size of this component.
321   */
322 public Dimension
323 getMinimumSize()
324 {
325   return getMinimumSize (getRows ());
326 }
327
328 /*************************************************************************/
329
330 /**
331   * Returns the minimum size of this component.
332   *
333   * @return The minimum size of this component.
334   *
335   * @deprecated This method is deprecated in favor of
336   * <code>getMinimumSize</code>.
337   */
338 public Dimension
339 minimumSize()
340 {
341   return minimumSize (getRows ());
342 }
343
344 /*************************************************************************/
345
346 /**
347   * Returns the minimum size of this component assuming it had the specified
348   * number of rows.
349   *
350   * @param rows The number of rows to size for.
351   *
352   * @return The minimum size of this component.
353   */
354 public Dimension
355 getMinimumSize(int rows)
356 {
357   return minimumSize (rows);
358 }
359
360 /*************************************************************************/
361
362 /**
363   * Returns the minimum size of this component assuming it had the specified
364   * number of rows.
365   *
366   * @param rows The number of rows to size for.
367   *
368   * @return The minimum size of this component.
369   *
370   * @deprecated This method is deprecated in favor of 
371   * <code>getMinimumSize(int)</code>>
372   */
373 public Dimension
374 minimumSize(int rows)
375 {
376   ListPeer peer = (ListPeer) getPeer ();
377   if (peer != null)
378     return peer.minimumSize (rows);
379   else
380     return new Dimension (0, 0);
381 }
382
383 /*************************************************************************/
384
385 /**
386   * Returns the preferred size of this component.
387   *
388   * @return The preferred size of this component.
389   */
390 public Dimension
391 getPreferredSize()
392 {
393   return getPreferredSize (getRows ());
394 }
395
396 /*************************************************************************/
397
398 /**
399   * Returns the preferred size of this component.
400   *
401   * @return The preferred size of this component.
402   *
403   * @deprecated This method is deprecated in favor of
404   * <code>getPreferredSize</code>.
405   */
406 public Dimension
407 preferredSize()
408 {
409   return preferredSize (getRows ());
410 }
411
412 /*************************************************************************/
413
414 /**
415   * Returns the preferred size of this component assuming it had the specified
416   * number of rows.
417   *
418   * @param rows The number of rows to size for.
419   *
420   * @return The preferred size of this component.
421   */
422 public Dimension
423 getPreferredSize(int rows)
424 {
425   return preferredSize (rows);
426 }
427
428 /*************************************************************************/
429
430 /**
431   * Returns the preferred size of this component assuming it had the specified
432   * number of rows.
433   *
434   * @param rows The number of rows to size for.
435   *
436   * @return The preferred size of this component.
437   *
438   * @deprecated This method is deprecated in favor of 
439   * <code>getPreferredSize(int)</code>>
440   */
441 public Dimension
442 preferredSize(int rows)
443 {
444   ListPeer peer = (ListPeer) getPeer ();
445   if (peer != null)
446     return peer.preferredSize (rows);
447   else
448     return new Dimension (0, 0);
449 }
450
451 /*************************************************************************/
452
453 /**
454   * This method adds the specified item to the end of the list.
455   *
456   * @param item The item to add to the list.
457   */
458 public void
459 add(String item)
460 {
461   add (item, -1);
462 }
463
464 /*************************************************************************/
465
466 /**
467   * This method adds the specified item to the end of the list.
468   *
469   * @param item The item to add to the list.
470   *
471   * @deprecated Use add() instead.
472   */
473 public void
474 addItem(String item)
475 {
476   addItem (item, -1);
477 }
478
479 /*************************************************************************/
480
481 /**
482   * Adds the specified item to the specified location in the list.
483   * If the desired index is -1 or greater than the number of rows
484   * in the list, then the item is added to the end.
485   *
486   * @param item The item to add to the list.
487   * @param index The location in the list to add the item, or -1 to add
488   * to the end.
489   */
490 public void
491 add(String item, int index)
492 {
493   addItem (item, index);
494 }
495
496 /*************************************************************************/
497
498 /**
499   * Adds the specified item to the specified location in the list.
500   * If the desired index is -1 or greater than the number of rows
501   * in the list, then the item is added to the end.
502   *
503   * @param item The item to add to the list.
504   * @param index The location in the list to add the item, or -1 to add
505   * to the end.
506   *
507   * @deprecated Use add() instead.
508   */
509 public void
510 addItem(String item, int index)
511 {
512   if ((index == -1) || (index >= items.size ()))
513     items.addElement (item);
514   else
515     items.insertElementAt (item, index);
516
517   ListPeer peer = (ListPeer) getPeer ();
518   if (peer != null)
519     peer.add (item, index);
520 }
521
522 /*************************************************************************/
523
524 /**
525   * Deletes the item at the specified index.
526   *
527   * @param index The index of the item to delete.
528   *
529   * @exception IllegalArgumentException If the index is not valid
530   *
531   * @deprecated
532   */
533 public void
534 delItem(int index) throws IllegalArgumentException
535 {
536   items.removeElementAt (index);
537
538   ListPeer peer = (ListPeer) getPeer ();
539   if (peer != null)
540     peer.delItems (index, index);
541 }
542
543 /*************************************************************************/
544
545 /**
546   * Deletes the item at the specified index.
547   *
548   * @param index The index of the item to delete.
549   *
550   * @exception IllegalArgumentException If the index is not valid
551   */
552 public void
553 remove(int index) throws IllegalArgumentException
554 {
555   delItem (index);
556 }
557
558 /*************************************************************************/
559
560 /**
561   * Deletes all items in the specified index range.
562   *
563   * @param start The beginning index of the range to delete.
564   * @param end The ending index of the range to delete.
565   *
566   * @exception IllegalArgumentException If the indexes are not valid
567   *
568   * @deprecated This method is deprecated for some unknown reason.
569   */
570 public synchronized void
571 delItems(int start, int end) throws IllegalArgumentException
572 {
573   if ((start < 0) || (start >= items.size()))
574     throw new IllegalArgumentException("Bad list start index value: " + start);
575
576   if ((start < 0) || (start >= items.size()))
577     throw new IllegalArgumentException("Bad list start index value: " + start);
578
579   if (start > end)
580     throw new IllegalArgumentException("Start is greater than end!");
581
582   // We must run the loop in reverse direction.
583   for (int i = end; i >= start; --i)
584     items.removeElementAt (i);
585   if (peer != null)
586     {
587       ListPeer l = (ListPeer) peer;
588       l.delItems (start, end);
589     }
590 }
591
592 /*************************************************************************/
593
594 /**
595   * Deletes the first occurrence of the specified item from the list.
596   *
597   * @param item The item to delete.
598   *
599   * @exception IllegalArgumentException If the specified item does not exist.
600   */
601 public synchronized void
602 remove(String item) throws IllegalArgumentException
603 {
604   int index = items.indexOf(item);
605   if (index == -1)
606     throw new IllegalArgumentException("List element to delete not found");
607
608   remove(index);
609 }
610
611 /*************************************************************************/
612
613 /**
614   * Deletes all of the items from the list.
615   */
616 public synchronized void
617 removeAll()
618 {
619   clear ();
620 }
621
622 /*************************************************************************/
623
624 /**
625   * Deletes all of the items from the list.
626   * 
627   * @deprecated This method is deprecated in favor of <code>removeAll()</code>.
628   */
629 public void
630 clear()
631 {
632   items.clear();
633
634   ListPeer peer = (ListPeer) getPeer ();
635   if (peer != null)
636     peer.removeAll ();
637 }
638
639 /*************************************************************************/
640
641 /**
642   * Replaces the item at the specified index with the specified item.
643   *
644   * @param item The new item value.
645   * @param index The index of the item to replace.
646   *
647   * @exception IllegalArgumentException If the index is not valid.
648   */
649 public synchronized void
650 replaceItem(String item, int index) throws IllegalArgumentException
651 {
652   if ((index < 0) || (index >= items.size()))
653     throw new IllegalArgumentException("Bad list index: " + index);
654
655   items.insertElementAt(item, index + 1);
656   items.removeElementAt (index);
657
658   if (peer != null)
659     {
660       ListPeer l = (ListPeer) peer;
661
662       /* We add first and then remove so that the selected
663          item remains the same */
664       l.add (item, index + 1);
665       l.delItems (index, index);
666     }
667 }
668
669 /*************************************************************************/
670
671 /**
672   * Returns the index of the currently selected item.  -1 will be returned
673   * if there are no selected rows or if there are multiple selected rows.
674   *
675   * @return The index of the selected row.
676   */
677 public synchronized int
678 getSelectedIndex()
679 {
680   if (peer != null)
681     {
682       ListPeer l = (ListPeer) peer;
683       selected = l.getSelectedIndexes ();
684     }
685
686   if (selected == null || selected.length != 1)
687     return -1;
688   return selected[0];
689 }
690
691 /*************************************************************************/
692
693 /**
694   * Returns an array containing the indexes of the rows that are 
695   * currently selected.
696   *
697   * @return A list of indexes of selected rows.
698   */
699 public synchronized int[]
700 getSelectedIndexes()
701 {
702   if (peer != null)
703     {
704       ListPeer l = (ListPeer) peer;
705       selected = l.getSelectedIndexes ();
706     }
707   return selected;
708 }
709
710 /*************************************************************************/
711
712 /**
713   * Returns the item that is currently selected, or <code>null</code> if there 
714   * is no item selected.  FIXME: What happens if multiple items selected?
715   *
716   * @return The selected item, or <code>null</code> if there is no
717   * selected item.
718   */
719 public synchronized String
720 getSelectedItem()
721 {
722   int index = getSelectedIndex();
723   if (index == -1)
724     return(null);
725
726   return((String)items.elementAt(index));
727 }
728
729 /*************************************************************************/
730
731 /**
732   * Returns the list of items that are currently selected in this list.
733   *
734   * @return The list of currently selected items.
735   */
736 public synchronized String[]
737 getSelectedItems()
738 {
739   int[] indexes = getSelectedIndexes();
740   if (indexes == null)
741     return(new String[0]);
742
743   String[] retvals = new String[indexes.length];
744   if (retvals.length > 0)
745     for (int i = 0 ; i < retvals.length; i++)
746        retvals[i] = (String)items.elementAt(indexes[i]);
747
748   return(retvals);
749 }
750
751 /*************************************************************************/
752
753 /**
754   * Returns the list of items that are currently selected in this list as
755   * an array of type <code>Object[]</code> instead of <code>String[]</code>.
756   *
757   * @return The list of currently selected items.
758   */
759 public synchronized Object[]
760 getSelectedObjects()
761 {
762   int[] indexes = getSelectedIndexes();
763   if (indexes == null)
764     return(new Object[0]);
765
766   Object[] retvals = new Object[indexes.length];
767   if (retvals.length > 0)
768     for (int i = 0 ; i < retvals.length; i++)
769        retvals[i] = items.elementAt(indexes[i]);
770
771   return(retvals);
772 }
773
774 /*************************************************************************/
775
776 /**
777   * Tests whether or not the specified index is selected.
778   *
779   * @param index The index to test.
780   *
781   * @return <code>true</code> if the index is selected, <code>false</code>
782   * otherwise.
783   */
784 public boolean
785 isIndexSelected(int index)
786 {
787   return isSelected (index);
788 }
789
790 /*************************************************************************/
791
792 /**
793   * Tests whether or not the specified index is selected.
794   *
795   * @param index The index to test.
796   *
797   * @return <code>true</code> if the index is selected, <code>false</code>
798   * otherwise.
799   *
800   * @deprecated This method is deprecated in favor of
801   * <code>isIndexSelected(int)</code>.
802   */
803 public boolean
804 isSelected(int index)
805 {
806   int[] indexes = getSelectedIndexes ();
807
808   for (int i = 0; i < indexes.length; i++)
809     if (indexes[i] == index)
810       return true;
811
812   return false;
813 }
814
815 /*************************************************************************/
816
817 /**
818   * This method ensures that the item at the specified index is visible.
819   *
820   * @exception IllegalArgumentException If the specified index is out of
821   * range.
822   */
823 public synchronized void
824 makeVisible(int index) throws IllegalArgumentException
825 {
826   if ((index < 0) || (index >= items.size()))
827     throw new IllegalArgumentException("Bad list index: " + index);
828
829   visibleIndex = index;
830   if (peer != null)
831     {
832       ListPeer l = (ListPeer) peer;
833       l.makeVisible (index);
834     }
835 }
836
837 /*************************************************************************/
838
839 /**
840   * Returns the index of the last item that was made visible via the
841   * <code>makeVisible()</code> method.
842   *
843   * @return The index of the last item made visible via the 
844   * <code>makeVisible()</code> method.
845   */
846 public int
847 getVisibleIndex()
848 {
849   return(visibleIndex);
850 }
851
852 /*************************************************************************/
853
854 /**
855   * Makes the item at the specified index selected.
856   *
857   * @param index The index of the item to select.
858   */
859 public synchronized void
860 select(int index)
861 {
862   ListPeer lp = (ListPeer)getPeer();
863   if (lp != null)
864     lp.select(index);
865 }
866
867 /*************************************************************************/
868
869 /**
870   * Makes the item at the specified index not selected.
871   *
872   * @param index The index of the item to unselect.
873   */
874 public synchronized void
875 deselect(int index)
876 {
877   ListPeer lp = (ListPeer)getPeer();
878   if (lp != null)
879     lp.deselect(index);
880 }
881
882 /*************************************************************************/
883
884 /**
885   * Notifies this object to create its native peer.
886   */
887 public void
888 addNotify()
889 {
890   if (peer == null)
891     peer = getToolkit ().createList (this);
892   super.addNotify ();
893 }
894
895 /*************************************************************************/
896
897 /**
898   * Notifies this object to destroy its native peer.
899   */
900 public void
901 removeNotify()
902 {
903   super.removeNotify();
904 }
905
906 /*************************************************************************/
907
908 /**
909   * Adds the specified <code>ActionListener</code> to the list of
910   * registered listeners for this object.
911   *
912   * @param listener The listener to add.
913   */
914 public synchronized void
915 addActionListener(ActionListener listener)
916 {
917   action_listeners = AWTEventMulticaster.add(action_listeners, listener);
918 }
919
920 /*************************************************************************/
921
922 /**
923   * Removes the specified <code>ActionListener</code> from the list of
924   * registers listeners for this object.
925   *
926   * @param listener The listener to remove.
927   */
928 public synchronized void
929 removeActionListener(ActionListener listener)
930 {
931   action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
932 }
933
934 /*************************************************************************/
935
936 /**
937   * Adds the specified <code>ItemListener</code> to the list of
938   * registered listeners for this object.
939   *
940   * @param listener The listener to add.
941   */
942 public synchronized void
943 addItemListener(ItemListener listener)
944 {
945   item_listeners = AWTEventMulticaster.add(item_listeners, listener);
946 }
947
948 /*************************************************************************/
949
950 /**
951   * Removes the specified <code>ItemListener</code> from the list of
952   * registers listeners for this object.
953   *
954   * @param listener The listener to remove.
955   */
956 public synchronized void
957 removeItemListener(ItemListener listener)
958 {
959   item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
960 }
961
962 /*************************************************************************/
963
964 /**
965   * Processes the specified event for this object.  If the event is an
966   * instance of <code>ActionEvent</code> then the
967   * <code>processActionEvent()</code> method is called.  Similarly, if the
968   * even is an instance of <code>ItemEvent</code> then the
969   * <code>processItemEvent()</code> method is called.  Otherwise the
970   * superclass method is called to process this event.
971   *
972   * @param event The event to process.
973   */
974 protected void
975 processEvent(AWTEvent event)
976 {
977   if (event instanceof ActionEvent)
978     processActionEvent((ActionEvent)event);
979   else if (event instanceof ItemEvent)
980     processItemEvent((ItemEvent)event);
981   else
982     super.processEvent(event);
983 }
984
985 /*************************************************************************/
986
987 /**
988   * This method processes the specified event by dispatching it to any
989   * registered listeners.  Note that this method will only get called if
990   * action events are enabled.  This will happen automatically if any
991   * listeners are added, or it can be done "manually" by calling
992   * the <code>enableEvents()</code> method.
993   *
994   * @param event The event to process.
995   */
996 protected void 
997 processActionEvent(ActionEvent event)
998 {
999   if (action_listeners != null)
1000     action_listeners.actionPerformed(event);
1001 }
1002
1003 /*************************************************************************/
1004
1005 /**
1006   * This method processes the specified event by dispatching it to any
1007   * registered listeners.  Note that this method will only get called if
1008   * item events are enabled.  This will happen automatically if any
1009   * listeners are added, or it can be done "manually" by calling
1010   * the <code>enableEvents()</code> method.
1011   *
1012   * @param event The event to process.
1013   */
1014 protected void 
1015 processItemEvent(ItemEvent event)
1016 {
1017   if (item_listeners != null)
1018     item_listeners.itemStateChanged(event);
1019 }
1020
1021 void
1022 dispatchEventImpl(AWTEvent e)
1023 {
1024   if (e.id <= ItemEvent.ITEM_LAST
1025       && e.id >= ItemEvent.ITEM_FIRST
1026       && (item_listeners != null 
1027           || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
1028     processEvent(e);
1029   else if (e.id <= ActionEvent.ACTION_LAST 
1030            && e.id >= ActionEvent.ACTION_FIRST
1031            && (action_listeners != null 
1032                || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
1033     processEvent(e);
1034   else
1035     super.dispatchEventImpl(e);
1036 }
1037
1038 /*************************************************************************/
1039
1040 /**
1041   * Returns a debugging string for this object.
1042   *
1043   * @return A debugging string for this object.
1044   */
1045 protected String
1046 paramString()
1047 {
1048   return "multiple=" + multipleMode + ",rows=" + rows + super.paramString();
1049 }
1050
1051   /**
1052    * Returns an array of all the objects currently registered as FooListeners
1053    * upon this <code>List</code>. FooListeners are registered using the 
1054    * addFooListener method.
1055    *
1056    * @exception ClassCastException If listenerType doesn't specify a class or
1057    * interface that implements java.util.EventListener.
1058    */
1059   public EventListener[] getListeners (Class listenerType)
1060   {
1061     if (listenerType == ActionListener.class)
1062       return AWTEventMulticaster.getListeners (action_listeners, listenerType);
1063     
1064     if (listenerType == ItemListener.class)
1065       return AWTEventMulticaster.getListeners (item_listeners, listenerType);
1066
1067     return super.getListeners (listenerType);
1068   }
1069
1070   /**
1071    * Returns all action listeners registered to this object.
1072    */
1073   public ActionListener[] getActionListeners ()
1074   {
1075     return (ActionListener[]) getListeners (ActionListener.class);
1076   }
1077   
1078   /**
1079    * Returns all action listeners registered to this object.
1080    */
1081   public ItemListener[] getItemListeners ()
1082   {
1083     return (ItemListener[]) getListeners (ItemListener.class);
1084   }
1085   
1086   // Accessibility internal class 
1087   protected class AccessibleAWTList extends AccessibleAWTComponent
1088     implements AccessibleSelection, ItemListener, ActionListener
1089   {
1090     protected class AccessibleAWTListChild extends AccessibleAWTComponent
1091       implements Accessible
1092     {
1093       private int index;
1094       private List parent;
1095       
1096       public AccessibleAWTListChild(List parent, int indexInParent)
1097       {
1098         this.parent = parent;
1099         index = indexInParent;
1100         if (parent == null)
1101           index = -1;
1102       }
1103       
1104       /* (non-Javadoc)
1105        * @see javax.accessibility.Accessible#getAccessibleContext()
1106        */
1107       public AccessibleContext getAccessibleContext()
1108       {
1109         return this;
1110       }
1111       
1112       public AccessibleRole getAccessibleRole()
1113       {
1114         return AccessibleRole.LIST_ITEM;
1115       }
1116       
1117       public AccessibleStateSet getAccessibleStateSet()
1118       {
1119         AccessibleStateSet states = super.getAccessibleStateSet();
1120         if (parent.isIndexSelected(index))
1121           states.add(AccessibleState.SELECTED);
1122         return states;
1123       }
1124       
1125       public int getAccessibleIndexInParent()
1126       {
1127         return index;
1128       }
1129
1130     }
1131     
1132     public AccessibleAWTList()
1133     {
1134       addItemListener(this);
1135       addActionListener(this);
1136     }
1137     
1138     public AccessibleRole getAccessibleRole()
1139     {
1140       return AccessibleRole.LIST;
1141     }
1142     
1143     public AccessibleStateSet getAccessibleStateSet()
1144     {
1145       AccessibleStateSet states = super.getAccessibleStateSet();
1146       states.add(AccessibleState.SELECTABLE);
1147       if (isMultipleMode())
1148         states.add(AccessibleState.MULTISELECTABLE);
1149       return states;
1150     }
1151
1152     public int getAccessibleChildrenCount()
1153     {
1154       return getItemCount();
1155     }
1156
1157     public Accessible getAccessibleChild(int i)
1158     {
1159       if (i >= getItemCount())
1160         return null;
1161       return new AccessibleAWTListChild(List.this, i);
1162     }
1163     
1164     /* (non-Javadoc)
1165      * @see javax.accessibility.AccessibleSelection#getAccessibleSelectionCount()
1166      */
1167     public int getAccessibleSelectionCount()
1168     {
1169       return getSelectedIndexes().length;
1170     }
1171
1172     /* (non-Javadoc)
1173      * @see javax.accessibility.AccessibleSelection#getAccessibleSelection()
1174      */
1175     public AccessibleSelection getAccessibleSelection()
1176     {
1177       return this;
1178     }
1179
1180     /* (non-Javadoc)
1181      * @see javax.accessibility.AccessibleSelection#getAccessibleSelection(int)
1182      */
1183     public Accessible getAccessibleSelection(int i)
1184     {
1185       int[] items = getSelectedIndexes();
1186       if (i >= items.length)
1187         return null;
1188       return new AccessibleAWTListChild(List.this, items[i]);
1189     }
1190
1191     /* (non-Javadoc)
1192      * @see javax.accessibility.AccessibleSelection#isAccessibleChildSelected(int)
1193      */
1194     public boolean isAccessibleChildSelected(int i)
1195     {
1196       return isIndexSelected(i);
1197     }
1198
1199     /* (non-Javadoc)
1200      * @see javax.accessibility.AccessibleSelection#addAccessibleSelection(int)
1201      */
1202     public void addAccessibleSelection(int i)
1203     {
1204       select(i);
1205     }
1206
1207     /* (non-Javadoc)
1208      * @see javax.accessibility.AccessibleSelection#removeAccessibleSelection(int)
1209      */
1210     public void removeAccessibleSelection(int i)
1211     {
1212       deselect(i);
1213     }
1214
1215     /* (non-Javadoc)
1216      * @see javax.accessibility.AccessibleSelection#clearAccessibleSelection()
1217      */
1218     public void clearAccessibleSelection()
1219     {
1220       for (int i = 0; i < getItemCount(); i++)
1221         deselect(i);
1222     }
1223
1224     /* (non-Javadoc)
1225      * @see javax.accessibility.AccessibleSelection#selectAllAccessibleSelection()
1226      */
1227     public void selectAllAccessibleSelection()
1228     {
1229       if (isMultipleMode())
1230         for (int i = 0; i < getItemCount(); i++)
1231           select(i);
1232     }
1233
1234     /* (non-Javadoc)
1235      * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
1236      */
1237     public void itemStateChanged(ItemEvent event)
1238     {
1239     }
1240
1241     /* (non-Javadoc)
1242      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
1243      */
1244     public void actionPerformed(ActionEvent event)
1245     {
1246     }
1247     
1248   }
1249
1250   /**
1251    * Gets the AccessibleContext associated with this <code>List</code>.
1252    * The context is created, if necessary.
1253    *
1254    * @return the associated context
1255    */
1256   public AccessibleContext getAccessibleContext()
1257   {
1258     /* Create the context if this is the first request */
1259     if (accessibleContext == null)
1260       accessibleContext = new AccessibleAWTList();
1261     return accessibleContext;
1262   }
1263 } // class List