19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.awt;
26
27 import java.util.Vector;
28 import java.util.Locale;
29 import java.util.EventListener;
30 import java.awt.peer.ListPeer;
31 import java.awt.event.*;
32 import java.io.ObjectOutputStream;
33 import java.io.ObjectInputStream;
34 import java.io.IOException;
35 import javax.accessibility.*;
36
37
38 /**
39 * The <code>List</code> component presents the user with a
40 * scrolling list of text items. The list can be set up so that
41 * the user can choose either one item or multiple items.
42 * <p>
43 * For example, the code . . .
44 *
45 * <hr><blockquote><pre>
46 * List lst = new List(4, false);
47 * lst.add("Mercury");
48 * lst.add("Venus");
49 * lst.add("Earth");
50 * lst.add("JavaSoft");
51 * lst.add("Mars");
52 * lst.add("Jupiter");
53 * lst.add("Saturn");
54 * lst.add("Uranus");
55 * lst.add("Neptune");
56 * lst.add("Pluto");
57 * cnt.add(lst);
58 * </pre></blockquote><hr>
59 * <p>
60 * where <code>cnt</code> is a container, produces the following
61 * scrolling list:
62 * <p>
63 * <img src="doc-files/List-1.gif"
64 * alt="Shows a list containing: Venus, Earth, JavaSoft, and Mars. Javasoft is selected." style="float:center; margin: 7px 10px;">
65 * <p>
66 * If the List allows multiple selections, then clicking on
67 * an item that is already selected deselects it. In the preceding
68 * example, only one item from the scrolling list can be selected
69 * at a time, since the second argument when creating the new scrolling
70 * list is <code>false</code>. If the List does not allow multiple
71 * selections, selecting an item causes any other selected item
72 * to be deselected.
73 * <p>
74 * Note that the list in the example shown was created with four visible
75 * rows. Once the list has been created, the number of visible rows
76 * cannot be changed. A default <code>List</code> is created with
77 * four rows, so that <code>lst = new List()</code> is equivalent to
78 * <code>list = new List(4, false)</code>.
79 * <p>
80 * Beginning with Java 1.1, the Abstract Window Toolkit
81 * sends the <code>List</code> object all mouse, keyboard, and focus events
82 * that occur over it. (The old AWT event model is being maintained
83 * only for backwards compatibility, and its use is discouraged.)
84 * <p>
85 * When an item is selected or deselected by the user, AWT sends an instance
86 * of <code>ItemEvent</code> to the list.
87 * When the user double-clicks on an item in a scrolling list,
88 * AWT sends an instance of <code>ActionEvent</code> to the
89 * list following the item event. AWT also generates an action event
90 * when the user presses the return key while an item in the
91 * list is selected.
92 * <p>
93 * If an application wants to perform some action based on an item
94 * in this list being selected or activated by the user, it should implement
95 * <code>ItemListener</code> or <code>ActionListener</code>
96 * as appropriate and register the new listener to receive
97 * events from this list.
98 * <p>
99 * For multiple-selection scrolling lists, it is considered a better
100 * user interface to use an external gesture (such as clicking on a
101 * button) to trigger the action.
102 * @author Sami Shaio
103 * @see java.awt.event.ItemEvent
104 * @see java.awt.event.ItemListener
105 * @see java.awt.event.ActionEvent
106 * @see java.awt.event.ActionListener
107 * @since 1.0
108 */
109 public class List extends Component implements ItemSelectable, Accessible {
110 /**
111 * A vector created to contain items which will become
112 * part of the List Component.
113 *
114 * @serial
115 * @see #addItem(String)
116 * @see #getItem(int)
117 */
118 Vector<String> items = new Vector<>();
119
120 /**
121 * This field will represent the number of visible rows in the
122 * <code>List</code> Component. It is specified only once, and
123 * that is when the list component is actually
124 * created. It will never change.
125 *
126 * @serial
127 * @see #getRows()
128 */
129 int rows = 0;
130
131 /**
132 * <code>multipleMode</code> is a variable that will
133 * be set to <code>true</code> if a list component is to be set to
134 * multiple selection mode, that is where the user can
135 * select more than one item in a list at one time.
136 * <code>multipleMode</code> will be set to false if the
137 * list component is set to single selection, that is where
138 * the user can only select one item on the list at any
139 * one time.
140 *
141 * @serial
142 * @see #isMultipleMode()
143 * @see #setMultipleMode(boolean)
144 */
145 boolean multipleMode = false;
146
147 /**
148 * <code>selected</code> is an array that will contain
149 * the indices of items that have been selected.
150 *
151 * @serial
152 * @see #getSelectedIndexes()
153 * @see #getSelectedIndex()
154 */
155 int selected[] = new int[0];
156
157 /**
158 * This variable contains the value that will be used
159 * when trying to make a particular list item visible.
160 *
161 * @serial
162 * @see #makeVisible(int)
163 */
164 int visibleIndex = -1;
165
166 transient ActionListener actionListener;
167 transient ItemListener itemListener;
168
169 private static final String base = "list";
170 private static int nameCounter = 0;
171
172 /*
173 * JDK 1.1 serialVersionUID
174 */
175 private static final long serialVersionUID = -3304312411574666869L;
176
177 /**
178 * Creates a new scrolling list.
179 * By default, there are four visible lines and multiple selections are
180 * not allowed. Note that this is a convenience method for
181 * <code>List(0, false)</code>. Also note that the number of visible
182 * lines in the list cannot be changed after it has been created.
183 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
184 * returns true.
185 * @see java.awt.GraphicsEnvironment#isHeadless
186 */
187 public List() throws HeadlessException {
188 this(0, false);
189 }
190
191 /**
192 * Creates a new scrolling list initialized with the specified
193 * number of visible lines. By default, multiple selections are
194 * not allowed. Note that this is a convenience method for
195 * <code>List(rows, false)</code>. Also note that the number
196 * of visible rows in the list cannot be changed after it has
197 * been created.
198 * @param rows the number of items to show.
199 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
200 * returns true.
201 * @see java.awt.GraphicsEnvironment#isHeadless
202 * @since 1.1
203 */
204 public List(int rows) throws HeadlessException {
205 this(rows, false);
206 }
207
208 /**
209 * The default number of visible rows is 4. A list with
210 * zero rows is unusable and unsightly.
211 */
212 static final int DEFAULT_VISIBLE_ROWS = 4;
213
214 /**
215 * Creates a new scrolling list initialized to display the specified
216 * number of rows. Note that if zero rows are specified, then
217 * the list will be created with a default of four rows.
218 * Also note that the number of visible rows in the list cannot
219 * be changed after it has been created.
220 * If the value of <code>multipleMode</code> is
221 * <code>true</code>, then the user can select multiple items from
222 * the list. If it is <code>false</code>, only one item at a time
223 * can be selected.
224 * @param rows the number of items to show.
225 * @param multipleMode if <code>true</code>,
226 * then multiple selections are allowed;
227 * otherwise, only one item can be selected at a time.
228 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
229 * returns true.
230 * @see java.awt.GraphicsEnvironment#isHeadless
231 */
232 public List(int rows, boolean multipleMode) throws HeadlessException {
233 GraphicsEnvironment.checkHeadless();
234 this.rows = (rows != 0) ? rows : DEFAULT_VISIBLE_ROWS;
235 this.multipleMode = multipleMode;
236 }
237
238 /**
239 * Construct a name for this component. Called by
240 * <code>getName</code> when the name is <code>null</code>.
241 */
242 String constructComponentName() {
243 synchronized (List.class) {
244 return base + nameCounter++;
245 }
246 }
247
248 /**
249 * Creates the peer for the list. The peer allows us to modify the
250 * list's appearance without changing its functionality.
251 */
252 public void addNotify() {
253 synchronized (getTreeLock()) {
254 if (peer == null)
255 peer = getComponentFactory().createList(this);
256 super.addNotify();
257 }
258 }
259
260 /**
269 }
270 super.removeNotify();
271 }
272 }
273
274 /**
275 * Gets the number of items in the list.
276 * @return the number of items in the list
277 * @see #getItem
278 * @since 1.1
279 */
280 public int getItemCount() {
281 return countItems();
282 }
283
284 /**
285 * Returns the number of items in the list.
286 *
287 * @return the number of items in the list
288 * @deprecated As of JDK version 1.1,
289 * replaced by <code>getItemCount()</code>.
290 */
291 @Deprecated
292 public int countItems() {
293 return items.size();
294 }
295
296 /**
297 * Gets the item associated with the specified index.
298 * @return an item that is associated with
299 * the specified index
300 * @param index the position of the item
301 * @see #getItemCount
302 */
303 public String getItem(int index) {
304 return getItemImpl(index);
305 }
306
307 // NOTE: This method may be called by privileged threads.
308 // We implement this functionality in a package-private method
309 // to insure that it cannot be overridden by client subclasses.
322 */
323 public synchronized String[] getItems() {
324 String itemCopies[] = new String[items.size()];
325 items.copyInto(itemCopies);
326 return itemCopies;
327 }
328
329 /**
330 * Adds the specified item to the end of scrolling list.
331 * @param item the item to be added
332 * @since 1.1
333 */
334 public void add(String item) {
335 addItem(item);
336 }
337
338 /**
339 * Adds the specified item to the end of the list.
340 *
341 * @param item the item to be added
342 * @deprecated replaced by <code>add(String)</code>.
343 */
344 @Deprecated
345 public void addItem(String item) {
346 addItem(item, -1);
347 }
348
349 /**
350 * Adds the specified item to the scrolling list
351 * at the position indicated by the index. The index is
352 * zero-based. If the value of the index is less than zero,
353 * or if the value of the index is greater than or equal to
354 * the number of items in the list, then the item is added
355 * to the end of the list.
356 * @param item the item to be added;
357 * if this parameter is <code>null</code> then the item is
358 * treated as an empty string, <code>""</code>
359 * @param index the position at which to add the item
360 * @since 1.1
361 */
362 public void add(String item, int index) {
363 addItem(item, index);
364 }
365
366 /**
367 * Adds the specified item to the list
368 * at the position indicated by the index.
369 *
370 * @param item the item to be added
371 * @param index the position at which to add the item
372 * @deprecated replaced by <code>add(String, int)</code>.
373 */
374 @Deprecated
375 public synchronized void addItem(String item, int index) {
376 if (index < -1 || index >= items.size()) {
377 index = -1;
378 }
379
380 if (item == null) {
381 item = "";
382 }
383
384 if (index == -1) {
385 items.addElement(item);
386 } else {
387 items.insertElementAt(item, index);
388 }
389
390 ListPeer peer = (ListPeer)this.peer;
391 if (peer != null) {
392 peer.add(item, index);
393 }
394 }
395
396 /**
397 * Replaces the item at the specified index in the scrolling list
398 * with the new string.
399 * @param newValue a new string to replace an existing item
400 * @param index the position of the item to replace
401 * @exception ArrayIndexOutOfBoundsException if <code>index</code>
402 * is out of range
403 */
404 public synchronized void replaceItem(String newValue, int index) {
405 remove(index);
406 add(newValue, index);
407 }
408
409 /**
410 * Removes all items from this list.
411 * @see #remove
412 * @see #delItems
413 * @since 1.1
414 */
415 public void removeAll() {
416 clear();
417 }
418
419 /**
420 * @deprecated As of JDK version 1.1,
421 * replaced by <code>removeAll()</code>.
422 */
423 @Deprecated
424 public synchronized void clear() {
425 ListPeer peer = (ListPeer)this.peer;
426 if (peer != null) {
427 peer.removeAll();
428 }
429 items = new Vector<>();
430 selected = new int[0];
431 }
432
433 /**
434 * Removes the first occurrence of an item from the list.
435 * If the specified item is selected, and is the only selected
436 * item in the list, the list is set to have no selection.
437 * @param item the item to remove from the list
438 * @exception IllegalArgumentException
439 * if the item doesn't exist in the list
440 * @since 1.1
441 */
442 public synchronized void remove(String item) {
443 int index = items.indexOf(item);
444 if (index < 0) {
445 throw new IllegalArgumentException("item " + item +
446 " not found in list");
447 } else {
448 remove(index);
449 }
450 }
451
452 /**
453 * Removes the item at the specified position
454 * from this scrolling list.
455 * If the item with the specified position is selected, and is the
456 * only selected item in the list, the list is set to have no selection.
457 * @param position the index of the item to delete
458 * @see #add(String, int)
459 * @since 1.1
460 * @exception ArrayIndexOutOfBoundsException
461 * if the <code>position</code> is less than 0 or
462 * greater than <code>getItemCount()-1</code>
463 */
464 public void remove(int position) {
465 delItem(position);
466 }
467
468 /**
469 * Removes the item at the specified position.
470 *
471 * @param position the index of the item to delete
472 * @deprecated replaced by <code>remove(String)</code>
473 * and <code>remove(int)</code>.
474 */
475 @Deprecated
476 public void delItem(int position) {
477 delItems(position, position);
478 }
479
480 /**
481 * Gets the index of the selected item on the list,
482 *
483 * @return the index of the selected item;
484 * if no item is selected, or if multiple items are
485 * selected, <code>-1</code> is returned.
486 * @see #select
487 * @see #deselect
488 * @see #isIndexSelected
489 */
490 public synchronized int getSelectedIndex() {
491 int sel[] = getSelectedIndexes();
492 return (sel.length == 1) ? sel[0] : -1;
493 }
494
495 /**
496 * Gets the selected indexes on the list.
497 *
498 * @return an array of the selected indexes on this scrolling list;
499 * if no item is selected, a zero-length array is returned.
500 * @see #select
501 * @see #deselect
502 * @see #isIndexSelected
503 */
504 public synchronized int[] getSelectedIndexes() {
505 ListPeer peer = (ListPeer)this.peer;
506 if (peer != null) {
507 selected = peer.getSelectedIndexes();
508 }
509 return selected.clone();
510 }
511
512 /**
513 * Gets the selected item on this scrolling list.
514 *
515 * @return the selected item on the list;
516 * if no item is selected, or if multiple items are
517 * selected, <code>null</code> is returned.
518 * @see #select
519 * @see #deselect
520 * @see #isIndexSelected
521 */
522 public synchronized String getSelectedItem() {
523 int index = getSelectedIndex();
524 return (index < 0) ? null : getItem(index);
525 }
526
527 /**
528 * Gets the selected items on this scrolling list.
529 *
530 * @return an array of the selected items on this scrolling list;
531 * if no item is selected, a zero-length array is returned.
532 * @see #select
533 * @see #deselect
534 * @see #isIndexSelected
535 */
536 public synchronized String[] getSelectedItems() {
537 int sel[] = getSelectedIndexes();
538 String str[] = new String[sel.length];
539 for (int i = 0 ; i < sel.length ; i++) {
540 str[i] = getItem(sel[i]);
541 }
542 return str;
543 }
544
545 /**
546 * Gets the selected items on this scrolling list in an array of Objects.
547 * @return an array of <code>Object</code>s representing the
548 * selected items on this scrolling list;
549 * if no item is selected, a zero-length array is returned.
550 * @see #getSelectedItems
551 * @see ItemSelectable
552 */
553 public Object[] getSelectedObjects() {
554 return getSelectedItems();
555 }
556
557 /**
558 * Selects the item at the specified index in the scrolling list.
559 *<p>
560 * Note that passing out of range parameters is invalid,
561 * and will result in unspecified behavior.
562 *
563 * <p>Note that this method should be primarily used to
564 * initially select an item in this component.
565 * Programmatically calling this method will <i>not</i> trigger
566 * an <code>ItemEvent</code>. The only way to trigger an
567 * <code>ItemEvent</code> is by user interaction.
568 *
569 * @param index the position of the item to select
570 * @see #getSelectedItem
571 * @see #deselect
572 * @see #isIndexSelected
573 */
574 public void select(int index) {
575 // Bug #4059614: select can't be synchronized while calling the peer,
576 // because it is called from the Window Thread. It is sufficient to
577 // synchronize the code that manipulates 'selected' except for the
578 // case where the peer changes. To handle this case, we simply
579 // repeat the selection process.
580
581 ListPeer peer;
582 do {
583 peer = (ListPeer)this.peer;
584 if (peer != null) {
585 peer.select(index);
586 return;
587 }
632 if (isMultipleMode() || (getSelectedIndex() == index)) {
633 peer.deselect(index);
634 }
635 }
636
637 for (int i = 0 ; i < selected.length ; i++) {
638 if (selected[i] == index) {
639 int newsel[] = new int[selected.length - 1];
640 System.arraycopy(selected, 0, newsel, 0, i);
641 System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
642 selected = newsel;
643 return;
644 }
645 }
646 }
647
648 /**
649 * Determines if the specified item in this scrolling list is
650 * selected.
651 * @param index the item to be checked
652 * @return <code>true</code> if the specified item has been
653 * selected; <code>false</code> otherwise
654 * @see #select
655 * @see #deselect
656 * @since 1.1
657 */
658 public boolean isIndexSelected(int index) {
659 return isSelected(index);
660 }
661
662 /**
663 * Determines if the specified item in the list is selected.
664 *
665 * @param index specifies the item to be checked
666 * @return {@code true} if the item is selected; otherwise {@code false}
667 * @deprecated As of JDK version 1.1,
668 * replaced by <code>isIndexSelected(int)</code>.
669 */
670 @Deprecated
671 public boolean isSelected(int index) {
672 int sel[] = getSelectedIndexes();
673 for (int i = 0 ; i < sel.length ; i++) {
674 if (sel[i] == index) {
675 return true;
676 }
677 }
678 return false;
679 }
680
681 /**
682 * Gets the number of visible lines in this list. Note that
683 * once the <code>List</code> has been created, this number
684 * will never change.
685 * @return the number of visible lines in this scrolling list
686 */
687 public int getRows() {
688 return rows;
689 }
690
691 /**
692 * Determines whether this list allows multiple selections.
693 *
694 * @return <code>true</code> if this list allows multiple
695 * selections; otherwise, <code>false</code>
696 * @see #setMultipleMode
697 * @since 1.1
698 */
699 public boolean isMultipleMode() {
700 return allowsMultipleSelections();
701 }
702
703 /**
704 * Determines whether this list allows multiple selections.
705 *
706 * @return {@code true} if this list allows multiple
707 * selections; otherwise {@code false}
708 * @deprecated As of JDK version 1.1,
709 * replaced by <code>isMultipleMode()</code>.
710 */
711 @Deprecated
712 public boolean allowsMultipleSelections() {
713 return multipleMode;
714 }
715
716 /**
717 * Sets the flag that determines whether this list
718 * allows multiple selections.
719 * When the selection mode is changed from multiple-selection to
720 * single-selection, the selected items change as follows:
721 * If a selected item has the location cursor, only that
722 * item will remain selected. If no selected item has the
723 * location cursor, all items will be deselected.
724 * @param b if <code>true</code> then multiple selections
725 * are allowed; otherwise, only one item from
726 * the list can be selected at once
727 * @see #isMultipleMode
728 * @since 1.1
729 */
730 public void setMultipleMode(boolean b) {
731 setMultipleSelections(b);
732 }
733
734 /**
735 * Enables or disables multiple selection mode for this list.
736 *
737 * @param b {@code true} to enable multiple mode, {@code false} otherwise
738 * @deprecated As of JDK version 1.1,
739 * replaced by <code>setMultipleMode(boolean)</code>.
740 */
741 @Deprecated
742 public synchronized void setMultipleSelections(boolean b) {
743 if (b != multipleMode) {
744 multipleMode = b;
745 ListPeer peer = (ListPeer)this.peer;
746 if (peer != null) {
747 peer.setMultipleMode(b);
748 }
749 }
750 }
751
752 /**
753 * Gets the index of the item that was last made visible by
754 * the method <code>makeVisible</code>.
755 * @return the index of the item that was last made visible
756 * @see #makeVisible
757 */
758 public int getVisibleIndex() {
759 return visibleIndex;
760 }
761
762 /**
763 * Makes the item at the specified index visible.
764 * @param index the position of the item
765 * @see #getVisibleIndex
766 */
767 public synchronized void makeVisible(int index) {
768 visibleIndex = index;
769 ListPeer peer = (ListPeer)this.peer;
770 if (peer != null) {
771 peer.makeVisible(index);
772 }
773 }
774
775 /**
776 * Gets the preferred dimensions for a list with the specified
777 * number of rows.
778 * @param rows number of rows in the list
779 * @return the preferred dimensions for displaying this scrolling list
780 * given that the specified number of rows must be visible
781 * @see java.awt.Component#getPreferredSize
782 * @since 1.1
783 */
784 public Dimension getPreferredSize(int rows) {
785 return preferredSize(rows);
786 }
787
788 /**
789 * Returns the preferred size of this component
790 * assuming it has the specified number of rows.
791 *
792 * @param rows the number of rows
793 * @return the preferred dimensions for displaying this list
794 * @deprecated As of JDK version 1.1,
795 * replaced by <code>getPreferredSize(int)</code>.
796 */
797 @Deprecated
798 public Dimension preferredSize(int rows) {
799 synchronized (getTreeLock()) {
800 ListPeer peer = (ListPeer)this.peer;
801 return (peer != null) ?
802 peer.getPreferredSize(rows) :
803 super.preferredSize();
804 }
805 }
806
807 /**
808 * Gets the preferred size of this scrolling list.
809 * @return the preferred dimensions for displaying this scrolling list
810 * @see java.awt.Component#getPreferredSize
811 * @since 1.1
812 */
813 public Dimension getPreferredSize() {
814 return preferredSize();
815 }
816
817 /**
818 * @deprecated As of JDK version 1.1,
819 * replaced by <code>getPreferredSize()</code>.
820 */
821 @Deprecated
822 public Dimension preferredSize() {
823 synchronized (getTreeLock()) {
824 return (rows > 0) ?
825 preferredSize(rows) :
826 super.preferredSize();
827 }
828 }
829
830 /**
831 * Gets the minimum dimensions for a list with the specified
832 * number of rows.
833 * @param rows number of rows in the list
834 * @return the minimum dimensions for displaying this scrolling list
835 * given that the specified number of rows must be visible
836 * @see java.awt.Component#getMinimumSize
837 * @since 1.1
838 */
839 public Dimension getMinimumSize(int rows) {
840 return minimumSize(rows);
841 }
842
843 /**
844 * Returns the minimum dimensions for the list
845 * with the specified number of rows.
846 *
847 * @param rows the number of rows in the list
848 * @return the minimum dimensions for displaying this list
849 * @deprecated As of JDK version 1.1,
850 * replaced by <code>getMinimumSize(int)</code>.
851 */
852 @Deprecated
853 public Dimension minimumSize(int rows) {
854 synchronized (getTreeLock()) {
855 ListPeer peer = (ListPeer)this.peer;
856 return (peer != null) ?
857 peer.getMinimumSize(rows) :
858 super.minimumSize();
859 }
860 }
861
862 /**
863 * Determines the minimum size of this scrolling list.
864 * @return the minimum dimensions needed
865 * to display this scrolling list
866 * @see java.awt.Component#getMinimumSize()
867 * @since 1.1
868 */
869 public Dimension getMinimumSize() {
870 return minimumSize();
871 }
872
873 /**
874 * @deprecated As of JDK version 1.1,
875 * replaced by <code>getMinimumSize()</code>.
876 */
877 @Deprecated
878 public Dimension minimumSize() {
879 synchronized (getTreeLock()) {
880 return (rows > 0) ? minimumSize(rows) : super.minimumSize();
881 }
882 }
883
884 /**
885 * Adds the specified item listener to receive item events from
886 * this list. Item events are sent in response to user input, but not
887 * in response to calls to <code>select</code> or <code>deselect</code>.
888 * If listener <code>l</code> is <code>null</code>,
889 * no exception is thrown and no action is performed.
890 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
891 * >AWT Threading Issues</a> for details on AWT's threading model.
892 *
893 * @param l the item listener
894 * @see #removeItemListener
895 * @see #getItemListeners
896 * @see #select
897 * @see #deselect
898 * @see java.awt.event.ItemEvent
899 * @see java.awt.event.ItemListener
900 * @since 1.1
901 */
902 public synchronized void addItemListener(ItemListener l) {
903 if (l == null) {
904 return;
905 }
906 itemListener = AWTEventMulticaster.add(itemListener, l);
907 newEventsOnly = true;
908 }
909
910 /**
911 * Removes the specified item listener so that it no longer
912 * receives item events from this list.
913 * If listener <code>l</code> is <code>null</code>,
914 * no exception is thrown and no action is performed.
915 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
916 * >AWT Threading Issues</a> for details on AWT's threading model.
917 *
918 * @param l the item listener
919 * @see #addItemListener
920 * @see #getItemListeners
921 * @see java.awt.event.ItemEvent
922 * @see java.awt.event.ItemListener
923 * @since 1.1
924 */
925 public synchronized void removeItemListener(ItemListener l) {
926 if (l == null) {
927 return;
928 }
929 itemListener = AWTEventMulticaster.remove(itemListener, l);
930 }
931
932 /**
933 * Returns an array of all the item listeners
934 * registered on this list.
935 *
936 * @return all of this list's <code>ItemListener</code>s
937 * or an empty array if no item
938 * listeners are currently registered
939 *
940 * @see #addItemListener
941 * @see #removeItemListener
942 * @see java.awt.event.ItemEvent
943 * @see java.awt.event.ItemListener
944 * @since 1.4
945 */
946 public synchronized ItemListener[] getItemListeners() {
947 return getListeners(ItemListener.class);
948 }
949
950 /**
951 * Adds the specified action listener to receive action events from
952 * this list. Action events occur when a user double-clicks
953 * on a list item or types Enter when the list has the keyboard
954 * focus.
955 * <p>
956 * If listener <code>l</code> is <code>null</code>,
957 * no exception is thrown and no action is performed.
958 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
959 * >AWT Threading Issues</a> for details on AWT's threading model.
960 *
961 * @param l the action listener
962 * @see #removeActionListener
963 * @see #getActionListeners
964 * @see java.awt.event.ActionEvent
965 * @see java.awt.event.ActionListener
966 * @since 1.1
967 */
968 public synchronized void addActionListener(ActionListener l) {
969 if (l == null) {
970 return;
971 }
972 actionListener = AWTEventMulticaster.add(actionListener, l);
973 newEventsOnly = true;
974 }
975
976 /**
977 * Removes the specified action listener so that it no longer
978 * receives action events from this list. Action events
979 * occur when a user double-clicks on a list item.
980 * If listener <code>l</code> is <code>null</code>,
981 * no exception is thrown and no action is performed.
982 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
983 * >AWT Threading Issues</a> for details on AWT's threading model.
984 *
985 * @param l the action listener
986 * @see #addActionListener
987 * @see #getActionListeners
988 * @see java.awt.event.ActionEvent
989 * @see java.awt.event.ActionListener
990 * @since 1.1
991 */
992 public synchronized void removeActionListener(ActionListener l) {
993 if (l == null) {
994 return;
995 }
996 actionListener = AWTEventMulticaster.remove(actionListener, l);
997 }
998
999 /**
1000 * Returns an array of all the action listeners
1001 * registered on this list.
1002 *
1003 * @return all of this list's <code>ActionListener</code>s
1004 * or an empty array if no action
1005 * listeners are currently registered
1006 *
1007 * @see #addActionListener
1008 * @see #removeActionListener
1009 * @see java.awt.event.ActionEvent
1010 * @see java.awt.event.ActionListener
1011 * @since 1.4
1012 */
1013 public synchronized ActionListener[] getActionListeners() {
1014 return getListeners(ActionListener.class);
1015 }
1016
1017 /**
1018 * Returns an array of all the objects currently registered
1019 * as <code><em>Foo</em>Listener</code>s
1020 * upon this <code>List</code>.
1021 * <code><em>Foo</em>Listener</code>s are registered using the
1022 * <code>add<em>Foo</em>Listener</code> method.
1023 *
1024 * <p>
1025 * You can specify the <code>listenerType</code> argument
1026 * with a class literal, such as
1027 * <code><em>Foo</em>Listener.class</code>.
1028 * For example, you can query a
1029 * <code>List</code> <code>l</code>
1030 * for its item listeners with the following code:
1031 *
1032 * <pre>ItemListener[] ils = (ItemListener[])(l.getListeners(ItemListener.class));</pre>
1033 *
1034 * If no such listeners exist, this method returns an empty array.
1035 *
1036 * @param listenerType the type of listeners requested; this parameter
1037 * should specify an interface that descends from
1038 * <code>java.util.EventListener</code>
1039 * @return an array of all objects registered as
1040 * <code><em>Foo</em>Listener</code>s on this list,
1041 * or an empty array if no such
1042 * listeners have been added
1043 * @exception ClassCastException if <code>listenerType</code>
1044 * doesn't specify a class or interface that implements
1045 * <code>java.util.EventListener</code>
1046 *
1047 * @see #getItemListeners
1048 * @since 1.3
1049 */
1050 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1051 EventListener l = null;
1052 if (listenerType == ActionListener.class) {
1053 l = actionListener;
1054 } else if (listenerType == ItemListener.class) {
1055 l = itemListener;
1056 } else {
1057 return super.getListeners(listenerType);
1058 }
1059 return AWTEventMulticaster.getListeners(l, listenerType);
1060 }
1061
1062 // REMIND: remove when filtering is done at lower level
1063 boolean eventEnabled(AWTEvent e) {
1064 switch(e.id) {
1065 case ActionEvent.ACTION_PERFORMED:
1066 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
1067 actionListener != null) {
1068 return true;
1069 }
1070 return false;
1071 case ItemEvent.ITEM_STATE_CHANGED:
1072 if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
1073 itemListener != null) {
1074 return true;
1075 }
1076 return false;
1077 default:
1078 break;
1079 }
1080 return super.eventEnabled(e);
1081 }
1082
1083 /**
1084 * Processes events on this scrolling list. If an event is
1085 * an instance of <code>ItemEvent</code>, it invokes the
1086 * <code>processItemEvent</code> method. Else, if the
1087 * event is an instance of <code>ActionEvent</code>,
1088 * it invokes <code>processActionEvent</code>.
1089 * If the event is not an item event or an action event,
1090 * it invokes <code>processEvent</code> on the superclass.
1091 * <p>Note that if the event parameter is <code>null</code>
1092 * the behavior is unspecified and may result in an
1093 * exception.
1094 *
1095 * @param e the event
1096 * @see java.awt.event.ActionEvent
1097 * @see java.awt.event.ItemEvent
1098 * @see #processActionEvent
1099 * @see #processItemEvent
1100 * @since 1.1
1101 */
1102 protected void processEvent(AWTEvent e) {
1103 if (e instanceof ItemEvent) {
1104 processItemEvent((ItemEvent)e);
1105 return;
1106 } else if (e instanceof ActionEvent) {
1107 processActionEvent((ActionEvent)e);
1108 return;
1109 }
1110 super.processEvent(e);
1111 }
1112
1113 /**
1114 * Processes item events occurring on this list by
1115 * dispatching them to any registered
1116 * <code>ItemListener</code> objects.
1117 * <p>
1118 * This method is not called unless item events are
1119 * enabled for this component. Item events are enabled
1120 * when one of the following occurs:
1121 * <ul>
1122 * <li>An <code>ItemListener</code> object is registered
1123 * via <code>addItemListener</code>.
1124 * <li>Item events are enabled via <code>enableEvents</code>.
1125 * </ul>
1126 * <p>Note that if the event parameter is <code>null</code>
1127 * the behavior is unspecified and may result in an
1128 * exception.
1129 *
1130 * @param e the item event
1131 * @see java.awt.event.ItemEvent
1132 * @see java.awt.event.ItemListener
1133 * @see #addItemListener
1134 * @see java.awt.Component#enableEvents
1135 * @since 1.1
1136 */
1137 protected void processItemEvent(ItemEvent e) {
1138 ItemListener listener = itemListener;
1139 if (listener != null) {
1140 listener.itemStateChanged(e);
1141 }
1142 }
1143
1144 /**
1145 * Processes action events occurring on this component
1146 * by dispatching them to any registered
1147 * <code>ActionListener</code> objects.
1148 * <p>
1149 * This method is not called unless action events are
1150 * enabled for this component. Action events are enabled
1151 * when one of the following occurs:
1152 * <ul>
1153 * <li>An <code>ActionListener</code> object is registered
1154 * via <code>addActionListener</code>.
1155 * <li>Action events are enabled via <code>enableEvents</code>.
1156 * </ul>
1157 * <p>Note that if the event parameter is <code>null</code>
1158 * the behavior is unspecified and may result in an
1159 * exception.
1160 *
1161 * @param e the action event
1162 * @see java.awt.event.ActionEvent
1163 * @see java.awt.event.ActionListener
1164 * @see #addActionListener
1165 * @see java.awt.Component#enableEvents
1166 * @since 1.1
1167 */
1168 protected void processActionEvent(ActionEvent e) {
1169 ActionListener listener = actionListener;
1170 if (listener != null) {
1171 listener.actionPerformed(e);
1172 }
1173 }
1174
1175 /**
1176 * Returns the parameter string representing the state of this
1177 * scrolling list. This string is useful for debugging.
1192 * private method.
1193 */
1194 @Deprecated
1195 public synchronized void delItems(int start, int end) {
1196 for (int i = end; i >= start; i--) {
1197 items.removeElementAt(i);
1198 }
1199 ListPeer peer = (ListPeer)this.peer;
1200 if (peer != null) {
1201 peer.delItems(start, end);
1202 }
1203 }
1204
1205 /*
1206 * Serialization support. Since the value of the selected
1207 * field isn't necessarily up to date, we sync it up with the
1208 * peer before serializing.
1209 */
1210
1211 /**
1212 * The <code>List</code> component's
1213 * Serialized Data Version.
1214 *
1215 * @serial
1216 */
1217 private int listSerializedDataVersion = 1;
1218
1219 /**
1220 * Writes default serializable fields to stream. Writes
1221 * a list of serializable <code>ItemListeners</code>
1222 * and <code>ActionListeners</code> as optional data.
1223 * The non-serializable listeners are detected and
1224 * no attempt is made to serialize them.
1225 *
1226 * @serialData <code>null</code> terminated sequence of 0
1227 * or more pairs; the pair consists of a <code>String</code>
1228 * and an <code>Object</code>; the <code>String</code>
1229 * indicates the type of object and is one of the
1230 * following:
1231 * <code>itemListenerK</code> indicating an
1232 * <code>ItemListener</code> object;
1233 * <code>actionListenerK</code> indicating an
1234 * <code>ActionListener</code> object
1235 *
1236 * @param s the <code>ObjectOutputStream</code> to write
1237 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1238 * @see java.awt.Component#itemListenerK
1239 * @see java.awt.Component#actionListenerK
1240 * @see #readObject(ObjectInputStream)
1241 */
1242 private void writeObject(ObjectOutputStream s)
1243 throws IOException
1244 {
1245 synchronized (this) {
1246 ListPeer peer = (ListPeer)this.peer;
1247 if (peer != null) {
1248 selected = peer.getSelectedIndexes();
1249 }
1250 }
1251 s.defaultWriteObject();
1252
1253 AWTEventMulticaster.save(s, itemListenerK, itemListener);
1254 AWTEventMulticaster.save(s, actionListenerK, actionListener);
1255 s.writeObject(null);
1256 }
1257
1258 /**
1259 * Reads the <code>ObjectInputStream</code> and if it
1260 * isn't <code>null</code> adds a listener to receive
1261 * both item events and action events (as specified
1262 * by the key stored in the stream) fired by the
1263 * <code>List</code>.
1264 * Unrecognized keys or values will be ignored.
1265 *
1266 * @param s the <code>ObjectInputStream</code> to write
1267 * @exception HeadlessException if
1268 * <code>GraphicsEnvironment.isHeadless</code> returns
1269 * <code>true</code>
1270 * @see #removeItemListener(ItemListener)
1271 * @see #addItemListener(ItemListener)
1272 * @see java.awt.GraphicsEnvironment#isHeadless
1273 * @see #writeObject(ObjectOutputStream)
1274 */
1275 private void readObject(ObjectInputStream s)
1276 throws ClassNotFoundException, IOException, HeadlessException
1277 {
1278 GraphicsEnvironment.checkHeadless();
1279 s.defaultReadObject();
1280
1281 Object keyOrNull;
1282 while(null != (keyOrNull = s.readObject())) {
1283 String key = ((String)keyOrNull).intern();
1284
1285 if (itemListenerK == key)
1286 addItemListener((ItemListener)(s.readObject()));
1287
1288 else if (actionListenerK == key)
1289 addActionListener((ActionListener)(s.readObject()));
1290
1291 else // skip value for unrecognized key
1292 s.readObject();
1293 }
1294 }
1295
1296
1297 /////////////////
1298 // Accessibility support
1299 ////////////////
1300
1301
1302 /**
1303 * Gets the <code>AccessibleContext</code> associated with this
1304 * <code>List</code>. For lists, the <code>AccessibleContext</code>
1305 * takes the form of an <code>AccessibleAWTList</code>.
1306 * A new <code>AccessibleAWTList</code> instance is created, if necessary.
1307 *
1308 * @return an <code>AccessibleAWTList</code> that serves as the
1309 * <code>AccessibleContext</code> of this <code>List</code>
1310 * @since 1.3
1311 */
1312 public AccessibleContext getAccessibleContext() {
1313 if (accessibleContext == null) {
1314 accessibleContext = new AccessibleAWTList();
1315 }
1316 return accessibleContext;
1317 }
1318
1319 /**
1320 * This class implements accessibility support for the
1321 * <code>List</code> class. It provides an implementation of the
1322 * Java Accessibility API appropriate to list user-interface elements.
1323 * @since 1.3
1324 */
1325 protected class AccessibleAWTList extends AccessibleAWTComponent
1326 implements AccessibleSelection, ItemListener, ActionListener
1327 {
1328 /*
1329 * JDK 1.3 serialVersionUID
1330 */
1331 private static final long serialVersionUID = 7924617370136012829L;
1332
1333 /**
1334 * Constructs new {@code AccessibleAWTList}
1335 */
1336 public AccessibleAWTList() {
1337 super();
1338 List.this.addActionListener(this);
1339 List.this.addItemListener(this);
1340 }
1341
1913 * @return A Dimension object that indicates the size of this
1914 * component; null if this object is not on the screen
1915 * @see #setSize
1916 */
1917 public Dimension getSize() {
1918 // [[[FIXME]]]
1919 return null;
1920 }
1921
1922 /**
1923 * Resizes this object so that it has width and height.
1924 *
1925 * @param d - The dimension specifying the new size of the object.
1926 * @see #getSize
1927 */
1928 public void setSize(Dimension d) {
1929 // not supported; no-op
1930 }
1931
1932 /**
1933 * Returns the <code>Accessible</code> child, if one exists,
1934 * contained at the local coordinate <code>Point</code>.
1935 *
1936 * @param p the point relative to the coordinate system of this
1937 * object
1938 * @return the <code>Accessible</code>, if it exists,
1939 * at the specified location; otherwise <code>null</code>
1940 */
1941 public Accessible getAccessibleAt(Point p) {
1942 return null; // object cannot have children!
1943 }
1944
1945 /**
1946 * Returns whether this object can accept focus or not. Objects
1947 * that can accept focus will also have the
1948 * <code>AccessibleState.FOCUSABLE</code> state set in their
1949 * <code>AccessibleStateSet</code>.
1950 *
1951 * @return true if object can accept focus; otherwise false
1952 * @see AccessibleContext#getAccessibleStateSet
1953 * @see AccessibleState#FOCUSABLE
1954 * @see AccessibleState#FOCUSED
1955 * @see AccessibleStateSet
1956 */
1957 public boolean isFocusTraversable() {
1958 return false; // list element cannot receive focus!
1959 }
1960
1961 /**
1962 * Requests focus for this object. If this object cannot accept
1963 * focus, nothing will happen. Otherwise, the object will attempt
1964 * to take focus.
1965 * @see #isFocusTraversable
1966 */
1967 public void requestFocus() {
1968 // nothing to do; a no-op
1969 }
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.awt;
26
27 import java.util.Vector;
28 import java.util.Locale;
29 import java.util.EventListener;
30 import java.awt.peer.ListPeer;
31 import java.awt.event.*;
32 import java.io.ObjectOutputStream;
33 import java.io.ObjectInputStream;
34 import java.io.IOException;
35 import javax.accessibility.*;
36
37
38 /**
39 * The {@code List} component presents the user with a
40 * scrolling list of text items. The list can be set up so that
41 * the user can choose either one item or multiple items.
42 * <p>
43 * For example, the code . . .
44 *
45 * <hr><blockquote><pre>
46 * List lst = new List(4, false);
47 * lst.add("Mercury");
48 * lst.add("Venus");
49 * lst.add("Earth");
50 * lst.add("JavaSoft");
51 * lst.add("Mars");
52 * lst.add("Jupiter");
53 * lst.add("Saturn");
54 * lst.add("Uranus");
55 * lst.add("Neptune");
56 * lst.add("Pluto");
57 * cnt.add(lst);
58 * </pre></blockquote><hr>
59 * <p>
60 * where {@code cnt} is a container, produces the following
61 * scrolling list:
62 * <p>
63 * <img src="doc-files/List-1.gif"
64 * alt="Shows a list containing: Venus, Earth, JavaSoft, and Mars. Javasoft is selected." style="float:center; margin: 7px 10px;">
65 * <p>
66 * If the List allows multiple selections, then clicking on
67 * an item that is already selected deselects it. In the preceding
68 * example, only one item from the scrolling list can be selected
69 * at a time, since the second argument when creating the new scrolling
70 * list is {@code false}. If the List does not allow multiple
71 * selections, selecting an item causes any other selected item
72 * to be deselected.
73 * <p>
74 * Note that the list in the example shown was created with four visible
75 * rows. Once the list has been created, the number of visible rows
76 * cannot be changed. A default {@code List} is created with
77 * four rows, so that {@code lst = new List()} is equivalent to
78 * {@code list = new List(4, false)}.
79 * <p>
80 * Beginning with Java 1.1, the Abstract Window Toolkit
81 * sends the {@code List} object all mouse, keyboard, and focus events
82 * that occur over it. (The old AWT event model is being maintained
83 * only for backwards compatibility, and its use is discouraged.)
84 * <p>
85 * When an item is selected or deselected by the user, AWT sends an instance
86 * of {@code ItemEvent} to the list.
87 * When the user double-clicks on an item in a scrolling list,
88 * AWT sends an instance of {@code ActionEvent} to the
89 * list following the item event. AWT also generates an action event
90 * when the user presses the return key while an item in the
91 * list is selected.
92 * <p>
93 * If an application wants to perform some action based on an item
94 * in this list being selected or activated by the user, it should implement
95 * {@code ItemListener} or {@code ActionListener}
96 * as appropriate and register the new listener to receive
97 * events from this list.
98 * <p>
99 * For multiple-selection scrolling lists, it is considered a better
100 * user interface to use an external gesture (such as clicking on a
101 * button) to trigger the action.
102 * @author Sami Shaio
103 * @see java.awt.event.ItemEvent
104 * @see java.awt.event.ItemListener
105 * @see java.awt.event.ActionEvent
106 * @see java.awt.event.ActionListener
107 * @since 1.0
108 */
109 public class List extends Component implements ItemSelectable, Accessible {
110 /**
111 * A vector created to contain items which will become
112 * part of the List Component.
113 *
114 * @serial
115 * @see #addItem(String)
116 * @see #getItem(int)
117 */
118 Vector<String> items = new Vector<>();
119
120 /**
121 * This field will represent the number of visible rows in the
122 * {@code List} Component. It is specified only once, and
123 * that is when the list component is actually
124 * created. It will never change.
125 *
126 * @serial
127 * @see #getRows()
128 */
129 int rows = 0;
130
131 /**
132 * {@code multipleMode} is a variable that will
133 * be set to {@code true} if a list component is to be set to
134 * multiple selection mode, that is where the user can
135 * select more than one item in a list at one time.
136 * {@code multipleMode} will be set to false if the
137 * list component is set to single selection, that is where
138 * the user can only select one item on the list at any
139 * one time.
140 *
141 * @serial
142 * @see #isMultipleMode()
143 * @see #setMultipleMode(boolean)
144 */
145 boolean multipleMode = false;
146
147 /**
148 * {@code selected} is an array that will contain
149 * the indices of items that have been selected.
150 *
151 * @serial
152 * @see #getSelectedIndexes()
153 * @see #getSelectedIndex()
154 */
155 int selected[] = new int[0];
156
157 /**
158 * This variable contains the value that will be used
159 * when trying to make a particular list item visible.
160 *
161 * @serial
162 * @see #makeVisible(int)
163 */
164 int visibleIndex = -1;
165
166 transient ActionListener actionListener;
167 transient ItemListener itemListener;
168
169 private static final String base = "list";
170 private static int nameCounter = 0;
171
172 /*
173 * JDK 1.1 serialVersionUID
174 */
175 private static final long serialVersionUID = -3304312411574666869L;
176
177 /**
178 * Creates a new scrolling list.
179 * By default, there are four visible lines and multiple selections are
180 * not allowed. Note that this is a convenience method for
181 * {@code List(0, false)}. Also note that the number of visible
182 * lines in the list cannot be changed after it has been created.
183 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
184 * returns true.
185 * @see java.awt.GraphicsEnvironment#isHeadless
186 */
187 public List() throws HeadlessException {
188 this(0, false);
189 }
190
191 /**
192 * Creates a new scrolling list initialized with the specified
193 * number of visible lines. By default, multiple selections are
194 * not allowed. Note that this is a convenience method for
195 * {@code List(rows, false)}. Also note that the number
196 * of visible rows in the list cannot be changed after it has
197 * been created.
198 * @param rows the number of items to show.
199 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
200 * returns true.
201 * @see java.awt.GraphicsEnvironment#isHeadless
202 * @since 1.1
203 */
204 public List(int rows) throws HeadlessException {
205 this(rows, false);
206 }
207
208 /**
209 * The default number of visible rows is 4. A list with
210 * zero rows is unusable and unsightly.
211 */
212 static final int DEFAULT_VISIBLE_ROWS = 4;
213
214 /**
215 * Creates a new scrolling list initialized to display the specified
216 * number of rows. Note that if zero rows are specified, then
217 * the list will be created with a default of four rows.
218 * Also note that the number of visible rows in the list cannot
219 * be changed after it has been created.
220 * If the value of {@code multipleMode} is
221 * {@code true}, then the user can select multiple items from
222 * the list. If it is {@code false}, only one item at a time
223 * can be selected.
224 * @param rows the number of items to show.
225 * @param multipleMode if {@code true},
226 * then multiple selections are allowed;
227 * otherwise, only one item can be selected at a time.
228 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
229 * returns true.
230 * @see java.awt.GraphicsEnvironment#isHeadless
231 */
232 public List(int rows, boolean multipleMode) throws HeadlessException {
233 GraphicsEnvironment.checkHeadless();
234 this.rows = (rows != 0) ? rows : DEFAULT_VISIBLE_ROWS;
235 this.multipleMode = multipleMode;
236 }
237
238 /**
239 * Construct a name for this component. Called by
240 * {@code getName} when the name is {@code null}.
241 */
242 String constructComponentName() {
243 synchronized (List.class) {
244 return base + nameCounter++;
245 }
246 }
247
248 /**
249 * Creates the peer for the list. The peer allows us to modify the
250 * list's appearance without changing its functionality.
251 */
252 public void addNotify() {
253 synchronized (getTreeLock()) {
254 if (peer == null)
255 peer = getComponentFactory().createList(this);
256 super.addNotify();
257 }
258 }
259
260 /**
269 }
270 super.removeNotify();
271 }
272 }
273
274 /**
275 * Gets the number of items in the list.
276 * @return the number of items in the list
277 * @see #getItem
278 * @since 1.1
279 */
280 public int getItemCount() {
281 return countItems();
282 }
283
284 /**
285 * Returns the number of items in the list.
286 *
287 * @return the number of items in the list
288 * @deprecated As of JDK version 1.1,
289 * replaced by {@code getItemCount()}.
290 */
291 @Deprecated
292 public int countItems() {
293 return items.size();
294 }
295
296 /**
297 * Gets the item associated with the specified index.
298 * @return an item that is associated with
299 * the specified index
300 * @param index the position of the item
301 * @see #getItemCount
302 */
303 public String getItem(int index) {
304 return getItemImpl(index);
305 }
306
307 // NOTE: This method may be called by privileged threads.
308 // We implement this functionality in a package-private method
309 // to insure that it cannot be overridden by client subclasses.
322 */
323 public synchronized String[] getItems() {
324 String itemCopies[] = new String[items.size()];
325 items.copyInto(itemCopies);
326 return itemCopies;
327 }
328
329 /**
330 * Adds the specified item to the end of scrolling list.
331 * @param item the item to be added
332 * @since 1.1
333 */
334 public void add(String item) {
335 addItem(item);
336 }
337
338 /**
339 * Adds the specified item to the end of the list.
340 *
341 * @param item the item to be added
342 * @deprecated replaced by {@code add(String)}.
343 */
344 @Deprecated
345 public void addItem(String item) {
346 addItem(item, -1);
347 }
348
349 /**
350 * Adds the specified item to the scrolling list
351 * at the position indicated by the index. The index is
352 * zero-based. If the value of the index is less than zero,
353 * or if the value of the index is greater than or equal to
354 * the number of items in the list, then the item is added
355 * to the end of the list.
356 * @param item the item to be added;
357 * if this parameter is {@code null} then the item is
358 * treated as an empty string, {@code ""}
359 * @param index the position at which to add the item
360 * @since 1.1
361 */
362 public void add(String item, int index) {
363 addItem(item, index);
364 }
365
366 /**
367 * Adds the specified item to the list
368 * at the position indicated by the index.
369 *
370 * @param item the item to be added
371 * @param index the position at which to add the item
372 * @deprecated replaced by {@code add(String, int)}.
373 */
374 @Deprecated
375 public synchronized void addItem(String item, int index) {
376 if (index < -1 || index >= items.size()) {
377 index = -1;
378 }
379
380 if (item == null) {
381 item = "";
382 }
383
384 if (index == -1) {
385 items.addElement(item);
386 } else {
387 items.insertElementAt(item, index);
388 }
389
390 ListPeer peer = (ListPeer)this.peer;
391 if (peer != null) {
392 peer.add(item, index);
393 }
394 }
395
396 /**
397 * Replaces the item at the specified index in the scrolling list
398 * with the new string.
399 * @param newValue a new string to replace an existing item
400 * @param index the position of the item to replace
401 * @exception ArrayIndexOutOfBoundsException if {@code index}
402 * is out of range
403 */
404 public synchronized void replaceItem(String newValue, int index) {
405 remove(index);
406 add(newValue, index);
407 }
408
409 /**
410 * Removes all items from this list.
411 * @see #remove
412 * @see #delItems
413 * @since 1.1
414 */
415 public void removeAll() {
416 clear();
417 }
418
419 /**
420 * @deprecated As of JDK version 1.1,
421 * replaced by {@code removeAll()}.
422 */
423 @Deprecated
424 public synchronized void clear() {
425 ListPeer peer = (ListPeer)this.peer;
426 if (peer != null) {
427 peer.removeAll();
428 }
429 items = new Vector<>();
430 selected = new int[0];
431 }
432
433 /**
434 * Removes the first occurrence of an item from the list.
435 * If the specified item is selected, and is the only selected
436 * item in the list, the list is set to have no selection.
437 * @param item the item to remove from the list
438 * @exception IllegalArgumentException
439 * if the item doesn't exist in the list
440 * @since 1.1
441 */
442 public synchronized void remove(String item) {
443 int index = items.indexOf(item);
444 if (index < 0) {
445 throw new IllegalArgumentException("item " + item +
446 " not found in list");
447 } else {
448 remove(index);
449 }
450 }
451
452 /**
453 * Removes the item at the specified position
454 * from this scrolling list.
455 * If the item with the specified position is selected, and is the
456 * only selected item in the list, the list is set to have no selection.
457 * @param position the index of the item to delete
458 * @see #add(String, int)
459 * @since 1.1
460 * @exception ArrayIndexOutOfBoundsException
461 * if the {@code position} is less than 0 or
462 * greater than {@code getItemCount()-1}
463 */
464 public void remove(int position) {
465 delItem(position);
466 }
467
468 /**
469 * Removes the item at the specified position.
470 *
471 * @param position the index of the item to delete
472 * @deprecated replaced by {@code remove(String)}
473 * and {@code remove(int)}.
474 */
475 @Deprecated
476 public void delItem(int position) {
477 delItems(position, position);
478 }
479
480 /**
481 * Gets the index of the selected item on the list,
482 *
483 * @return the index of the selected item;
484 * if no item is selected, or if multiple items are
485 * selected, {@code -1} is returned.
486 * @see #select
487 * @see #deselect
488 * @see #isIndexSelected
489 */
490 public synchronized int getSelectedIndex() {
491 int sel[] = getSelectedIndexes();
492 return (sel.length == 1) ? sel[0] : -1;
493 }
494
495 /**
496 * Gets the selected indexes on the list.
497 *
498 * @return an array of the selected indexes on this scrolling list;
499 * if no item is selected, a zero-length array is returned.
500 * @see #select
501 * @see #deselect
502 * @see #isIndexSelected
503 */
504 public synchronized int[] getSelectedIndexes() {
505 ListPeer peer = (ListPeer)this.peer;
506 if (peer != null) {
507 selected = peer.getSelectedIndexes();
508 }
509 return selected.clone();
510 }
511
512 /**
513 * Gets the selected item on this scrolling list.
514 *
515 * @return the selected item on the list;
516 * if no item is selected, or if multiple items are
517 * selected, {@code null} is returned.
518 * @see #select
519 * @see #deselect
520 * @see #isIndexSelected
521 */
522 public synchronized String getSelectedItem() {
523 int index = getSelectedIndex();
524 return (index < 0) ? null : getItem(index);
525 }
526
527 /**
528 * Gets the selected items on this scrolling list.
529 *
530 * @return an array of the selected items on this scrolling list;
531 * if no item is selected, a zero-length array is returned.
532 * @see #select
533 * @see #deselect
534 * @see #isIndexSelected
535 */
536 public synchronized String[] getSelectedItems() {
537 int sel[] = getSelectedIndexes();
538 String str[] = new String[sel.length];
539 for (int i = 0 ; i < sel.length ; i++) {
540 str[i] = getItem(sel[i]);
541 }
542 return str;
543 }
544
545 /**
546 * Gets the selected items on this scrolling list in an array of Objects.
547 * @return an array of {@code Object}s representing the
548 * selected items on this scrolling list;
549 * if no item is selected, a zero-length array is returned.
550 * @see #getSelectedItems
551 * @see ItemSelectable
552 */
553 public Object[] getSelectedObjects() {
554 return getSelectedItems();
555 }
556
557 /**
558 * Selects the item at the specified index in the scrolling list.
559 *<p>
560 * Note that passing out of range parameters is invalid,
561 * and will result in unspecified behavior.
562 *
563 * <p>Note that this method should be primarily used to
564 * initially select an item in this component.
565 * Programmatically calling this method will <i>not</i> trigger
566 * an {@code ItemEvent}. The only way to trigger an
567 * {@code ItemEvent} is by user interaction.
568 *
569 * @param index the position of the item to select
570 * @see #getSelectedItem
571 * @see #deselect
572 * @see #isIndexSelected
573 */
574 public void select(int index) {
575 // Bug #4059614: select can't be synchronized while calling the peer,
576 // because it is called from the Window Thread. It is sufficient to
577 // synchronize the code that manipulates 'selected' except for the
578 // case where the peer changes. To handle this case, we simply
579 // repeat the selection process.
580
581 ListPeer peer;
582 do {
583 peer = (ListPeer)this.peer;
584 if (peer != null) {
585 peer.select(index);
586 return;
587 }
632 if (isMultipleMode() || (getSelectedIndex() == index)) {
633 peer.deselect(index);
634 }
635 }
636
637 for (int i = 0 ; i < selected.length ; i++) {
638 if (selected[i] == index) {
639 int newsel[] = new int[selected.length - 1];
640 System.arraycopy(selected, 0, newsel, 0, i);
641 System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
642 selected = newsel;
643 return;
644 }
645 }
646 }
647
648 /**
649 * Determines if the specified item in this scrolling list is
650 * selected.
651 * @param index the item to be checked
652 * @return {@code true} if the specified item has been
653 * selected; {@code false} otherwise
654 * @see #select
655 * @see #deselect
656 * @since 1.1
657 */
658 public boolean isIndexSelected(int index) {
659 return isSelected(index);
660 }
661
662 /**
663 * Determines if the specified item in the list is selected.
664 *
665 * @param index specifies the item to be checked
666 * @return {@code true} if the item is selected; otherwise {@code false}
667 * @deprecated As of JDK version 1.1,
668 * replaced by {@code isIndexSelected(int)}.
669 */
670 @Deprecated
671 public boolean isSelected(int index) {
672 int sel[] = getSelectedIndexes();
673 for (int i = 0 ; i < sel.length ; i++) {
674 if (sel[i] == index) {
675 return true;
676 }
677 }
678 return false;
679 }
680
681 /**
682 * Gets the number of visible lines in this list. Note that
683 * once the {@code List} has been created, this number
684 * will never change.
685 * @return the number of visible lines in this scrolling list
686 */
687 public int getRows() {
688 return rows;
689 }
690
691 /**
692 * Determines whether this list allows multiple selections.
693 *
694 * @return {@code true} if this list allows multiple
695 * selections; otherwise, {@code false}
696 * @see #setMultipleMode
697 * @since 1.1
698 */
699 public boolean isMultipleMode() {
700 return allowsMultipleSelections();
701 }
702
703 /**
704 * Determines whether this list allows multiple selections.
705 *
706 * @return {@code true} if this list allows multiple
707 * selections; otherwise {@code false}
708 * @deprecated As of JDK version 1.1,
709 * replaced by {@code isMultipleMode()}.
710 */
711 @Deprecated
712 public boolean allowsMultipleSelections() {
713 return multipleMode;
714 }
715
716 /**
717 * Sets the flag that determines whether this list
718 * allows multiple selections.
719 * When the selection mode is changed from multiple-selection to
720 * single-selection, the selected items change as follows:
721 * If a selected item has the location cursor, only that
722 * item will remain selected. If no selected item has the
723 * location cursor, all items will be deselected.
724 * @param b if {@code true} then multiple selections
725 * are allowed; otherwise, only one item from
726 * the list can be selected at once
727 * @see #isMultipleMode
728 * @since 1.1
729 */
730 public void setMultipleMode(boolean b) {
731 setMultipleSelections(b);
732 }
733
734 /**
735 * Enables or disables multiple selection mode for this list.
736 *
737 * @param b {@code true} to enable multiple mode, {@code false} otherwise
738 * @deprecated As of JDK version 1.1,
739 * replaced by {@code setMultipleMode(boolean)}.
740 */
741 @Deprecated
742 public synchronized void setMultipleSelections(boolean b) {
743 if (b != multipleMode) {
744 multipleMode = b;
745 ListPeer peer = (ListPeer)this.peer;
746 if (peer != null) {
747 peer.setMultipleMode(b);
748 }
749 }
750 }
751
752 /**
753 * Gets the index of the item that was last made visible by
754 * the method {@code makeVisible}.
755 * @return the index of the item that was last made visible
756 * @see #makeVisible
757 */
758 public int getVisibleIndex() {
759 return visibleIndex;
760 }
761
762 /**
763 * Makes the item at the specified index visible.
764 * @param index the position of the item
765 * @see #getVisibleIndex
766 */
767 public synchronized void makeVisible(int index) {
768 visibleIndex = index;
769 ListPeer peer = (ListPeer)this.peer;
770 if (peer != null) {
771 peer.makeVisible(index);
772 }
773 }
774
775 /**
776 * Gets the preferred dimensions for a list with the specified
777 * number of rows.
778 * @param rows number of rows in the list
779 * @return the preferred dimensions for displaying this scrolling list
780 * given that the specified number of rows must be visible
781 * @see java.awt.Component#getPreferredSize
782 * @since 1.1
783 */
784 public Dimension getPreferredSize(int rows) {
785 return preferredSize(rows);
786 }
787
788 /**
789 * Returns the preferred size of this component
790 * assuming it has the specified number of rows.
791 *
792 * @param rows the number of rows
793 * @return the preferred dimensions for displaying this list
794 * @deprecated As of JDK version 1.1,
795 * replaced by {@code getPreferredSize(int)}.
796 */
797 @Deprecated
798 public Dimension preferredSize(int rows) {
799 synchronized (getTreeLock()) {
800 ListPeer peer = (ListPeer)this.peer;
801 return (peer != null) ?
802 peer.getPreferredSize(rows) :
803 super.preferredSize();
804 }
805 }
806
807 /**
808 * Gets the preferred size of this scrolling list.
809 * @return the preferred dimensions for displaying this scrolling list
810 * @see java.awt.Component#getPreferredSize
811 * @since 1.1
812 */
813 public Dimension getPreferredSize() {
814 return preferredSize();
815 }
816
817 /**
818 * @deprecated As of JDK version 1.1,
819 * replaced by {@code getPreferredSize()}.
820 */
821 @Deprecated
822 public Dimension preferredSize() {
823 synchronized (getTreeLock()) {
824 return (rows > 0) ?
825 preferredSize(rows) :
826 super.preferredSize();
827 }
828 }
829
830 /**
831 * Gets the minimum dimensions for a list with the specified
832 * number of rows.
833 * @param rows number of rows in the list
834 * @return the minimum dimensions for displaying this scrolling list
835 * given that the specified number of rows must be visible
836 * @see java.awt.Component#getMinimumSize
837 * @since 1.1
838 */
839 public Dimension getMinimumSize(int rows) {
840 return minimumSize(rows);
841 }
842
843 /**
844 * Returns the minimum dimensions for the list
845 * with the specified number of rows.
846 *
847 * @param rows the number of rows in the list
848 * @return the minimum dimensions for displaying this list
849 * @deprecated As of JDK version 1.1,
850 * replaced by {@code getMinimumSize(int)}.
851 */
852 @Deprecated
853 public Dimension minimumSize(int rows) {
854 synchronized (getTreeLock()) {
855 ListPeer peer = (ListPeer)this.peer;
856 return (peer != null) ?
857 peer.getMinimumSize(rows) :
858 super.minimumSize();
859 }
860 }
861
862 /**
863 * Determines the minimum size of this scrolling list.
864 * @return the minimum dimensions needed
865 * to display this scrolling list
866 * @see java.awt.Component#getMinimumSize()
867 * @since 1.1
868 */
869 public Dimension getMinimumSize() {
870 return minimumSize();
871 }
872
873 /**
874 * @deprecated As of JDK version 1.1,
875 * replaced by {@code getMinimumSize()}.
876 */
877 @Deprecated
878 public Dimension minimumSize() {
879 synchronized (getTreeLock()) {
880 return (rows > 0) ? minimumSize(rows) : super.minimumSize();
881 }
882 }
883
884 /**
885 * Adds the specified item listener to receive item events from
886 * this list. Item events are sent in response to user input, but not
887 * in response to calls to {@code select} or {@code deselect}.
888 * If listener {@code l} is {@code null},
889 * no exception is thrown and no action is performed.
890 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
891 * >AWT Threading Issues</a> for details on AWT's threading model.
892 *
893 * @param l the item listener
894 * @see #removeItemListener
895 * @see #getItemListeners
896 * @see #select
897 * @see #deselect
898 * @see java.awt.event.ItemEvent
899 * @see java.awt.event.ItemListener
900 * @since 1.1
901 */
902 public synchronized void addItemListener(ItemListener l) {
903 if (l == null) {
904 return;
905 }
906 itemListener = AWTEventMulticaster.add(itemListener, l);
907 newEventsOnly = true;
908 }
909
910 /**
911 * Removes the specified item listener so that it no longer
912 * receives item events from this list.
913 * If listener {@code l} is {@code null},
914 * no exception is thrown and no action is performed.
915 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
916 * >AWT Threading Issues</a> for details on AWT's threading model.
917 *
918 * @param l the item listener
919 * @see #addItemListener
920 * @see #getItemListeners
921 * @see java.awt.event.ItemEvent
922 * @see java.awt.event.ItemListener
923 * @since 1.1
924 */
925 public synchronized void removeItemListener(ItemListener l) {
926 if (l == null) {
927 return;
928 }
929 itemListener = AWTEventMulticaster.remove(itemListener, l);
930 }
931
932 /**
933 * Returns an array of all the item listeners
934 * registered on this list.
935 *
936 * @return all of this list's {@code ItemListener}s
937 * or an empty array if no item
938 * listeners are currently registered
939 *
940 * @see #addItemListener
941 * @see #removeItemListener
942 * @see java.awt.event.ItemEvent
943 * @see java.awt.event.ItemListener
944 * @since 1.4
945 */
946 public synchronized ItemListener[] getItemListeners() {
947 return getListeners(ItemListener.class);
948 }
949
950 /**
951 * Adds the specified action listener to receive action events from
952 * this list. Action events occur when a user double-clicks
953 * on a list item or types Enter when the list has the keyboard
954 * focus.
955 * <p>
956 * If listener {@code l} is {@code null},
957 * no exception is thrown and no action is performed.
958 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
959 * >AWT Threading Issues</a> for details on AWT's threading model.
960 *
961 * @param l the action listener
962 * @see #removeActionListener
963 * @see #getActionListeners
964 * @see java.awt.event.ActionEvent
965 * @see java.awt.event.ActionListener
966 * @since 1.1
967 */
968 public synchronized void addActionListener(ActionListener l) {
969 if (l == null) {
970 return;
971 }
972 actionListener = AWTEventMulticaster.add(actionListener, l);
973 newEventsOnly = true;
974 }
975
976 /**
977 * Removes the specified action listener so that it no longer
978 * receives action events from this list. Action events
979 * occur when a user double-clicks on a list item.
980 * If listener {@code l} is {@code null},
981 * no exception is thrown and no action is performed.
982 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
983 * >AWT Threading Issues</a> for details on AWT's threading model.
984 *
985 * @param l the action listener
986 * @see #addActionListener
987 * @see #getActionListeners
988 * @see java.awt.event.ActionEvent
989 * @see java.awt.event.ActionListener
990 * @since 1.1
991 */
992 public synchronized void removeActionListener(ActionListener l) {
993 if (l == null) {
994 return;
995 }
996 actionListener = AWTEventMulticaster.remove(actionListener, l);
997 }
998
999 /**
1000 * Returns an array of all the action listeners
1001 * registered on this list.
1002 *
1003 * @return all of this list's {@code ActionListener}s
1004 * or an empty array if no action
1005 * listeners are currently registered
1006 *
1007 * @see #addActionListener
1008 * @see #removeActionListener
1009 * @see java.awt.event.ActionEvent
1010 * @see java.awt.event.ActionListener
1011 * @since 1.4
1012 */
1013 public synchronized ActionListener[] getActionListeners() {
1014 return getListeners(ActionListener.class);
1015 }
1016
1017 /**
1018 * Returns an array of all the objects currently registered
1019 * as <code><em>Foo</em>Listener</code>s
1020 * upon this {@code List}.
1021 * <code><em>Foo</em>Listener</code>s are registered using the
1022 * <code>add<em>Foo</em>Listener</code> method.
1023 *
1024 * <p>
1025 * You can specify the {@code listenerType} argument
1026 * with a class literal, such as
1027 * <code><em>Foo</em>Listener.class</code>.
1028 * For example, you can query a
1029 * {@code List l}
1030 * for its item listeners with the following code:
1031 *
1032 * <pre>ItemListener[] ils = (ItemListener[])(l.getListeners(ItemListener.class));</pre>
1033 *
1034 * If no such listeners exist, this method returns an empty array.
1035 *
1036 * @param listenerType the type of listeners requested; this parameter
1037 * should specify an interface that descends from
1038 * {@code java.util.EventListener}
1039 * @return an array of all objects registered as
1040 * <code><em>Foo</em>Listener</code>s on this list,
1041 * or an empty array if no such
1042 * listeners have been added
1043 * @exception ClassCastException if {@code listenerType}
1044 * doesn't specify a class or interface that implements
1045 * {@code java.util.EventListener}
1046 *
1047 * @see #getItemListeners
1048 * @since 1.3
1049 */
1050 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1051 EventListener l = null;
1052 if (listenerType == ActionListener.class) {
1053 l = actionListener;
1054 } else if (listenerType == ItemListener.class) {
1055 l = itemListener;
1056 } else {
1057 return super.getListeners(listenerType);
1058 }
1059 return AWTEventMulticaster.getListeners(l, listenerType);
1060 }
1061
1062 // REMIND: remove when filtering is done at lower level
1063 boolean eventEnabled(AWTEvent e) {
1064 switch(e.id) {
1065 case ActionEvent.ACTION_PERFORMED:
1066 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
1067 actionListener != null) {
1068 return true;
1069 }
1070 return false;
1071 case ItemEvent.ITEM_STATE_CHANGED:
1072 if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
1073 itemListener != null) {
1074 return true;
1075 }
1076 return false;
1077 default:
1078 break;
1079 }
1080 return super.eventEnabled(e);
1081 }
1082
1083 /**
1084 * Processes events on this scrolling list. If an event is
1085 * an instance of {@code ItemEvent}, it invokes the
1086 * {@code processItemEvent} method. Else, if the
1087 * event is an instance of {@code ActionEvent},
1088 * it invokes {@code processActionEvent}.
1089 * If the event is not an item event or an action event,
1090 * it invokes {@code processEvent} on the superclass.
1091 * <p>Note that if the event parameter is {@code null}
1092 * the behavior is unspecified and may result in an
1093 * exception.
1094 *
1095 * @param e the event
1096 * @see java.awt.event.ActionEvent
1097 * @see java.awt.event.ItemEvent
1098 * @see #processActionEvent
1099 * @see #processItemEvent
1100 * @since 1.1
1101 */
1102 protected void processEvent(AWTEvent e) {
1103 if (e instanceof ItemEvent) {
1104 processItemEvent((ItemEvent)e);
1105 return;
1106 } else if (e instanceof ActionEvent) {
1107 processActionEvent((ActionEvent)e);
1108 return;
1109 }
1110 super.processEvent(e);
1111 }
1112
1113 /**
1114 * Processes item events occurring on this list by
1115 * dispatching them to any registered
1116 * {@code ItemListener} objects.
1117 * <p>
1118 * This method is not called unless item events are
1119 * enabled for this component. Item events are enabled
1120 * when one of the following occurs:
1121 * <ul>
1122 * <li>An {@code ItemListener} object is registered
1123 * via {@code addItemListener}.
1124 * <li>Item events are enabled via {@code enableEvents}.
1125 * </ul>
1126 * <p>Note that if the event parameter is {@code null}
1127 * the behavior is unspecified and may result in an
1128 * exception.
1129 *
1130 * @param e the item event
1131 * @see java.awt.event.ItemEvent
1132 * @see java.awt.event.ItemListener
1133 * @see #addItemListener
1134 * @see java.awt.Component#enableEvents
1135 * @since 1.1
1136 */
1137 protected void processItemEvent(ItemEvent e) {
1138 ItemListener listener = itemListener;
1139 if (listener != null) {
1140 listener.itemStateChanged(e);
1141 }
1142 }
1143
1144 /**
1145 * Processes action events occurring on this component
1146 * by dispatching them to any registered
1147 * {@code ActionListener} objects.
1148 * <p>
1149 * This method is not called unless action events are
1150 * enabled for this component. Action events are enabled
1151 * when one of the following occurs:
1152 * <ul>
1153 * <li>An {@code ActionListener} object is registered
1154 * via {@code addActionListener}.
1155 * <li>Action events are enabled via {@code enableEvents}.
1156 * </ul>
1157 * <p>Note that if the event parameter is {@code null}
1158 * the behavior is unspecified and may result in an
1159 * exception.
1160 *
1161 * @param e the action event
1162 * @see java.awt.event.ActionEvent
1163 * @see java.awt.event.ActionListener
1164 * @see #addActionListener
1165 * @see java.awt.Component#enableEvents
1166 * @since 1.1
1167 */
1168 protected void processActionEvent(ActionEvent e) {
1169 ActionListener listener = actionListener;
1170 if (listener != null) {
1171 listener.actionPerformed(e);
1172 }
1173 }
1174
1175 /**
1176 * Returns the parameter string representing the state of this
1177 * scrolling list. This string is useful for debugging.
1192 * private method.
1193 */
1194 @Deprecated
1195 public synchronized void delItems(int start, int end) {
1196 for (int i = end; i >= start; i--) {
1197 items.removeElementAt(i);
1198 }
1199 ListPeer peer = (ListPeer)this.peer;
1200 if (peer != null) {
1201 peer.delItems(start, end);
1202 }
1203 }
1204
1205 /*
1206 * Serialization support. Since the value of the selected
1207 * field isn't necessarily up to date, we sync it up with the
1208 * peer before serializing.
1209 */
1210
1211 /**
1212 * The {@code List} component's
1213 * Serialized Data Version.
1214 *
1215 * @serial
1216 */
1217 private int listSerializedDataVersion = 1;
1218
1219 /**
1220 * Writes default serializable fields to stream. Writes
1221 * a list of serializable {@code ItemListeners}
1222 * and {@code ActionListeners} as optional data.
1223 * The non-serializable listeners are detected and
1224 * no attempt is made to serialize them.
1225 *
1226 * @serialData {@code null} terminated sequence of 0
1227 * or more pairs; the pair consists of a {@code String}
1228 * and an {@code Object}; the {@code String}
1229 * indicates the type of object and is one of the
1230 * following:
1231 * {@code itemListenerK} indicating an
1232 * {@code ItemListener} object;
1233 * {@code actionListenerK} indicating an
1234 * {@code ActionListener} object
1235 *
1236 * @param s the {@code ObjectOutputStream} to write
1237 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1238 * @see java.awt.Component#itemListenerK
1239 * @see java.awt.Component#actionListenerK
1240 * @see #readObject(ObjectInputStream)
1241 */
1242 private void writeObject(ObjectOutputStream s)
1243 throws IOException
1244 {
1245 synchronized (this) {
1246 ListPeer peer = (ListPeer)this.peer;
1247 if (peer != null) {
1248 selected = peer.getSelectedIndexes();
1249 }
1250 }
1251 s.defaultWriteObject();
1252
1253 AWTEventMulticaster.save(s, itemListenerK, itemListener);
1254 AWTEventMulticaster.save(s, actionListenerK, actionListener);
1255 s.writeObject(null);
1256 }
1257
1258 /**
1259 * Reads the {@code ObjectInputStream} and if it
1260 * isn't {@code null} adds a listener to receive
1261 * both item events and action events (as specified
1262 * by the key stored in the stream) fired by the
1263 * {@code List}.
1264 * Unrecognized keys or values will be ignored.
1265 *
1266 * @param s the {@code ObjectInputStream} to write
1267 * @exception HeadlessException if
1268 * {@code GraphicsEnvironment.isHeadless} returns
1269 * {@code true}
1270 * @see #removeItemListener(ItemListener)
1271 * @see #addItemListener(ItemListener)
1272 * @see java.awt.GraphicsEnvironment#isHeadless
1273 * @see #writeObject(ObjectOutputStream)
1274 */
1275 private void readObject(ObjectInputStream s)
1276 throws ClassNotFoundException, IOException, HeadlessException
1277 {
1278 GraphicsEnvironment.checkHeadless();
1279 s.defaultReadObject();
1280
1281 Object keyOrNull;
1282 while(null != (keyOrNull = s.readObject())) {
1283 String key = ((String)keyOrNull).intern();
1284
1285 if (itemListenerK == key)
1286 addItemListener((ItemListener)(s.readObject()));
1287
1288 else if (actionListenerK == key)
1289 addActionListener((ActionListener)(s.readObject()));
1290
1291 else // skip value for unrecognized key
1292 s.readObject();
1293 }
1294 }
1295
1296
1297 /////////////////
1298 // Accessibility support
1299 ////////////////
1300
1301
1302 /**
1303 * Gets the {@code AccessibleContext} associated with this
1304 * {@code List}. For lists, the {@code AccessibleContext}
1305 * takes the form of an {@code AccessibleAWTList}.
1306 * A new {@code AccessibleAWTList} instance is created, if necessary.
1307 *
1308 * @return an {@code AccessibleAWTList} that serves as the
1309 * {@code AccessibleContext} of this {@code List}
1310 * @since 1.3
1311 */
1312 public AccessibleContext getAccessibleContext() {
1313 if (accessibleContext == null) {
1314 accessibleContext = new AccessibleAWTList();
1315 }
1316 return accessibleContext;
1317 }
1318
1319 /**
1320 * This class implements accessibility support for the
1321 * {@code List} class. It provides an implementation of the
1322 * Java Accessibility API appropriate to list user-interface elements.
1323 * @since 1.3
1324 */
1325 protected class AccessibleAWTList extends AccessibleAWTComponent
1326 implements AccessibleSelection, ItemListener, ActionListener
1327 {
1328 /*
1329 * JDK 1.3 serialVersionUID
1330 */
1331 private static final long serialVersionUID = 7924617370136012829L;
1332
1333 /**
1334 * Constructs new {@code AccessibleAWTList}
1335 */
1336 public AccessibleAWTList() {
1337 super();
1338 List.this.addActionListener(this);
1339 List.this.addItemListener(this);
1340 }
1341
1913 * @return A Dimension object that indicates the size of this
1914 * component; null if this object is not on the screen
1915 * @see #setSize
1916 */
1917 public Dimension getSize() {
1918 // [[[FIXME]]]
1919 return null;
1920 }
1921
1922 /**
1923 * Resizes this object so that it has width and height.
1924 *
1925 * @param d - The dimension specifying the new size of the object.
1926 * @see #getSize
1927 */
1928 public void setSize(Dimension d) {
1929 // not supported; no-op
1930 }
1931
1932 /**
1933 * Returns the {@code Accessible} child, if one exists,
1934 * contained at the local coordinate {@code Point}.
1935 *
1936 * @param p the point relative to the coordinate system of this
1937 * object
1938 * @return the {@code Accessible}, if it exists,
1939 * at the specified location; otherwise {@code null}
1940 */
1941 public Accessible getAccessibleAt(Point p) {
1942 return null; // object cannot have children!
1943 }
1944
1945 /**
1946 * Returns whether this object can accept focus or not. Objects
1947 * that can accept focus will also have the
1948 * {@code AccessibleState.FOCUSABLE} state set in their
1949 * {@code AccessibleStateSet}.
1950 *
1951 * @return true if object can accept focus; otherwise false
1952 * @see AccessibleContext#getAccessibleStateSet
1953 * @see AccessibleState#FOCUSABLE
1954 * @see AccessibleState#FOCUSED
1955 * @see AccessibleStateSet
1956 */
1957 public boolean isFocusTraversable() {
1958 return false; // list element cannot receive focus!
1959 }
1960
1961 /**
1962 * Requests focus for this object. If this object cannot accept
1963 * focus, nothing will happen. Otherwise, the object will attempt
1964 * to take focus.
1965 * @see #isFocusTraversable
1966 */
1967 public void requestFocus() {
1968 // nothing to do; a no-op
1969 }
|