1 /* List.java -- A listbox widget
2 Copyright (C) 1999, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
41 import java
.io
.Serializable
;
42 import java
.awt
.event
.ActionEvent
;
43 import java
.awt
.event
.ActionListener
;
44 import java
.awt
.event
.ItemEvent
;
45 import java
.awt
.event
.ItemListener
;
46 import java
.awt
.peer
.ListPeer
;
47 import java
.awt
.peer
.ComponentPeer
;
48 import java
.util
.EventListener
;
49 import java
.util
.Vector
;
50 import javax
.accessibility
.Accessible
;
53 * Class that implements a listbox widget
55 * @author Aaron M. Renn (arenn@urbanophile.com)
57 public class List
extends Component
58 implements ItemSelectable
, Accessible
65 // Serialization constant
66 private static final long serialVersionUID
= -3304312411574666869L;
68 /*************************************************************************/
74 // FIXME: Need read/writeObject
77 * @serial The items in the list.
79 private Vector items
= new Vector();
82 * @serial Indicates whether or not multiple items can be selected
85 private boolean multipleMode
;
88 * @serial The number of rows in the list. This is set on creation
89 * only and cannot be modified.
94 * @serial An array of the item indices that are selected.
96 private int[] selected
;
99 * @serial An index value used by <code>makeVisible()</code> and
100 * <code>getVisibleIndex</code>.
102 private int visibleIndex
;
104 // The list of ItemListeners for this object.
105 private ItemListener item_listeners
;
107 // The list of ActionListeners for this object.
108 private ActionListener action_listeners
;
110 /*************************************************************************/
117 * Initializes a new instance of <code>List</code> with no visible lines
118 * and multi-select disabled.
120 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
128 /*************************************************************************/
131 * Initializes a new instance of <code>List</code> with the specified
132 * number of visible lines and multi-select disabled.
134 * @param lines The number of visible lines in the list.
136 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
144 /*************************************************************************/
147 * Initializes a new instance of <code>List</code> with the specified
148 * number of lines and the specified multi-select setting.
150 * @param lines The number of visible lines in the list.
151 * @param multipleMode <code>true</code> if multiple lines can be selected
152 * simultaneously, <code>false</code> otherwise.
154 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
157 List(int rows
, boolean multipleMode
)
160 this.multipleMode
= multipleMode
;
162 if (GraphicsEnvironment
.isHeadless())
163 throw new HeadlessException ();
166 /*************************************************************************/
173 * Returns the number of items in this list.
175 * @return The number of items in this list.
180 return(items
.size());
183 /*************************************************************************/
186 * Returns the number of items in this list.
188 * @return The number of items in this list.
190 * @deprecated This method is deprecated in favor of
191 * <code>getItemCount()</code>
196 return(getItemCount());
199 /*************************************************************************/
202 * Returns the complete list of items.
204 * @return The complete list of items in the list.
206 public synchronized String
[]
209 String
[] l_items
= new String
[getItemCount()];
211 items
.copyInto(l_items
);
215 /*************************************************************************/
218 * Returns the item at the specified index.
220 * @param index The index of the item to retrieve.
222 * @exception IndexOutOfBoundsException If the index value is not valid.
227 return((String
)items
.elementAt(index
));
230 /*************************************************************************/
233 * Returns the number of visible rows in the list.
235 * @return The number of visible rows in the list.
243 /*************************************************************************/
246 * Tests whether or not multi-select mode is enabled.
248 * @return <code>true</code> if multi-select mode is enabled,
249 * <code>false</code> otherwise.
254 return(multipleMode
);
257 /*************************************************************************/
260 * Tests whether or not multi-select mode is enabled.
262 * @return <code>true</code> if multi-select mode is enabled,
263 * <code>false</code> otherwise.
265 * @deprecated This method is deprecated in favor of
266 * <code>isMultipleMode()</code>.
269 allowsMultipleSelections()
271 return(multipleMode
);
274 /*************************************************************************/
277 * This method enables or disables multiple selection mode for this
280 * @param multipleMode <code>true</code> to enable multiple mode,
281 * <code>false</code> otherwise.
284 setMultipleMode(boolean multipleMode
)
286 this.multipleMode
= multipleMode
;
289 ListPeer l
= (ListPeer
) peer
;
290 l
.setMultipleMode (multipleMode
);
294 /*************************************************************************/
297 * This method enables or disables multiple selection mode for this
300 * @param multipleMode <code>true</code> to enable multiple mode,
301 * <code>false</code> otherwise.
304 setMultipleSelections(boolean multipleMode
)
306 setMultipleMode(multipleMode
);
309 /*************************************************************************/
312 * Returns the minimum size of this component.
314 * @return The minimum size of this component.
319 return(getMinimumSize(rows
));
322 /*************************************************************************/
325 * Returns the minimum size of this component.
327 * @return The minimum size of this component.
329 * @deprecated This method is deprecated in favor of
330 * <code>getMinimumSize</code>.
335 return(getMinimumSize(rows
));
338 /*************************************************************************/
341 * Returns the minimum size of this component assuming it had the specified
344 * @param rows The number of rows to size for.
346 * @return The minimum size of this component.
349 getMinimumSize(int rows
)
351 ListPeer lp
= (ListPeer
)getPeer();
353 return(lp
.minimumSize(rows
));
355 return(new Dimension(0,0));
358 /*************************************************************************/
361 * Returns the minimum size of this component assuming it had the specified
364 * @param rows The number of rows to size for.
366 * @return The minimum size of this component.
368 * @deprecated This method is deprecated in favor of
369 * <code>getMinimumSize(int)</code>>
372 minimumSize(int rows
)
374 return(getMinimumSize(rows
));
377 /*************************************************************************/
380 * Returns the preferred size of this component.
382 * @return The preferred size of this component.
387 return(getPreferredSize(rows
));
390 /*************************************************************************/
393 * Returns the preferred size of this component.
395 * @return The preferred size of this component.
397 * @deprecated This method is deprecated in favor of
398 * <code>getPreferredSize</code>.
403 return(getPreferredSize(rows
));
406 /*************************************************************************/
409 * Returns the preferred size of this component assuming it had the specified
412 * @param rows The number of rows to size for.
414 * @return The preferred size of this component.
417 getPreferredSize(int rows
)
419 ListPeer lp
= (ListPeer
)getPeer();
421 return(lp
.preferredSize(rows
));
423 return(new Dimension(0,0));
426 /*************************************************************************/
429 * Returns the preferred size of this component assuming it had the specified
432 * @param rows The number of rows to size for.
434 * @return The preferred size of this component.
436 * @deprecated This method is deprecated in favor of
437 * <code>getPreferredSize(int)</code>>
440 preferredSize(int rows
)
442 return(getPreferredSize(rows
));
445 /*************************************************************************/
448 * This method adds the specified item to the end of the list.
450 * @param item The item to add to the list.
458 /*************************************************************************/
461 * This method adds the specified item to the end of the list.
463 * @param item The item to add to the list.
465 * @deprecated Use add() instead.
473 /*************************************************************************/
476 * Adds the specified item to the specified location in the list.
477 * If the desired index is -1 or greater than the number of rows
478 * in the list, then the item is added to the end.
480 * @param item The item to add to the list.
481 * @param index The location in the list to add the item, or -1 to add
485 add(String item
, int index
)
487 if ((index
== -1) || (index
>= items
.size()))
488 items
.addElement(item
);
490 items
.insertElementAt(item
, index
);
494 ListPeer l
= (ListPeer
) peer
;
499 /*************************************************************************/
502 * Adds the specified item to the specified location in the list.
503 * If the desired index is -1 or greater than the number of rows
504 * in the list, then the item is added to the end.
506 * @param item The item to add to the list.
507 * @param index The location in the list to add the item, or -1 to add
510 * @deprecated Use add() instead.
513 addItem(String item
, int index
)
518 /*************************************************************************/
521 * Deletes the item at the specified index.
523 * @param index The index of the item to delete.
525 * @exception IllegalArgumentException If the index is not valid
528 delItem(int index
) throws IllegalArgumentException
533 /*************************************************************************/
536 * Deletes the item at the specified index.
538 * @param index The index of the item to delete.
540 * @exception IllegalArgumentException If the index is not valid
543 remove(int index
) throws IllegalArgumentException
545 items
.removeElementAt (index
);
548 ListPeer l
= (ListPeer
) peer
;
549 l
.delItems (index
, index
);
553 /*************************************************************************/
556 * Deletes all items in the specified index range.
558 * @param start The beginning index of the range to delete.
559 * @param end The ending index of the range to delete.
561 * @exception IllegalArgumentException If the indexes are not valid
563 * @deprecated This method is deprecated for some unknown reason.
565 public synchronized void
566 delItems(int start
, int end
) throws IllegalArgumentException
568 if ((start
< 0) || (start
>= items
.size()))
569 throw new IllegalArgumentException("Bad list start index value: " + start
);
571 if ((start
< 0) || (start
>= items
.size()))
572 throw new IllegalArgumentException("Bad list start index value: " + start
);
575 throw new IllegalArgumentException("Start is greater than end!");
577 // We must run the loop in reverse direction.
578 for (int i
= end
; i
>= start
; --i
)
579 items
.removeElementAt (i
);
582 ListPeer l
= (ListPeer
) peer
;
583 l
.delItems (start
, end
);
587 /*************************************************************************/
590 * Deletes the first occurrence of the specified item from the list.
592 * @param item The item to delete.
594 * @exception IllegalArgumentException If the specified item does not exist.
596 public synchronized void
597 remove(String item
) throws IllegalArgumentException
599 int index
= items
.indexOf(item
);
601 throw new IllegalArgumentException("List element to delete not found");
606 /*************************************************************************/
609 * Deletes all of the items from the list.
611 public synchronized void
617 ListPeer l
= (ListPeer
) peer
;
622 /*************************************************************************/
625 * Deletes all of the items from the list.
627 * @deprecated This method is deprecated in favor of <code>removeAll()</code>.
635 /*************************************************************************/
638 * Replaces the item at the specified index with the specified item.
640 * @param item The new item value.
641 * @param index The index of the item to replace.
643 * @exception IllegalArgumentException If the index is not valid.
645 public synchronized void
646 replaceItem(String item
, int index
) throws IllegalArgumentException
649 addItem(item
, index
);
652 /*************************************************************************/
655 * Returns the index of the currently selected item. -1 will be returned
656 * if there are no selected rows or if there are multiple selected rows.
658 * @return The index of the selected row.
660 public synchronized int
665 ListPeer l
= (ListPeer
) peer
;
666 selected
= l
.getSelectedIndexes ();
669 if (selected
== null || selected
.length
> 1)
674 /*************************************************************************/
677 * Returns an array containing the indexes of the rows that are
678 * currently selected.
680 * @return A list of indexes of selected rows.
682 public synchronized int[]
687 ListPeer l
= (ListPeer
) peer
;
688 selected
= l
.getSelectedIndexes ();
693 /*************************************************************************/
696 * Returns the item that is currently selected, or <code>null</code> if there
697 * is no item selected. FIXME: What happens if multiple items selected?
699 * @return The selected item, or <code>null</code> if there is no
702 public synchronized String
705 int index
= getSelectedIndex();
709 return((String
)items
.elementAt(index
));
712 /*************************************************************************/
715 * Returns the list of items that are currently selected in this list.
717 * @return The list of currently selected items.
719 public synchronized String
[]
722 int[] indexes
= getSelectedIndexes();
724 return(new String
[0]);
726 String
[] retvals
= new String
[indexes
.length
];
727 if (retvals
.length
> 0)
728 for (int i
= 0 ; i
< retvals
.length
; i
++)
729 retvals
[i
] = (String
)items
.elementAt(indexes
[i
]);
734 /*************************************************************************/
737 * Returns the list of items that are currently selected in this list as
738 * an array of type <code>Object[]</code> instead of <code>String[]</code>.
740 * @return The list of currently selected items.
742 public synchronized Object
[]
745 int[] indexes
= getSelectedIndexes();
747 return(new Object
[0]);
749 Object
[] retvals
= new Object
[indexes
.length
];
750 if (retvals
.length
> 0)
751 for (int i
= 0 ; i
< retvals
.length
; i
++)
752 retvals
[i
] = items
.elementAt(indexes
[i
]);
757 /*************************************************************************/
760 * Tests whether or not the specified index is selected.
762 * @param index The index to test.
764 * @return <code>true</code> if the index is selected, <code>false</code>
768 isIndexSelected(int index
)
770 int[] indexes
= getSelectedIndexes();
772 for (int i
= 0; i
< indexes
.length
; i
++)
773 if (indexes
[i
] == index
)
779 /*************************************************************************/
782 * Tests whether or not the specified index is selected.
784 * @param index The index to test.
786 * @return <code>true</code> if the index is selected, <code>false</code>
789 * @deprecated This method is deprecated in favor of
790 * <code>isIndexSelected(int)</code>.
793 isSelected(int index
)
795 return(isIndexSelected(index
));
798 /*************************************************************************/
801 * This method ensures that the item at the specified index is visible.
803 * @exception IllegalArgumentException If the specified index is out of
806 public synchronized void
807 makeVisible(int index
) throws IllegalArgumentException
809 if ((index
< 0) || (index
>= items
.size()))
810 throw new IllegalArgumentException("Bad list index: " + index
);
812 visibleIndex
= index
;
815 ListPeer l
= (ListPeer
) peer
;
816 l
.makeVisible (index
);
820 /*************************************************************************/
823 * Returns the index of the last item that was made visible via the
824 * <code>makeVisible()</code> method.
826 * @return The index of the last item made visible via the
827 * <code>makeVisible()</code> method.
832 return(visibleIndex
);
835 /*************************************************************************/
838 * Makes the item at the specified index selected.
840 * @param index The index of the item to select.
842 public synchronized void
845 ListPeer lp
= (ListPeer
)getPeer();
850 /*************************************************************************/
853 * Makes the item at the specified index not selected.
855 * @param index The index of the item to unselect.
857 public synchronized void
860 ListPeer lp
= (ListPeer
)getPeer();
865 /*************************************************************************/
868 * Notifies this object to create its native peer.
874 peer
= getToolkit ().createList (this);
878 /*************************************************************************/
881 * Notifies this object to destroy its native peer.
886 super.removeNotify();
889 /*************************************************************************/
892 * Adds the specified <code>ActionListener</code> to the list of
893 * registered listeners for this object.
895 * @param listener The listener to add.
897 public synchronized void
898 addActionListener(ActionListener listener
)
900 action_listeners
= AWTEventMulticaster
.add(action_listeners
, listener
);
903 /*************************************************************************/
906 * Removes the specified <code>ActionListener</code> from the list of
907 * registers listeners for this object.
909 * @param listener The listener to remove.
911 public synchronized void
912 removeActionListener(ActionListener listener
)
914 action_listeners
= AWTEventMulticaster
.remove(action_listeners
, listener
);
917 /*************************************************************************/
920 * Adds the specified <code>ItemListener</code> to the list of
921 * registered listeners for this object.
923 * @param listener The listener to add.
925 public synchronized void
926 addItemListener(ItemListener listener
)
928 item_listeners
= AWTEventMulticaster
.add(item_listeners
, listener
);
931 /*************************************************************************/
934 * Removes the specified <code>ItemListener</code> from the list of
935 * registers listeners for this object.
937 * @param listener The listener to remove.
939 public synchronized void
940 removeItemListener(ItemListener listener
)
942 item_listeners
= AWTEventMulticaster
.remove(item_listeners
, listener
);
945 /*************************************************************************/
948 * Processes the specified event for this object. If the event is an
949 * instance of <code>ActionEvent</code> then the
950 * <code>processActionEvent()</code> method is called. Similarly, if the
951 * even is an instance of <code>ItemEvent</code> then the
952 * <code>processItemEvent()</code> method is called. Otherwise the
953 * superclass method is called to process this event.
955 * @param event The event to process.
958 processEvent(AWTEvent event
)
960 if (event
instanceof ActionEvent
)
961 processActionEvent((ActionEvent
)event
);
962 else if (event
instanceof ItemEvent
)
963 processItemEvent((ItemEvent
)event
);
965 super.processEvent(event
);
968 /*************************************************************************/
971 * This method processes the specified event by dispatching it to any
972 * registered listeners. Note that this method will only get called if
973 * action events are enabled. This will happen automatically if any
974 * listeners are added, or it can be done "manually" by calling
975 * the <code>enableEvents()</code> method.
977 * @param event The event to process.
980 processActionEvent(ActionEvent event
)
982 if (action_listeners
!= null)
983 action_listeners
.actionPerformed(event
);
986 /*************************************************************************/
989 * This method processes the specified event by dispatching it to any
990 * registered listeners. Note that this method will only get called if
991 * item events are enabled. This will happen automatically if any
992 * listeners are added, or it can be done "manually" by calling
993 * the <code>enableEvents()</code> method.
995 * @param event The event to process.
998 processItemEvent(ItemEvent event
)
1000 if (item_listeners
!= null)
1001 item_listeners
.itemStateChanged(event
);
1005 dispatchEventImpl(AWTEvent e
)
1007 if (e
.id
<= ItemEvent
.ITEM_LAST
1008 && e
.id
>= ItemEvent
.ITEM_FIRST
1009 && (item_listeners
!= null
1010 || (eventMask
& AWTEvent
.ITEM_EVENT_MASK
) != 0))
1012 else if (e
.id
<= ActionEvent
.ACTION_LAST
1013 && e
.id
>= ActionEvent
.ACTION_FIRST
1014 && (action_listeners
!= null
1015 || (eventMask
& AWTEvent
.ACTION_EVENT_MASK
) != 0))
1018 super.dispatchEventImpl(e
);
1021 /*************************************************************************/
1024 * Returns a debugging string for this object.
1026 * @return A debugging string for this object.
1031 return "multiple=" + multipleMode
+ ",rows=" + rows
+ super.paramString();
1035 * Returns an array of all the objects currently registered as FooListeners
1036 * upon this <code>List</code>. FooListeners are registered using the
1037 * addFooListener method.
1039 * @exception ClassCastException If listenerType doesn't specify a class or
1040 * interface that implements java.util.EventListener.
1042 public EventListener
[] getListeners (Class listenerType
)
1044 if (listenerType
== ActionListener
.class)
1045 return AWTEventMulticaster
.getListeners (action_listeners
, listenerType
);
1047 if (listenerType
== ItemListener
.class)
1048 return AWTEventMulticaster
.getListeners (item_listeners
, listenerType
);
1050 return super.getListeners (listenerType
);
1054 * Returns all action listeners registered to this object.
1056 public ActionListener
[] getActionListeners ()
1058 return (ActionListener
[]) getListeners (ActionListener
.class);
1062 * Returns all action listeners registered to this object.
1064 public ItemListener
[] getItemListeners ()
1066 return (ItemListener
[]) getListeners (ItemListener
.class);