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