1 /*
2 * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 * <p>
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." ALIGN=center HSPACE=10 VSPACE=7>
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 JDK1.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 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 JDK1.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 final static 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 = getToolkit().createList(this);
256 super.addNotify();
257 }
258 }
259
260 /**
261 * Removes the peer for this list. The peer allows us to modify the
262 * list's appearance without changing its functionality.
263 */
264 public void removeNotify() {
265 synchronized (getTreeLock()) {
266 ListPeer peer = (ListPeer)this.peer;
267 if (peer != null) {
268 selected = peer.getSelectedIndexes();
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 JDK1.1
279 */
280 public int getItemCount() {
281 return countItems();
282 }
283
284 /**
285 * @deprecated As of JDK version 1.1,
286 * replaced by <code>getItemCount()</code>.
287 */
288 @Deprecated
289 public int countItems() {
290 return items.size();
291 }
292
293 /**
294 * Gets the item associated with the specified index.
295 * @return an item that is associated with
296 * the specified index
297 * @param index the position of the item
298 * @see #getItemCount
299 */
300 public String getItem(int index) {
301 return getItemImpl(index);
302 }
303
304 // NOTE: This method may be called by privileged threads.
305 // We implement this functionality in a package-private method
306 // to insure that it cannot be overridden by client subclasses.
307 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
308 final String getItemImpl(int index) {
309 return (String)items.elementAt(index);
310 }
311
312 /**
313 * Gets the items in the list.
314 * @return a string array containing items of the list
315 * @see #select
316 * @see #deselect
317 * @see #isIndexSelected
318 * @since JDK1.1
319 */
320 public synchronized String[] getItems() {
321 String itemCopies[] = new String[items.size()];
322 items.copyInto(itemCopies);
323 return itemCopies;
324 }
325
326 /**
327 * Adds the specified item to the end of scrolling list.
328 * @param item the item to be added
329 * @since JDK1.1
330 */
331 public void add(String item) {
332 addItem(item);
333 }
334
335 /**
336 * @deprecated replaced by <code>add(String)</code>.
337 */
338 @Deprecated
339 public void addItem(String item) {
340 addItem(item, -1);
341 }
342
343 /**
344 * Adds the specified item to the the scrolling list
345 * at the position indicated by the index. The index is
346 * zero-based. If the value of the index is less than zero,
347 * or if the value of the index is greater than or equal to
348 * the number of items in the list, then the item is added
349 * to the end of the list.
350 * @param item the item to be added;
351 * if this parameter is <code>null</code> then the item is
352 * treated as an empty string, <code>""</code>
353 * @param index the position at which to add the item
354 * @since JDK1.1
355 */
356 public void add(String item, int index) {
357 addItem(item, index);
358 }
359
360 /**
361 * @deprecated replaced by <code>add(String, int)</code>.
362 */
363 @Deprecated
364 public synchronized void addItem(String item, int index) {
365 if (index < -1 || index >= items.size()) {
366 index = -1;
367 }
368
369 if (item == null) {
370 item = "";
371 }
372
373 if (index == -1) {
374 items.addElement(item);
375 } else {
376 items.insertElementAt(item, index);
377 }
378
379 ListPeer peer = (ListPeer)this.peer;
380 if (peer != null) {
381 peer.addItem(item, index);
382 }
383 }
384
385 /**
386 * Replaces the item at the specified index in the scrolling list
387 * with the new string.
388 * @param newValue a new string to replace an existing item
389 * @param index the position of the item to replace
390 * @exception ArrayIndexOutOfBoundsException if <code>index</code>
391 * is out of range
392 */
393 public synchronized void replaceItem(String newValue, int index) {
394 remove(index);
395 add(newValue, index);
396 }
397
398 /**
399 * Removes all items from this list.
400 * @see #remove
401 * @see #delItems
402 * @since JDK1.1
403 */
404 public void removeAll() {
405 clear();
406 }
407
408 /**
409 * @deprecated As of JDK version 1.1,
410 * replaced by <code>removeAll()</code>.
411 */
412 @Deprecated
413 public synchronized void clear() {
414 ListPeer peer = (ListPeer)this.peer;
415 if (peer != null) {
416 peer.clear();
417 }
418 items = new Vector();
419 selected = new int[0];
420 }
421
422 /**
423 * Removes the first occurrence of an item from the list.
424 * If the specified item is selected, and is the only selected
425 * item in the list, the list is set to have no selection.
426 * @param item the item to remove from the list
427 * @exception IllegalArgumentException
428 * if the item doesn't exist in the list
429 * @since JDK1.1
430 */
431 public synchronized void remove(String item) {
432 int index = items.indexOf(item);
433 if (index < 0) {
434 throw new IllegalArgumentException("item " + item +
435 " not found in list");
436 } else {
437 remove(index);
438 }
439 }
440
441 /**
442 * Removes the item at the specified position
443 * from this scrolling list.
444 * If the item with the specified position is selected, and is the
445 * only selected item in the list, the list is set to have no selection.
446 * @param position the index of the item to delete
447 * @see #add(String, int)
448 * @since JDK1.1
449 * @exception ArrayIndexOutOfBoundsException
450 * if the <code>position</code> is less than 0 or
451 * greater than <code>getItemCount()-1</code>
452 */
453 public void remove(int position) {
454 delItem(position);
455 }
456
457 /**
458 * @deprecated replaced by <code>remove(String)</code>
459 * and <code>remove(int)</code>.
460 */
461 @Deprecated
462 public void delItem(int position) {
463 delItems(position, position);
464 }
465
466 /**
467 * Gets the index of the selected item on the list,
468 *
469 * @return the index of the selected item;
470 * if no item is selected, or if multiple items are
471 * selected, <code>-1</code> is returned.
472 * @see #select
473 * @see #deselect
474 * @see #isIndexSelected
475 */
476 public synchronized int getSelectedIndex() {
477 int sel[] = getSelectedIndexes();
478 return (sel.length == 1) ? sel[0] : -1;
479 }
480
481 /**
482 * Gets the selected indexes on the list.
483 *
484 * @return an array of the selected indexes on this scrolling list;
485 * if no item is selected, a zero-length array is returned.
486 * @see #select
487 * @see #deselect
488 * @see #isIndexSelected
489 */
490 public synchronized int[] getSelectedIndexes() {
491 ListPeer peer = (ListPeer)this.peer;
492 if (peer != null) {
493 selected = ((ListPeer)peer).getSelectedIndexes();
494 }
495 return (int[])selected.clone();
496 }
497
498 /**
499 * Gets the selected item on this scrolling list.
500 *
501 * @return the selected item on the list;
502 * if no item is selected, or if multiple items are
503 * selected, <code>null</code> is returned.
504 * @see #select
505 * @see #deselect
506 * @see #isIndexSelected
507 */
508 public synchronized String getSelectedItem() {
509 int index = getSelectedIndex();
510 return (index < 0) ? null : getItem(index);
511 }
512
513 /**
514 * Gets the selected items on this scrolling list.
515 *
516 * @return an array of the selected items on this scrolling list;
517 * if no item is selected, a zero-length array is returned.
518 * @see #select
519 * @see #deselect
520 * @see #isIndexSelected
521 */
522 public synchronized String[] getSelectedItems() {
523 int sel[] = getSelectedIndexes();
524 String str[] = new String[sel.length];
525 for (int i = 0 ; i < sel.length ; i++) {
526 str[i] = getItem(sel[i]);
527 }
528 return str;
529 }
530
531 /**
532 * Gets the selected items on this scrolling list in an array of Objects.
533 * @return an array of <code>Object</code>s representing the
534 * selected items on this scrolling list;
535 * if no item is selected, a zero-length array is returned.
536 * @see #getSelectedItems
537 * @see ItemSelectable
538 */
539 public Object[] getSelectedObjects() {
540 return getSelectedItems();
541 }
542
543 /**
544 * Selects the item at the specified index in the scrolling list.
545 *<p>
546 * Note that passing out of range parameters is invalid,
547 * and will result in unspecified behavior.
548 *
549 * <p>Note that this method should be primarily used to
550 * initially select an item in this component.
551 * Programmatically calling this method will <i>not</i> trigger
552 * an <code>ItemEvent</code>. The only way to trigger an
553 * <code>ItemEvent</code> is by user interaction.
554 *
555 * @param index the position of the item to select
556 * @see #getSelectedItem
557 * @see #deselect
558 * @see #isIndexSelected
559 */
560 public void select(int index) {
561 // Bug #4059614: select can't be synchronized while calling the peer,
562 // because it is called from the Window Thread. It is sufficient to
563 // synchronize the code that manipulates 'selected' except for the
564 // case where the peer changes. To handle this case, we simply
565 // repeat the selection process.
566
567 ListPeer peer;
568 do {
569 peer = (ListPeer)this.peer;
570 if (peer != null) {
571 peer.select(index);
572 return;
573 }
574
575 synchronized(this)
576 {
577 boolean alreadySelected = false;
578
579 for (int i = 0 ; i < selected.length ; i++) {
580 if (selected[i] == index) {
581 alreadySelected = true;
582 break;
583 }
584 }
585
586 if (!alreadySelected) {
587 if (!multipleMode) {
588 selected = new int[1];
589 selected[0] = index;
590 } else {
591 int newsel[] = new int[selected.length + 1];
592 System.arraycopy(selected, 0, newsel, 0,
593 selected.length);
594 newsel[selected.length] = index;
595 selected = newsel;
596 }
597 }
598 }
599 } while (peer != this.peer);
600 }
601
602 /**
603 * Deselects the item at the specified index.
604 * <p>
605 * Note that passing out of range parameters is invalid,
606 * and will result in unspecified behavior.
607 * <p>
608 * If the item at the specified index is not selected,
609 * then the operation is ignored.
610 * @param index the position of the item to deselect
611 * @see #select
612 * @see #getSelectedItem
613 * @see #isIndexSelected
614 */
615 public synchronized void deselect(int index) {
616 ListPeer peer = (ListPeer)this.peer;
617 if (peer != null) {
618 if (isMultipleMode() || (getSelectedIndex() == index)) {
619 peer.deselect(index);
620 }
621 }
622
623 for (int i = 0 ; i < selected.length ; i++) {
624 if (selected[i] == index) {
625 int newsel[] = new int[selected.length - 1];
626 System.arraycopy(selected, 0, newsel, 0, i);
627 System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
628 selected = newsel;
629 return;
630 }
631 }
632 }
633
634 /**
635 * Determines if the specified item in this scrolling list is
636 * selected.
637 * @param index the item to be checked
638 * @return <code>true</code> if the specified item has been
639 * selected; <code>false</code> otherwise
640 * @see #select
641 * @see #deselect
642 * @since JDK1.1
643 */
644 public boolean isIndexSelected(int index) {
645 return isSelected(index);
646 }
647
648 /**
649 * @deprecated As of JDK version 1.1,
650 * replaced by <code>isIndexSelected(int)</code>.
651 */
652 @Deprecated
653 public boolean isSelected(int index) {
654 int sel[] = getSelectedIndexes();
655 for (int i = 0 ; i < sel.length ; i++) {
656 if (sel[i] == index) {
657 return true;
658 }
659 }
660 return false;
661 }
662
663 /**
664 * Gets the number of visible lines in this list. Note that
665 * once the <code>List</code> has been created, this number
666 * will never change.
667 * @return the number of visible lines in this scrolling list
668 */
669 public int getRows() {
670 return rows;
671 }
672
673 /**
674 * Determines whether this list allows multiple selections.
675 * @return <code>true</code> if this list allows multiple
676 * selections; otherwise, <code>false</code>
677 * @see #setMultipleMode
678 * @since JDK1.1
679 */
680 public boolean isMultipleMode() {
681 return allowsMultipleSelections();
682 }
683
684 /**
685 * @deprecated As of JDK version 1.1,
686 * replaced by <code>isMultipleMode()</code>.
687 */
688 @Deprecated
689 public boolean allowsMultipleSelections() {
690 return multipleMode;
691 }
692
693 /**
694 * Sets the flag that determines whether this list
695 * allows multiple selections.
696 * When the selection mode is changed from multiple-selection to
697 * single-selection, the selected items change as follows:
698 * If a selected item has the location cursor, only that
699 * item will remain selected. If no selected item has the
700 * location cursor, all items will be deselected.
701 * @param b if <code>true</code> then multiple selections
702 * are allowed; otherwise, only one item from
703 * the list can be selected at once
704 * @see #isMultipleMode
705 * @since JDK1.1
706 */
707 public void setMultipleMode(boolean b) {
708 setMultipleSelections(b);
709 }
710
711 /**
712 * @deprecated As of JDK version 1.1,
713 * replaced by <code>setMultipleMode(boolean)</code>.
714 */
715 @Deprecated
716 public synchronized void setMultipleSelections(boolean b) {
717 if (b != multipleMode) {
718 multipleMode = b;
719 ListPeer peer = (ListPeer)this.peer;
720 if (peer != null) {
721 peer.setMultipleSelections(b);
722 }
723 }
724 }
725
726 /**
727 * Gets the index of the item that was last made visible by
728 * the method <code>makeVisible</code>.
729 * @return the index of the item that was last made visible
730 * @see #makeVisible
731 */
732 public int getVisibleIndex() {
733 return visibleIndex;
734 }
735
736 /**
737 * Makes the item at the specified index visible.
738 * @param index the position of the item
739 * @see #getVisibleIndex
740 */
741 public synchronized void makeVisible(int index) {
742 visibleIndex = index;
743 ListPeer peer = (ListPeer)this.peer;
744 if (peer != null) {
745 peer.makeVisible(index);
746 }
747 }
748
749 /**
750 * Gets the preferred dimensions for a list with the specified
751 * number of rows.
752 * @param rows number of rows in the list
753 * @return the preferred dimensions for displaying this scrolling list
754 * given that the specified number of rows must be visible
755 * @see java.awt.Component#getPreferredSize
756 * @since JDK1.1
757 */
758 public Dimension getPreferredSize(int rows) {
759 return preferredSize(rows);
760 }
761
762 /**
763 * @deprecated As of JDK version 1.1,
764 * replaced by <code>getPreferredSize(int)</code>.
765 */
766 @Deprecated
767 public Dimension preferredSize(int rows) {
768 synchronized (getTreeLock()) {
769 ListPeer peer = (ListPeer)this.peer;
770 return (peer != null) ?
771 peer.preferredSize(rows) :
772 super.preferredSize();
773 }
774 }
775
776 /**
777 * Gets the preferred size of this scrolling list.
778 * @return the preferred dimensions for displaying this scrolling list
779 * @see java.awt.Component#getPreferredSize
780 * @since JDK1.1
781 */
782 public Dimension getPreferredSize() {
783 return preferredSize();
784 }
785
786 /**
787 * @deprecated As of JDK version 1.1,
788 * replaced by <code>getPreferredSize()</code>.
789 */
790 @Deprecated
791 public Dimension preferredSize() {
792 synchronized (getTreeLock()) {
793 return (rows > 0) ?
794 preferredSize(rows) :
795 super.preferredSize();
796 }
797 }
798
799 /**
800 * Gets the minumum dimensions for a list with the specified
801 * number of rows.
802 * @param rows number of rows in the list
803 * @return the minimum dimensions for displaying this scrolling list
804 * given that the specified number of rows must be visible
805 * @see java.awt.Component#getMinimumSize
806 * @since JDK1.1
807 */
808 public Dimension getMinimumSize(int rows) {
809 return minimumSize(rows);
810 }
811
812 /**
813 * @deprecated As of JDK version 1.1,
814 * replaced by <code>getMinimumSize(int)</code>.
815 */
816 @Deprecated
817 public Dimension minimumSize(int rows) {
818 synchronized (getTreeLock()) {
819 ListPeer peer = (ListPeer)this.peer;
820 return (peer != null) ?
821 peer.minimumSize(rows) :
822 super.minimumSize();
823 }
824 }
825
826 /**
827 * Determines the minimum size of this scrolling list.
828 * @return the minimum dimensions needed
829 * to display this scrolling list
830 * @see java.awt.Component#getMinimumSize()
831 * @since JDK1.1
832 */
833 public Dimension getMinimumSize() {
834 return minimumSize();
835 }
836
837 /**
838 * @deprecated As of JDK version 1.1,
839 * replaced by <code>getMinimumSize()</code>.
840 */
841 @Deprecated
842 public Dimension minimumSize() {
843 synchronized (getTreeLock()) {
844 return (rows > 0) ? minimumSize(rows) : super.minimumSize();
845 }
846 }
847
848 /**
849 * Adds the specified item listener to receive item events from
850 * this list. Item events are sent in response to user input, but not
851 * in response to calls to <code>select</code> or <code>deselect</code>.
852 * If listener <code>l</code> is <code>null</code>,
853 * no exception is thrown and no action is performed.
854 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
855 * >AWT Threading Issues</a> for details on AWT's threading model.
856 *
857 * @param l the item listener
858 * @see #removeItemListener
859 * @see #getItemListeners
860 * @see #select
861 * @see #deselect
862 * @see java.awt.event.ItemEvent
863 * @see java.awt.event.ItemListener
864 * @since JDK1.1
865 */
866 public synchronized void addItemListener(ItemListener l) {
867 if (l == null) {
868 return;
869 }
870 itemListener = AWTEventMulticaster.add(itemListener, l);
871 newEventsOnly = true;
872 }
873
874 /**
875 * Removes the specified item listener so that it no longer
876 * receives item events from this list.
877 * If listener <code>l</code> is <code>null</code>,
878 * no exception is thrown and no action is performed.
879 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
880 * >AWT Threading Issues</a> for details on AWT's threading model.
881 *
882 * @param l the item listener
883 * @see #addItemListener
884 * @see #getItemListeners
885 * @see java.awt.event.ItemEvent
886 * @see java.awt.event.ItemListener
887 * @since JDK1.1
888 */
889 public synchronized void removeItemListener(ItemListener l) {
890 if (l == null) {
891 return;
892 }
893 itemListener = AWTEventMulticaster.remove(itemListener, l);
894 }
895
896 /**
897 * Returns an array of all the item listeners
898 * registered on this list.
899 *
900 * @return all of this list's <code>ItemListener</code>s
901 * or an empty array if no item
902 * listeners are currently registered
903 *
904 * @see #addItemListener
905 * @see #removeItemListener
906 * @see java.awt.event.ItemEvent
907 * @see java.awt.event.ItemListener
908 * @since 1.4
909 */
910 public synchronized ItemListener[] getItemListeners() {
911 return (ItemListener[])(getListeners(ItemListener.class));
912 }
913
914 /**
915 * Adds the specified action listener to receive action events from
916 * this list. Action events occur when a user double-clicks
917 * on a list item or types Enter when the list has the keyboard
918 * focus.
919 * <p>
920 * If listener <code>l</code> is <code>null</code>,
921 * no exception is thrown and no action is performed.
922 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
923 * >AWT Threading Issues</a> for details on AWT's threading model.
924 *
925 * @param l the action listener
926 * @see #removeActionListener
927 * @see #getActionListeners
928 * @see java.awt.event.ActionEvent
929 * @see java.awt.event.ActionListener
930 * @since JDK1.1
931 */
932 public synchronized void addActionListener(ActionListener l) {
933 if (l == null) {
934 return;
935 }
936 actionListener = AWTEventMulticaster.add(actionListener, l);
937 newEventsOnly = true;
938 }
939
940 /**
941 * Removes the specified action listener so that it no longer
942 * receives action events from this list. Action events
943 * occur when a user double-clicks on a list item.
944 * If listener <code>l</code> is <code>null</code>,
945 * no exception is thrown and no action is performed.
946 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
947 * >AWT Threading Issues</a> for details on AWT's threading model.
948 *
949 * @param l the action listener
950 * @see #addActionListener
951 * @see #getActionListeners
952 * @see java.awt.event.ActionEvent
953 * @see java.awt.event.ActionListener
954 * @since JDK1.1
955 */
956 public synchronized void removeActionListener(ActionListener l) {
957 if (l == null) {
958 return;
959 }
960 actionListener = AWTEventMulticaster.remove(actionListener, l);
961 }
962
963 /**
964 * Returns an array of all the action listeners
965 * registered on this list.
966 *
967 * @return all of this list's <code>ActionListener</code>s
968 * or an empty array if no action
969 * listeners are currently registered
970 *
971 * @see #addActionListener
972 * @see #removeActionListener
973 * @see java.awt.event.ActionEvent
974 * @see java.awt.event.ActionListener
975 * @since 1.4
976 */
977 public synchronized ActionListener[] getActionListeners() {
978 return (ActionListener[])(getListeners(ActionListener.class));
979 }
980
981 /**
982 * Returns an array of all the objects currently registered
983 * as <code><em>Foo</em>Listener</code>s
984 * upon this <code>List</code>.
985 * <code><em>Foo</em>Listener</code>s are registered using the
986 * <code>add<em>Foo</em>Listener</code> method.
987 *
988 * <p>
989 * You can specify the <code>listenerType</code> argument
990 * with a class literal, such as
991 * <code><em>Foo</em>Listener.class</code>.
992 * For example, you can query a
993 * <code>List</code> <code>l</code>
994 * for its item listeners with the following code:
995 *
996 * <pre>ItemListener[] ils = (ItemListener[])(l.getListeners(ItemListener.class));</pre>
997 *
998 * If no such listeners exist, this method returns an empty array.
999 *
1000 * @param listenerType the type of listeners requested; this parameter
1001 * should specify an interface that descends from
1002 * <code>java.util.EventListener</code>
1003 * @return an array of all objects registered as
1004 * <code><em>Foo</em>Listener</code>s on this list,
1005 * or an empty array if no such
1006 * listeners have been added
1007 * @exception ClassCastException if <code>listenerType</code>
1008 * doesn't specify a class or interface that implements
1009 * <code>java.util.EventListener</code>
1010 *
1011 * @see #getItemListeners
1012 * @since 1.3
1013 */
1014 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1015 EventListener l = null;
1016 if (listenerType == ActionListener.class) {
1017 l = actionListener;
1018 } else if (listenerType == ItemListener.class) {
1019 l = itemListener;
1020 } else {
1021 return super.getListeners(listenerType);
1022 }
1023 return AWTEventMulticaster.getListeners(l, listenerType);
1024 }
1025
1026 // REMIND: remove when filtering is done at lower level
1027 boolean eventEnabled(AWTEvent e) {
1028 switch(e.id) {
1029 case ActionEvent.ACTION_PERFORMED:
1030 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
1031 actionListener != null) {
1032 return true;
1033 }
1034 return false;
1035 case ItemEvent.ITEM_STATE_CHANGED:
1036 if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
1037 itemListener != null) {
1038 return true;
1039 }
1040 return false;
1041 default:
1042 break;
1043 }
1044 return super.eventEnabled(e);
1045 }
1046
1047 /**
1048 * Processes events on this scrolling list. If an event is
1049 * an instance of <code>ItemEvent</code>, it invokes the
1050 * <code>processItemEvent</code> method. Else, if the
1051 * event is an instance of <code>ActionEvent</code>,
1052 * it invokes <code>processActionEvent</code>.
1053 * If the event is not an item event or an action event,
1054 * it invokes <code>processEvent</code> on the superclass.
1055 * <p>Note that if the event parameter is <code>null</code>
1056 * the behavior is unspecified and may result in an
1057 * exception.
1058 *
1059 * @param e the event
1060 * @see java.awt.event.ActionEvent
1061 * @see java.awt.event.ItemEvent
1062 * @see #processActionEvent
1063 * @see #processItemEvent
1064 * @since JDK1.1
1065 */
1066 protected void processEvent(AWTEvent e) {
1067 if (e instanceof ItemEvent) {
1068 processItemEvent((ItemEvent)e);
1069 return;
1070 } else if (e instanceof ActionEvent) {
1071 processActionEvent((ActionEvent)e);
1072 return;
1073 }
1074 super.processEvent(e);
1075 }
1076
1077 /**
1078 * Processes item events occurring on this list by
1079 * dispatching them to any registered
1080 * <code>ItemListener</code> objects.
1081 * <p>
1082 * This method is not called unless item events are
1083 * enabled for this component. Item events are enabled
1084 * when one of the following occurs:
1085 * <p><ul>
1086 * <li>An <code>ItemListener</code> object is registered
1087 * via <code>addItemListener</code>.
1088 * <li>Item events are enabled via <code>enableEvents</code>.
1089 * </ul>
1090 * <p>Note that if the event parameter is <code>null</code>
1091 * the behavior is unspecified and may result in an
1092 * exception.
1093 *
1094 * @param e the item event
1095 * @see java.awt.event.ItemEvent
1096 * @see java.awt.event.ItemListener
1097 * @see #addItemListener
1098 * @see java.awt.Component#enableEvents
1099 * @since JDK1.1
1100 */
1101 protected void processItemEvent(ItemEvent e) {
1102 ItemListener listener = itemListener;
1103 if (listener != null) {
1104 listener.itemStateChanged(e);
1105 }
1106 }
1107
1108 /**
1109 * Processes action events occurring on this component
1110 * by dispatching them to any registered
1111 * <code>ActionListener</code> objects.
1112 * <p>
1113 * This method is not called unless action events are
1114 * enabled for this component. Action events are enabled
1115 * when one of the following occurs:
1116 * <p><ul>
1117 * <li>An <code>ActionListener</code> object is registered
1118 * via <code>addActionListener</code>.
1119 * <li>Action events are enabled via <code>enableEvents</code>.
1120 * </ul>
1121 * <p>Note that if the event parameter is <code>null</code>
1122 * the behavior is unspecified and may result in an
1123 * exception.
1124 *
1125 * @param e the action event
1126 * @see java.awt.event.ActionEvent
1127 * @see java.awt.event.ActionListener
1128 * @see #addActionListener
1129 * @see java.awt.Component#enableEvents
1130 * @since JDK1.1
1131 */
1132 protected void processActionEvent(ActionEvent e) {
1133 ActionListener listener = actionListener;
1134 if (listener != null) {
1135 listener.actionPerformed(e);
1136 }
1137 }
1138
1139 /**
1140 * Returns the parameter string representing the state of this
1141 * scrolling list. This string is useful for debugging.
1142 * @return the parameter string of this scrolling list
1143 */
1144 protected String paramString() {
1145 return super.paramString() + ",selected=" + getSelectedItem();
1146 }
1147
1148 /**
1149 * @deprecated As of JDK version 1.1,
1150 * Not for public use in the future.
1151 * This method is expected to be retained only as a package
1152 * private method.
1153 */
1154 @Deprecated
1155 public synchronized void delItems(int start, int end) {
1156 for (int i = end; i >= start; i--) {
1157 items.removeElementAt(i);
1158 }
1159 ListPeer peer = (ListPeer)this.peer;
1160 if (peer != null) {
1161 peer.delItems(start, end);
1162 }
1163 }
1164
1165 /*
1166 * Serialization support. Since the value of the selected
1167 * field isn't neccessarily up to date we sync it up with the
1168 * peer before serializing.
1169 */
1170
1171 /**
1172 * The <code>List</code> component's
1173 * Serialized Data Version.
1174 *
1175 * @serial
1176 */
1177 private int listSerializedDataVersion = 1;
1178
1179 /**
1180 * Writes default serializable fields to stream. Writes
1181 * a list of serializable <code>ItemListeners</code>
1182 * and <code>ActionListeners</code> as optional data.
1183 * The non-serializable listeners are detected and
1184 * no attempt is made to serialize them.
1185 *
1186 * @serialData <code>null</code> terminated sequence of 0
1187 * or more pairs; the pair consists of a <code>String</code>
1188 * and an <code>Object</code>; the <code>String</code>
1189 * indicates the type of object and is one of the
1190 * following:
1191 * <code>itemListenerK</code> indicating an
1192 * <code>ItemListener</code> object;
1193 * <code>actionListenerK</code> indicating an
1194 * <code>ActionListener</code> object
1195 *
1196 * @param s the <code>ObjectOutputStream</code> to write
1197 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
1198 * @see java.awt.Component#itemListenerK
1199 * @see java.awt.Component#actionListenerK
1200 * @see #readObject(ObjectInputStream)
1201 */
1202 private void writeObject(ObjectOutputStream s)
1203 throws IOException
1204 {
1205 synchronized (this) {
1206 ListPeer peer = (ListPeer)this.peer;
1207 if (peer != null) {
1208 selected = peer.getSelectedIndexes();
1209 }
1210 }
1211 s.defaultWriteObject();
1212
1213 AWTEventMulticaster.save(s, itemListenerK, itemListener);
1214 AWTEventMulticaster.save(s, actionListenerK, actionListener);
1215 s.writeObject(null);
1216 }
1217
1218 /**
1219 * Reads the <code>ObjectInputStream</code> and if it
1220 * isn't <code>null</code> adds a listener to receive
1221 * both item events and action events (as specified
1222 * by the key stored in the stream) fired by the
1223 * <code>List</code>.
1224 * Unrecognized keys or values will be ignored.
1225 *
1226 * @param s the <code>ObjectInputStream</code> to write
1227 * @exception HeadlessException if
1228 * <code>GraphicsEnvironment.isHeadless</code> returns
1229 * <code>true</code>
1230 * @see #removeItemListener(ItemListener)
1231 * @see #addItemListener(ItemListener)
1232 * @see java.awt.GraphicsEnvironment#isHeadless
1233 * @see #writeObject(ObjectOutputStream)
1234 */
1235 private void readObject(ObjectInputStream s)
1236 throws ClassNotFoundException, IOException, HeadlessException
1237 {
1238 GraphicsEnvironment.checkHeadless();
1239 s.defaultReadObject();
1240
1241 Object keyOrNull;
1242 while(null != (keyOrNull = s.readObject())) {
1243 String key = ((String)keyOrNull).intern();
1244
1245 if (itemListenerK == key)
1246 addItemListener((ItemListener)(s.readObject()));
1247
1248 else if (actionListenerK == key)
1249 addActionListener((ActionListener)(s.readObject()));
1250
1251 else // skip value for unrecognized key
1252 s.readObject();
1253 }
1254 }
1255
1256
1257 /////////////////
1258 // Accessibility support
1259 ////////////////
1260
1261
1262 /**
1263 * Gets the <code>AccessibleContext</code> associated with this
1264 * <code>List</code>. For lists, the <code>AccessibleContext</code>
1265 * takes the form of an <code>AccessibleAWTList</code>.
1266 * A new <code>AccessibleAWTList</code> instance is created, if necessary.
1267 *
1268 * @return an <code>AccessibleAWTList</code> that serves as the
1269 * <code>AccessibleContext</code> of this <code>List</code>
1270 * @since 1.3
1271 */
1272 public AccessibleContext getAccessibleContext() {
1273 if (accessibleContext == null) {
1274 accessibleContext = new AccessibleAWTList();
1275 }
1276 return accessibleContext;
1277 }
1278
1279 /**
1280 * This class implements accessibility support for the
1281 * <code>List</code> class. It provides an implementation of the
1282 * Java Accessibility API appropriate to list user-interface elements.
1283 * @since 1.3
1284 */
1285 protected class AccessibleAWTList extends AccessibleAWTComponent
1286 implements AccessibleSelection, ItemListener, ActionListener
1287 {
1288 /*
1289 * JDK 1.3 serialVersionUID
1290 */
1291 private static final long serialVersionUID = 7924617370136012829L;
1292
1293 public AccessibleAWTList() {
1294 super();
1295 List.this.addActionListener(this);
1296 List.this.addItemListener(this);
1297 }
1298
1299 public void actionPerformed(ActionEvent event) {
1300 }
1301
1302 public void itemStateChanged(ItemEvent event) {
1303 }
1304
1305 /**
1306 * Get the state set of this object.
1307 *
1308 * @return an instance of AccessibleState containing the current state
1309 * of the object
1310 * @see AccessibleState
1311 */
1312 public AccessibleStateSet getAccessibleStateSet() {
1313 AccessibleStateSet states = super.getAccessibleStateSet();
1314 if (List.this.isMultipleMode()) {
1315 states.add(AccessibleState.MULTISELECTABLE);
1316 }
1317 return states;
1318 }
1319
1320 /**
1321 * Get the role of this object.
1322 *
1323 * @return an instance of AccessibleRole describing the role of the
1324 * object
1325 * @see AccessibleRole
1326 */
1327 public AccessibleRole getAccessibleRole() {
1328 return AccessibleRole.LIST;
1329 }
1330
1331 /**
1332 * Returns the Accessible child contained at the local coordinate
1333 * Point, if one exists.
1334 *
1335 * @return the Accessible at the specified location, if it exists
1336 */
1337 public Accessible getAccessibleAt(Point p) {
1338 return null; // fredxFIXME Not implemented yet
1339 }
1340
1341 /**
1342 * Returns the number of accessible children in the object. If all
1343 * of the children of this object implement Accessible, than this
1344 * method should return the number of children of this object.
1345 *
1346 * @return the number of accessible children in the object.
1347 */
1348 public int getAccessibleChildrenCount() {
1349 return List.this.getItemCount();
1350 }
1351
1352 /**
1353 * Return the nth Accessible child of the object.
1354 *
1355 * @param i zero-based index of child
1356 * @return the nth Accessible child of the object
1357 */
1358 public Accessible getAccessibleChild(int i) {
1359 synchronized(List.this) {
1360 if (i >= List.this.getItemCount()) {
1361 return null;
1362 } else {
1363 return new AccessibleAWTListChild(List.this, i);
1364 }
1365 }
1366 }
1367
1368 /**
1369 * Get the AccessibleSelection associated with this object. In the
1370 * implementation of the Java Accessibility API for this class,
1371 * return this object, which is responsible for implementing the
1372 * AccessibleSelection interface on behalf of itself.
1373 *
1374 * @return this object
1375 */
1376 public AccessibleSelection getAccessibleSelection() {
1377 return this;
1378 }
1379
1380 // AccessibleSelection methods
1381
1382 /**
1383 * Returns the number of items currently selected.
1384 * If no items are selected, the return value will be 0.
1385 *
1386 * @return the number of items currently selected.
1387 */
1388 public int getAccessibleSelectionCount() {
1389 return List.this.getSelectedIndexes().length;
1390 }
1391
1392 /**
1393 * Returns an Accessible representing the specified selected item
1394 * in the object. If there isn't a selection, or there are
1395 * fewer items selected than the integer passed in, the return
1396 * value will be null.
1397 *
1398 * @param i the zero-based index of selected items
1399 * @return an Accessible containing the selected item
1400 */
1401 public Accessible getAccessibleSelection(int i) {
1402 synchronized(List.this) {
1403 int len = getAccessibleSelectionCount();
1404 if (i < 0 || i >= len) {
1405 return null;
1406 } else {
1407 return getAccessibleChild(List.this.getSelectedIndexes()[i]);
1408 }
1409 }
1410 }
1411
1412 /**
1413 * Returns true if the current child of this object is selected.
1414 *
1415 * @param i the zero-based index of the child in this Accessible
1416 * object.
1417 * @see AccessibleContext#getAccessibleChild
1418 */
1419 public boolean isAccessibleChildSelected(int i) {
1420 return List.this.isIndexSelected(i);
1421 }
1422
1423 /**
1424 * Adds the specified selected item in the object to the object's
1425 * selection. If the object supports multiple selections,
1426 * the specified item is added to any existing selection, otherwise
1427 * it replaces any existing selection in the object. If the
1428 * specified item is already selected, this method has no effect.
1429 *
1430 * @param i the zero-based index of selectable items
1431 */
1432 public void addAccessibleSelection(int i) {
1433 List.this.select(i);
1434 }
1435
1436 /**
1437 * Removes the specified selected item in the object from the object's
1438 * selection. If the specified item isn't currently selected, this
1439 * method has no effect.
1440 *
1441 * @param i the zero-based index of selectable items
1442 */
1443 public void removeAccessibleSelection(int i) {
1444 List.this.deselect(i);
1445 }
1446
1447 /**
1448 * Clears the selection in the object, so that nothing in the
1449 * object is selected.
1450 */
1451 public void clearAccessibleSelection() {
1452 synchronized(List.this) {
1453 int selectedIndexes[] = List.this.getSelectedIndexes();
1454 if (selectedIndexes == null)
1455 return;
1456 for (int i = selectedIndexes.length - 1; i >= 0; i--) {
1457 List.this.deselect(selectedIndexes[i]);
1458 }
1459 }
1460 }
1461
1462 /**
1463 * Causes every selected item in the object to be selected
1464 * if the object supports multiple selections.
1465 */
1466 public void selectAllAccessibleSelection() {
1467 synchronized(List.this) {
1468 for (int i = List.this.getItemCount() - 1; i >= 0; i--) {
1469 List.this.select(i);
1470 }
1471 }
1472 }
1473
1474 /**
1475 * This class implements accessibility support for
1476 * List children. It provides an implementation of the
1477 * Java Accessibility API appropriate to list children
1478 * user-interface elements.
1479 * @since 1.3
1480 */
1481 protected class AccessibleAWTListChild extends AccessibleAWTComponent
1482 implements Accessible
1483 {
1484 /*
1485 * JDK 1.3 serialVersionUID
1486 */
1487 private static final long serialVersionUID = 4412022926028300317L;
1488
1489 // [[[FIXME]]] need to finish implementing this!!!
1490
1491 private List parent;
1492 private int indexInParent;
1493
1494 public AccessibleAWTListChild(List parent, int indexInParent) {
1495 this.parent = parent;
1496 this.setAccessibleParent(parent);
1497 this.indexInParent = indexInParent;
1498 }
1499
1500 //
1501 // required Accessible methods
1502 //
1503 /**
1504 * Gets the AccessibleContext for this object. In the
1505 * implementation of the Java Accessibility API for this class,
1506 * return this object, which acts as its own AccessibleContext.
1507 *
1508 * @return this object
1509 */
1510 public AccessibleContext getAccessibleContext() {
1511 return this;
1512 }
1513
1514 //
1515 // required AccessibleContext methods
1516 //
1517
1518 /**
1519 * Get the role of this object.
1520 *
1521 * @return an instance of AccessibleRole describing the role of
1522 * the object
1523 * @see AccessibleRole
1524 */
1525 public AccessibleRole getAccessibleRole() {
1526 return AccessibleRole.LIST_ITEM;
1527 }
1528
1529 /**
1530 * Get the state set of this object. The AccessibleStateSet of an
1531 * object is composed of a set of unique AccessibleState's. A
1532 * change in the AccessibleStateSet of an object will cause a
1533 * PropertyChangeEvent to be fired for the
1534 * ACCESSIBLE_STATE_PROPERTY property.
1535 *
1536 * @return an instance of AccessibleStateSet containing the
1537 * current state set of the object
1538 * @see AccessibleStateSet
1539 * @see AccessibleState
1540 * @see #addPropertyChangeListener
1541 */
1542 public AccessibleStateSet getAccessibleStateSet() {
1543 AccessibleStateSet states = super.getAccessibleStateSet();
1544 if (parent.isIndexSelected(indexInParent)) {
1545 states.add(AccessibleState.SELECTED);
1546 }
1547 return states;
1548 }
1549
1550 /**
1551 * Gets the locale of the component. If the component does not
1552 * have a locale, then the locale of its parent is returned.
1553 *
1554 * @return This component's locale. If this component does not have
1555 * a locale, the locale of its parent is returned.
1556 *
1557 * @exception IllegalComponentStateException
1558 * If the Component does not have its own locale and has not yet
1559 * been added to a containment hierarchy such that the locale can
1560 * be determined from the containing parent.
1561 */
1562 public Locale getLocale() {
1563 return parent.getLocale();
1564 }
1565
1566 /**
1567 * Get the 0-based index of this object in its accessible parent.
1568 *
1569 * @return the 0-based index of this object in its parent; -1 if
1570 * this object does not have an accessible parent.
1571 *
1572 * @see #getAccessibleParent
1573 * @see #getAccessibleChildrenCount
1574 * @see #getAccessibleChild
1575 */
1576 public int getAccessibleIndexInParent() {
1577 return indexInParent;
1578 }
1579
1580 /**
1581 * Returns the number of accessible children of the object.
1582 *
1583 * @return the number of accessible children of the object.
1584 */
1585 public int getAccessibleChildrenCount() {
1586 return 0; // list elements can't have children
1587 }
1588
1589 /**
1590 * Return the specified Accessible child of the object. The
1591 * Accessible children of an Accessible object are zero-based,
1592 * so the first child of an Accessible child is at index 0, the
1593 * second child is at index 1, and so on.
1594 *
1595 * @param i zero-based index of child
1596 * @return the Accessible child of the object
1597 * @see #getAccessibleChildrenCount
1598 */
1599 public Accessible getAccessibleChild(int i) {
1600 return null; // list elements can't have children
1601 }
1602
1603
1604 //
1605 // AccessibleComponent delegatation to parent List
1606 //
1607
1608 /**
1609 * Get the background color of this object.
1610 *
1611 * @return the background color, if supported, of the object;
1612 * otherwise, null
1613 * @see #setBackground
1614 */
1615 public Color getBackground() {
1616 return parent.getBackground();
1617 }
1618
1619 /**
1620 * Set the background color of this object.
1621 *
1622 * @param c the new Color for the background
1623 * @see #setBackground
1624 */
1625 public void setBackground(Color c) {
1626 parent.setBackground(c);
1627 }
1628
1629 /**
1630 * Get the foreground color of this object.
1631 *
1632 * @return the foreground color, if supported, of the object;
1633 * otherwise, null
1634 * @see #setForeground
1635 */
1636 public Color getForeground() {
1637 return parent.getForeground();
1638 }
1639
1640 /**
1641 * Set the foreground color of this object.
1642 *
1643 * @param c the new Color for the foreground
1644 * @see #getForeground
1645 */
1646 public void setForeground(Color c) {
1647 parent.setForeground(c);
1648 }
1649
1650 /**
1651 * Get the Cursor of this object.
1652 *
1653 * @return the Cursor, if supported, of the object; otherwise, null
1654 * @see #setCursor
1655 */
1656 public Cursor getCursor() {
1657 return parent.getCursor();
1658 }
1659
1660 /**
1661 * Set the Cursor of this object.
1662 * <p>
1663 * The method may have no visual effect if the Java platform
1664 * implementation and/or the native system do not support
1665 * changing the mouse cursor shape.
1666 * @param cursor the new Cursor for the object
1667 * @see #getCursor
1668 */
1669 public void setCursor(Cursor cursor) {
1670 parent.setCursor(cursor);
1671 }
1672
1673 /**
1674 * Get the Font of this object.
1675 *
1676 * @return the Font,if supported, for the object; otherwise, null
1677 * @see #setFont
1678 */
1679 public Font getFont() {
1680 return parent.getFont();
1681 }
1682
1683 /**
1684 * Set the Font of this object.
1685 *
1686 * @param f the new Font for the object
1687 * @see #getFont
1688 */
1689 public void setFont(Font f) {
1690 parent.setFont(f);
1691 }
1692
1693 /**
1694 * Get the FontMetrics of this object.
1695 *
1696 * @param f the Font
1697 * @return the FontMetrics, if supported, the object; otherwise, null
1698 * @see #getFont
1699 */
1700 public FontMetrics getFontMetrics(Font f) {
1701 return parent.getFontMetrics(f);
1702 }
1703
1704 /**
1705 * Determine if the object is enabled. Objects that are enabled
1706 * will also have the AccessibleState.ENABLED state set in their
1707 * AccessibleStateSet.
1708 *
1709 * @return true if object is enabled; otherwise, false
1710 * @see #setEnabled
1711 * @see AccessibleContext#getAccessibleStateSet
1712 * @see AccessibleState#ENABLED
1713 * @see AccessibleStateSet
1714 */
1715 public boolean isEnabled() {
1716 return parent.isEnabled();
1717 }
1718
1719 /**
1720 * Set the enabled state of the object.
1721 *
1722 * @param b if true, enables this object; otherwise, disables it
1723 * @see #isEnabled
1724 */
1725 public void setEnabled(boolean b) {
1726 parent.setEnabled(b);
1727 }
1728
1729 /**
1730 * Determine if the object is visible. Note: this means that the
1731 * object intends to be visible; however, it may not be
1732 * showing on the screen because one of the objects that this object
1733 * is contained by is currently not visible. To determine if an
1734 * object is showing on the screen, use isShowing().
1735 * <p>Objects that are visible will also have the
1736 * AccessibleState.VISIBLE state set in their AccessibleStateSet.
1737 *
1738 * @return true if object is visible; otherwise, false
1739 * @see #setVisible
1740 * @see AccessibleContext#getAccessibleStateSet
1741 * @see AccessibleState#VISIBLE
1742 * @see AccessibleStateSet
1743 */
1744 public boolean isVisible() {
1745 // [[[FIXME]]] needs to work like isShowing() below
1746 return false;
1747 // return parent.isVisible();
1748 }
1749
1750 /**
1751 * Set the visible state of the object.
1752 *
1753 * @param b if true, shows this object; otherwise, hides it
1754 * @see #isVisible
1755 */
1756 public void setVisible(boolean b) {
1757 // [[[FIXME]]] should scroll to item to make it show!
1758 parent.setVisible(b);
1759 }
1760
1761 /**
1762 * Determine if the object is showing. This is determined by
1763 * checking the visibility of the object and visibility of the
1764 * object ancestors.
1765 * Note: this will return true even if the object is obscured
1766 * by another (for example, it to object is underneath a menu
1767 * that was pulled down).
1768 *
1769 * @return true if object is showing; otherwise, false
1770 */
1771 public boolean isShowing() {
1772 // [[[FIXME]]] only if it's showing!!!
1773 return false;
1774 // return parent.isShowing();
1775 }
1776
1777 /**
1778 * Checks whether the specified point is within this object's
1779 * bounds, where the point's x and y coordinates are defined to
1780 * be relative to the coordinate system of the object.
1781 *
1782 * @param p the Point relative to the coordinate system of the
1783 * object
1784 * @return true if object contains Point; otherwise false
1785 * @see #getBounds
1786 */
1787 public boolean contains(Point p) {
1788 // [[[FIXME]]] - only if p is within the list element!!!
1789 return false;
1790 // return parent.contains(p);
1791 }
1792
1793 /**
1794 * Returns the location of the object on the screen.
1795 *
1796 * @return location of object on screen; null if this object
1797 * is not on the screen
1798 * @see #getBounds
1799 * @see #getLocation
1800 */
1801 public Point getLocationOnScreen() {
1802 // [[[FIXME]]] sigh
1803 return null;
1804 }
1805
1806 /**
1807 * Gets the location of the object relative to the parent in the
1808 * form of a point specifying the object's top-left corner in the
1809 * screen's coordinate space.
1810 *
1811 * @return An instance of Point representing the top-left corner of
1812 * the objects's bounds in the coordinate space of the screen; null
1813 * if this object or its parent are not on the screen
1814 * @see #getBounds
1815 * @see #getLocationOnScreen
1816 */
1817 public Point getLocation() {
1818 // [[[FIXME]]]
1819 return null;
1820 }
1821
1822 /**
1823 * Sets the location of the object relative to the parent.
1824 * @param p the new position for the top-left corner
1825 * @see #getLocation
1826 */
1827 public void setLocation(Point p) {
1828 // [[[FIXME]]] maybe - can simply return as no-op
1829 }
1830
1831 /**
1832 * Gets the bounds of this object in the form of a Rectangle object.
1833 * The bounds specify this object's width, height, and location
1834 * relative to its parent.
1835 *
1836 * @return A rectangle indicating this component's bounds; null if
1837 * this object is not on the screen.
1838 * @see #contains
1839 */
1840 public Rectangle getBounds() {
1841 // [[[FIXME]]]
1842 return null;
1843 }
1844
1845 /**
1846 * Sets the bounds of this object in the form of a Rectangle
1847 * object. The bounds specify this object's width, height, and
1848 * location relative to its parent.
1849 *
1850 * @param r rectangle indicating this component's bounds
1851 * @see #getBounds
1852 */
1853 public void setBounds(Rectangle r) {
1854 // no-op; not supported
1855 }
1856
1857 /**
1858 * Returns the size of this object in the form of a Dimension
1859 * object. The height field of the Dimension object contains this
1860 * objects's height, and the width field of the Dimension object
1861 * contains this object's width.
1862 *
1863 * @return A Dimension object that indicates the size of this
1864 * component; null if this object is not on the screen
1865 * @see #setSize
1866 */
1867 public Dimension getSize() {
1868 // [[[FIXME]]]
1869 return null;
1870 }
1871
1872 /**
1873 * Resizes this object so that it has width and height.
1874 *
1875 * @param d - The dimension specifying the new size of the object.
1876 * @see #getSize
1877 */
1878 public void setSize(Dimension d) {
1879 // not supported; no-op
1880 }
1881
1882 /**
1883 * Returns the <code>Accessible</code> child, if one exists,
1884 * contained at the local coordinate <code>Point</code>.
1885 *
1886 * @param p the point relative to the coordinate system of this
1887 * object
1888 * @return the <code>Accessible</code>, if it exists,
1889 * at the specified location; otherwise <code>null</code>
1890 */
1891 public Accessible getAccessibleAt(Point p) {
1892 return null; // object cannot have children!
1893 }
1894
1895 /**
1896 * Returns whether this object can accept focus or not. Objects
1897 * that can accept focus will also have the
1898 * <code>AccessibleState.FOCUSABLE</code> state set in their
1899 * <code>AccessibleStateSet</code>.
1900 *
1901 * @return true if object can accept focus; otherwise false
1902 * @see AccessibleContext#getAccessibleStateSet
1903 * @see AccessibleState#FOCUSABLE
1904 * @see AccessibleState#FOCUSED
1905 * @see AccessibleStateSet
1906 */
1907 public boolean isFocusTraversable() {
1908 return false; // list element cannot receive focus!
1909 }
1910
1911 /**
1912 * Requests focus for this object. If this object cannot accept
1913 * focus, nothing will happen. Otherwise, the object will attempt
1914 * to take focus.
1915 * @see #isFocusTraversable
1916 */
1917 public void requestFocus() {
1918 // nothing to do; a no-op
1919 }
1920
1921 /**
1922 * Adds the specified focus listener to receive focus events from
1923 * this component.
1924 *
1925 * @param l the focus listener
1926 * @see #removeFocusListener
1927 */
1928 public void addFocusListener(FocusListener l) {
1929 // nothing to do; a no-op
1930 }
1931
1932 /**
1933 * Removes the specified focus listener so it no longer receives
1934 * focus events from this component.
1935 *
1936 * @param l the focus listener
1937 * @see #addFocusListener
1938 */
1939 public void removeFocusListener(FocusListener l) {
1940 // nothing to do; a no-op
1941 }
1942
1943
1944
1945 } // inner class AccessibleAWTListChild
1946
1947 } // inner class AccessibleAWTList
1948
1949 }