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