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
.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 import javax
.accessibility
.Accessible
;
51 * Class that implements a listbox widget
53 * @author Aaron M. Renn (arenn@urbanophile.com)
55 public class List
extends Component
56 implements ItemSelectable
, Accessible
63 // Serialization constant
64 private static final long serialVersionUID
= -3304312411574666869L;
66 /*************************************************************************/
72 // FIXME: Need read/writeObject
75 * @serial The items in the list.
77 private Vector items
= new Vector();
80 * @serial Indicates whether or not multiple items can be selected
83 private boolean multipleMode
;
86 * @serial The number of rows in the list. This is set on creation
87 * only and cannot be modified.
92 * @serial An array of the item indices that are selected.
94 private int[] selected
;
97 * @serial An index value used by <code>makeVisible()</code> and
98 * <code>getVisibleIndex</code>.
100 private int visibleIndex
;
102 // The list of ItemListeners for this object.
103 private ItemListener item_listeners
;
105 // The list of ActionListeners for this object.
106 private ActionListener action_listeners
;
108 /*************************************************************************/
115 * Initializes a new instance of <code>List</code> with no visible lines
116 * and multi-select disabled.
118 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
126 /*************************************************************************/
129 * Initializes a new instance of <code>List</code> with the specified
130 * number of visible lines and multi-select disabled.
132 * @param lines The number of visible lines in the list.
134 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
142 /*************************************************************************/
145 * Initializes a new instance of <code>List</code> with the specified
146 * number of lines and the specified multi-select setting.
148 * @param lines The number of visible lines in the list.
149 * @param multipleMode <code>true</code> if multiple lines can be selected
150 * simultaneously, <code>false</code> otherwise.
152 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
155 List(int rows
, boolean multipleMode
)
158 this.multipleMode
= multipleMode
;
160 if (GraphicsEnvironment
.isHeadless())
161 throw new HeadlessException ();
164 /*************************************************************************/
171 * Returns the number of items in this list.
173 * @return The number of items in this list.
178 return(items
.size());
181 /*************************************************************************/
184 * Returns the number of items in this list.
186 * @return The number of items in this list.
188 * @deprecated This method is deprecated in favor of
189 * <code>getItemCount()</code>
194 return(getItemCount());
197 /*************************************************************************/
200 * Returns the complete list of items.
202 * @return The complete list of items in the list.
204 public synchronized String
[]
207 String
[] l_items
= new String
[getItemCount()];
209 items
.copyInto(l_items
);
213 /*************************************************************************/
216 * Returns the item at the specified index.
218 * @param index The index of the item to retrieve.
220 * @exception IndexOutOfBoundsException If the index value is not valid.
225 return((String
)items
.elementAt(index
));
228 /*************************************************************************/
231 * Returns the number of visible rows in the list.
233 * @return The number of visible rows in the list.
241 /*************************************************************************/
244 * Tests whether or not multi-select mode is enabled.
246 * @return <code>true</code> if multi-select mode is enabled,
247 * <code>false</code> otherwise.
252 return(multipleMode
);
255 /*************************************************************************/
258 * Tests whether or not multi-select mode is enabled.
260 * @return <code>true</code> if multi-select mode is enabled,
261 * <code>false</code> otherwise.
263 * @deprecated This method is deprecated in favor of
264 * <code>isMultipleMode()</code>.
267 allowsMultipleSelections()
269 return(multipleMode
);
272 /*************************************************************************/
275 * This method enables or disables multiple selection mode for this
278 * @param multipleMode <code>true</code> to enable multiple mode,
279 * <code>false</code> otherwise.
282 setMultipleMode(boolean multipleMode
)
284 this.multipleMode
= multipleMode
;
287 ListPeer l
= (ListPeer
) peer
;
288 l
.setMultipleMode (multipleMode
);
292 /*************************************************************************/
295 * This method enables or disables multiple selection mode for this
298 * @param multipleMode <code>true</code> to enable multiple mode,
299 * <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
530 delItem(int index
) throws IllegalArgumentException
535 /*************************************************************************/
538 * Deletes the item at the specified index.
540 * @param index The index of the item to delete.
542 * @exception IllegalArgumentException If the index is not valid
545 remove(int index
) throws IllegalArgumentException
547 items
.removeElementAt (index
);
550 ListPeer l
= (ListPeer
) peer
;
551 l
.delItems (index
, index
);
555 /*************************************************************************/
558 * Deletes all items in the specified index range.
560 * @param start The beginning index of the range to delete.
561 * @param end The ending index of the range to delete.
563 * @exception IllegalArgumentException If the indexes are not valid
565 * @deprecated This method is deprecated for some unknown reason.
567 public synchronized void
568 delItems(int start
, int end
) throws IllegalArgumentException
570 if ((start
< 0) || (start
>= items
.size()))
571 throw new IllegalArgumentException("Bad list start index value: " + start
);
573 if ((start
< 0) || (start
>= items
.size()))
574 throw new IllegalArgumentException("Bad list start index value: " + start
);
577 throw new IllegalArgumentException("Start is greater than end!");
579 // We must run the loop in reverse direction.
580 for (int i
= end
; i
>= start
; --i
)
581 items
.removeElementAt (i
);
584 ListPeer l
= (ListPeer
) peer
;
585 l
.delItems (start
, end
);
589 /*************************************************************************/
592 * Deletes the first occurrence of the specified item from the list.
594 * @param item The item to delete.
596 * @exception IllegalArgumentException If the specified item does not exist.
598 public synchronized void
599 remove(String item
) throws IllegalArgumentException
601 int index
= items
.indexOf(item
);
603 throw new IllegalArgumentException("List element to delete not found");
608 /*************************************************************************/
611 * Deletes all of the items from the list.
613 public synchronized void
619 ListPeer l
= (ListPeer
) peer
;
624 /*************************************************************************/
627 * Deletes all of the items from the list.
629 * @deprecated This method is deprecated in favor of <code>removeAll()</code>.
637 /*************************************************************************/
640 * Replaces the item at the specified index with the specified item.
642 * @param item The new item value.
643 * @param index The index of the item to replace.
645 * @exception IllegalArgumentException If the index is not valid.
647 public synchronized void
648 replaceItem(String item
, int index
) throws IllegalArgumentException
650 if ((index
< 0) || (index
>= items
.size()))
651 throw new IllegalArgumentException("Bad list index: " + index
);
653 items
.insertElementAt(item
, index
+ 1);
654 items
.removeElementAt (index
);
658 ListPeer l
= (ListPeer
) peer
;
660 /* We add first and then remove so that the selected
661 item remains the same */
662 l
.add (item
, index
+ 1);
663 l
.delItems (index
, index
);
667 /*************************************************************************/
670 * Returns the index of the currently selected item. -1 will be returned
671 * if there are no selected rows or if there are multiple selected rows.
673 * @return The index of the selected row.
675 public synchronized int
680 ListPeer l
= (ListPeer
) peer
;
681 selected
= l
.getSelectedIndexes ();
684 if (selected
== null || selected
.length
!= 1)
689 /*************************************************************************/
692 * Returns an array containing the indexes of the rows that are
693 * currently selected.
695 * @return A list of indexes of selected rows.
697 public synchronized int[]
702 ListPeer l
= (ListPeer
) peer
;
703 selected
= l
.getSelectedIndexes ();
708 /*************************************************************************/
711 * Returns the item that is currently selected, or <code>null</code> if there
712 * is no item selected. FIXME: What happens if multiple items selected?
714 * @return The selected item, or <code>null</code> if there is no
717 public synchronized String
720 int index
= getSelectedIndex();
724 return((String
)items
.elementAt(index
));
727 /*************************************************************************/
730 * Returns the list of items that are currently selected in this list.
732 * @return The list of currently selected items.
734 public synchronized String
[]
737 int[] indexes
= getSelectedIndexes();
739 return(new String
[0]);
741 String
[] retvals
= new String
[indexes
.length
];
742 if (retvals
.length
> 0)
743 for (int i
= 0 ; i
< retvals
.length
; i
++)
744 retvals
[i
] = (String
)items
.elementAt(indexes
[i
]);
749 /*************************************************************************/
752 * Returns the list of items that are currently selected in this list as
753 * an array of type <code>Object[]</code> instead of <code>String[]</code>.
755 * @return The list of currently selected items.
757 public synchronized Object
[]
760 int[] indexes
= getSelectedIndexes();
762 return(new Object
[0]);
764 Object
[] retvals
= new Object
[indexes
.length
];
765 if (retvals
.length
> 0)
766 for (int i
= 0 ; i
< retvals
.length
; i
++)
767 retvals
[i
] = items
.elementAt(indexes
[i
]);
772 /*************************************************************************/
775 * Tests whether or not the specified index is selected.
777 * @param index The index to test.
779 * @return <code>true</code> if the index is selected, <code>false</code>
783 isIndexSelected(int index
)
785 int[] indexes
= getSelectedIndexes();
787 for (int i
= 0; i
< indexes
.length
; i
++)
788 if (indexes
[i
] == index
)
794 /*************************************************************************/
797 * Tests whether or not the specified index is selected.
799 * @param index The index to test.
801 * @return <code>true</code> if the index is selected, <code>false</code>
804 * @deprecated This method is deprecated in favor of
805 * <code>isIndexSelected(int)</code>.
808 isSelected(int index
)
810 return(isIndexSelected(index
));
813 /*************************************************************************/
816 * This method ensures that the item at the specified index is visible.
818 * @exception IllegalArgumentException If the specified index is out of
821 public synchronized void
822 makeVisible(int index
) throws IllegalArgumentException
824 if ((index
< 0) || (index
>= items
.size()))
825 throw new IllegalArgumentException("Bad list index: " + index
);
827 visibleIndex
= index
;
830 ListPeer l
= (ListPeer
) peer
;
831 l
.makeVisible (index
);
835 /*************************************************************************/
838 * Returns the index of the last item that was made visible via the
839 * <code>makeVisible()</code> method.
841 * @return The index of the last item made visible via the
842 * <code>makeVisible()</code> method.
847 return(visibleIndex
);
850 /*************************************************************************/
853 * Makes the item at the specified index selected.
855 * @param index The index of the item to select.
857 public synchronized void
860 ListPeer lp
= (ListPeer
)getPeer();
865 /*************************************************************************/
868 * Makes the item at the specified index not selected.
870 * @param index The index of the item to unselect.
872 public synchronized void
875 ListPeer lp
= (ListPeer
)getPeer();
880 /*************************************************************************/
883 * Notifies this object to create its native peer.
889 peer
= getToolkit ().createList (this);
893 /*************************************************************************/
896 * Notifies this object to destroy its native peer.
901 super.removeNotify();
904 /*************************************************************************/
907 * Adds the specified <code>ActionListener</code> to the list of
908 * registered listeners for this object.
910 * @param listener The listener to add.
912 public synchronized void
913 addActionListener(ActionListener listener
)
915 action_listeners
= AWTEventMulticaster
.add(action_listeners
, listener
);
918 /*************************************************************************/
921 * Removes the specified <code>ActionListener</code> from the list of
922 * registers listeners for this object.
924 * @param listener The listener to remove.
926 public synchronized void
927 removeActionListener(ActionListener listener
)
929 action_listeners
= AWTEventMulticaster
.remove(action_listeners
, listener
);
932 /*************************************************************************/
935 * Adds the specified <code>ItemListener</code> to the list of
936 * registered listeners for this object.
938 * @param listener The listener to add.
940 public synchronized void
941 addItemListener(ItemListener listener
)
943 item_listeners
= AWTEventMulticaster
.add(item_listeners
, listener
);
946 /*************************************************************************/
949 * Removes the specified <code>ItemListener</code> from the list of
950 * registers listeners for this object.
952 * @param listener The listener to remove.
954 public synchronized void
955 removeItemListener(ItemListener listener
)
957 item_listeners
= AWTEventMulticaster
.remove(item_listeners
, listener
);
960 /*************************************************************************/
963 * Processes the specified event for this object. If the event is an
964 * instance of <code>ActionEvent</code> then the
965 * <code>processActionEvent()</code> method is called. Similarly, if the
966 * even is an instance of <code>ItemEvent</code> then the
967 * <code>processItemEvent()</code> method is called. Otherwise the
968 * superclass method is called to process this event.
970 * @param event The event to process.
973 processEvent(AWTEvent event
)
975 if (event
instanceof ActionEvent
)
976 processActionEvent((ActionEvent
)event
);
977 else if (event
instanceof ItemEvent
)
978 processItemEvent((ItemEvent
)event
);
980 super.processEvent(event
);
983 /*************************************************************************/
986 * This method processes the specified event by dispatching it to any
987 * registered listeners. Note that this method will only get called if
988 * action events are enabled. This will happen automatically if any
989 * listeners are added, or it can be done "manually" by calling
990 * the <code>enableEvents()</code> method.
992 * @param event The event to process.
995 processActionEvent(ActionEvent event
)
997 if (action_listeners
!= null)
998 action_listeners
.actionPerformed(event
);
1001 /*************************************************************************/
1004 * This method processes the specified event by dispatching it to any
1005 * registered listeners. Note that this method will only get called if
1006 * item events are enabled. This will happen automatically if any
1007 * listeners are added, or it can be done "manually" by calling
1008 * the <code>enableEvents()</code> method.
1010 * @param event The event to process.
1013 processItemEvent(ItemEvent event
)
1015 if (item_listeners
!= null)
1016 item_listeners
.itemStateChanged(event
);
1020 dispatchEventImpl(AWTEvent e
)
1022 if (e
.id
<= ItemEvent
.ITEM_LAST
1023 && e
.id
>= ItemEvent
.ITEM_FIRST
1024 && (item_listeners
!= null
1025 || (eventMask
& AWTEvent
.ITEM_EVENT_MASK
) != 0))
1027 else if (e
.id
<= ActionEvent
.ACTION_LAST
1028 && e
.id
>= ActionEvent
.ACTION_FIRST
1029 && (action_listeners
!= null
1030 || (eventMask
& AWTEvent
.ACTION_EVENT_MASK
) != 0))
1033 super.dispatchEventImpl(e
);
1036 /*************************************************************************/
1039 * Returns a debugging string for this object.
1041 * @return A debugging string for this object.
1046 return "multiple=" + multipleMode
+ ",rows=" + rows
+ super.paramString();
1050 * Returns an array of all the objects currently registered as FooListeners
1051 * upon this <code>List</code>. FooListeners are registered using the
1052 * addFooListener method.
1054 * @exception ClassCastException If listenerType doesn't specify a class or
1055 * interface that implements java.util.EventListener.
1057 public EventListener
[] getListeners (Class listenerType
)
1059 if (listenerType
== ActionListener
.class)
1060 return AWTEventMulticaster
.getListeners (action_listeners
, listenerType
);
1062 if (listenerType
== ItemListener
.class)
1063 return AWTEventMulticaster
.getListeners (item_listeners
, listenerType
);
1065 return super.getListeners (listenerType
);
1069 * Returns all action listeners registered to this object.
1071 public ActionListener
[] getActionListeners ()
1073 return (ActionListener
[]) getListeners (ActionListener
.class);
1077 * Returns all action listeners registered to this object.
1079 public ItemListener
[] getItemListeners ()
1081 return (ItemListener
[]) getListeners (ItemListener
.class);