2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / awt / List.java
blob79b2faa62994525d436324ae22050011b51c8c8e
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)
9 any later version.
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
19 02111-1307 USA.
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.
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. */
39 package java.awt;
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;
50 /**
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
60 * Static Variables
63 // Serialization constant
64 private static final long serialVersionUID = -3304312411574666869L;
66 /*************************************************************************/
69 * Instance Variables
72 // FIXME: Need read/writeObject
74 /**
75 * @serial The items in the list.
77 private Vector items = new Vector();
79 /**
80 * @serial Indicates whether or not multiple items can be selected
81 * simultaneously.
83 private boolean multipleMode;
85 /**
86 * @serial The number of rows in the list. This is set on creation
87 * only and cannot be modified.
89 private int rows;
91 /**
92 * @serial An array of the item indices that are selected.
94 private int[] selected;
96 /**
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 /*************************************************************************/
111 * Constructors
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.
120 public
121 List()
123 this(4, false);
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.
136 public
137 List(int rows)
139 this(rows, false);
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.
154 public
155 List(int rows, boolean multipleMode)
157 this.rows = rows;
158 this.multipleMode = multipleMode;
160 if (GraphicsEnvironment.isHeadless())
161 throw new HeadlessException ();
164 /*************************************************************************/
167 * Instance Variables
171 * Returns the number of items in this list.
173 * @return The number of items in this list.
175 public int
176 getItemCount()
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>
191 public int
192 countItems()
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[]
205 getItems()
207 String[] l_items = new String[getItemCount()];
209 items.copyInto(l_items);
210 return(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.
222 public String
223 getItem(int index)
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.
235 public int
236 getRows()
238 return(rows);
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.
249 public boolean
250 isMultipleMode()
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>.
266 public boolean
267 allowsMultipleSelections()
269 return(multipleMode);
272 /*************************************************************************/
275 * This method enables or disables multiple selection mode for this
276 * list.
278 * @param multipleMode <code>true</code> to enable multiple mode,
279 * <code>false</code> otherwise.
281 public void
282 setMultipleMode(boolean multipleMode)
284 this.multipleMode = multipleMode;
285 if (peer != null)
287 ListPeer l = (ListPeer) peer;
288 l.setMultipleMode (multipleMode);
292 /*************************************************************************/
295 * This method enables or disables multiple selection mode for this
296 * list.
298 * @param multipleMode <code>true</code> to enable multiple mode,
299 * <code>false</code> otherwise.
301 * @deprecated
303 public void
304 setMultipleSelections(boolean multipleMode)
306 setMultipleMode(multipleMode);
309 /*************************************************************************/
312 * Returns the minimum size of this component.
314 * @return The minimum size of this component.
316 public Dimension
317 getMinimumSize()
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>.
332 public Dimension
333 minimumSize()
335 return(getMinimumSize(rows));
338 /*************************************************************************/
341 * Returns the minimum size of this component assuming it had the specified
342 * number of rows.
344 * @param rows The number of rows to size for.
346 * @return The minimum size of this component.
348 public Dimension
349 getMinimumSize(int rows)
351 ListPeer lp = (ListPeer)getPeer();
352 if (lp != null)
353 return(lp.minimumSize(rows));
354 else
355 return(new Dimension(0,0));
358 /*************************************************************************/
361 * Returns the minimum size of this component assuming it had the specified
362 * number of rows.
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>>
371 public Dimension
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.
384 public Dimension
385 getPreferredSize()
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>.
400 public Dimension
401 preferredSize()
403 return(getPreferredSize(rows));
406 /*************************************************************************/
409 * Returns the preferred size of this component assuming it had the specified
410 * number of rows.
412 * @param rows The number of rows to size for.
414 * @return The preferred size of this component.
416 public Dimension
417 getPreferredSize(int rows)
419 ListPeer lp = (ListPeer)getPeer();
420 if (lp != null)
421 return(lp.preferredSize(rows));
422 else
423 return(new Dimension(0,0));
426 /*************************************************************************/
429 * Returns the preferred size of this component assuming it had the specified
430 * number of rows.
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>>
439 public Dimension
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.
452 public void
453 add(String item)
455 add(item, -1);
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.
467 public void
468 addItem(String item)
470 addItem(item, -1);
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
482 * to the end.
484 public void
485 add(String item, int index)
487 if ((index == -1) || (index >= items.size()))
488 items.addElement(item);
489 else
490 items.insertElementAt(item, index);
492 if (peer != null)
494 ListPeer l = (ListPeer) peer;
495 l.add (item, index);
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
508 * to the end.
510 * @deprecated Use add() instead.
512 public void
513 addItem(String item, int index)
515 add(item, 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
527 * @deprecated
529 public void
530 delItem(int index) throws IllegalArgumentException
532 remove(index);
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
544 public void
545 remove(int index) throws IllegalArgumentException
547 items.removeElementAt (index);
548 if (peer != null)
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);
576 if (start > end)
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);
582 if (peer != null)
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);
602 if (index == -1)
603 throw new IllegalArgumentException("List element to delete not found");
605 remove(index);
608 /*************************************************************************/
611 * Deletes all of the items from the list.
613 public synchronized void
614 removeAll()
616 items.clear();
617 if (peer != null)
619 ListPeer l = (ListPeer) peer;
620 l.removeAll ();
624 /*************************************************************************/
627 * Deletes all of the items from the list.
629 * @deprecated This method is deprecated in favor of <code>removeAll()</code>.
631 public void
632 clear()
634 removeAll();
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);
656 if (peer != null)
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
676 getSelectedIndex()
678 if (peer != null)
680 ListPeer l = (ListPeer) peer;
681 selected = l.getSelectedIndexes ();
684 if (selected == null || selected.length != 1)
685 return -1;
686 return selected[0];
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[]
698 getSelectedIndexes()
700 if (peer != null)
702 ListPeer l = (ListPeer) peer;
703 selected = l.getSelectedIndexes ();
705 return selected;
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
715 * selected item.
717 public synchronized String
718 getSelectedItem()
720 int index = getSelectedIndex();
721 if (index == -1)
722 return(null);
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[]
735 getSelectedItems()
737 int[] indexes = getSelectedIndexes();
738 if (indexes == null)
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]);
746 return(retvals);
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[]
758 getSelectedObjects()
760 int[] indexes = getSelectedIndexes();
761 if (indexes == null)
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]);
769 return(retvals);
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>
780 * otherwise.
782 public boolean
783 isIndexSelected(int index)
785 int[] indexes = getSelectedIndexes();
787 for (int i = 0; i < indexes.length; i++)
788 if (indexes[i] == index)
789 return(true);
791 return(false);
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>
802 * otherwise.
804 * @deprecated This method is deprecated in favor of
805 * <code>isIndexSelected(int)</code>.
807 public boolean
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
819 * range.
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;
828 if (peer != null)
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.
844 public int
845 getVisibleIndex()
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
858 select(int index)
860 ListPeer lp = (ListPeer)getPeer();
861 if (lp != null)
862 lp.select(index);
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
873 deselect(int index)
875 ListPeer lp = (ListPeer)getPeer();
876 if (lp != null)
877 lp.deselect(index);
880 /*************************************************************************/
883 * Notifies this object to create its native peer.
885 public void
886 addNotify()
888 if (peer == null)
889 peer = getToolkit ().createList (this);
890 super.addNotify ();
893 /*************************************************************************/
896 * Notifies this object to destroy its native peer.
898 public void
899 removeNotify()
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.
972 protected void
973 processEvent(AWTEvent event)
975 if (event instanceof ActionEvent)
976 processActionEvent((ActionEvent)event);
977 else if (event instanceof ItemEvent)
978 processItemEvent((ItemEvent)event);
979 else
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.
994 protected void
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.
1012 protected void
1013 processItemEvent(ItemEvent event)
1015 if (item_listeners != null)
1016 item_listeners.itemStateChanged(event);
1019 void
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))
1026 processEvent(e);
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))
1031 processEvent(e);
1032 else
1033 super.dispatchEventImpl(e);
1036 /*************************************************************************/
1039 * Returns a debugging string for this object.
1041 * @return A debugging string for this object.
1043 protected String
1044 paramString()
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);
1083 } // class List