1 /* List.java -- A listbox widget 2 Copyright (C) 1999, 2002, 2004, 2006, Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.awt; 40 41 import java.awt.event.ActionEvent; 42 import java.awt.event.ActionListener; 43 import java.awt.event.ItemEvent; 44 import java.awt.event.ItemListener; 45 import java.awt.peer.ListPeer; 46 import java.util.EventListener; 47 import java.util.Vector; 48 49 import javax.accessibility.Accessible; 50 import javax.accessibility.AccessibleContext; 51 import javax.accessibility.AccessibleRole; 52 import javax.accessibility.AccessibleSelection; 53 import javax.accessibility.AccessibleState; 54 import javax.accessibility.AccessibleStateSet; 55 56 /** 57 * Class that implements a listbox widget 58 * 59 * @author Aaron M. Renn (arenn@urbanophile.com) 60 */ 61 public class List extends Component 62 implements ItemSelectable, Accessible 63 { 64 65 /** 66 * The number used to generate the name returned by getName. 67 */ 68 private static transient long next_list_number; 69 70 // Serialization constant 71 private static final long serialVersionUID = -3304312411574666869L; 72 73 // FIXME: Need read/writeObject 74 75 /** 76 * @serial The items in the list. 77 */ 78 private Vector items = new Vector(); 79 80 /** 81 * @serial Indicates whether or not multiple items can be selected 82 * simultaneously. 83 */ 84 private boolean multipleMode; 85 86 /** 87 * @serial The number of rows in the list. This is set on creation 88 * only and cannot be modified. 89 */ 90 private int rows; 91 92 /** 93 * @serial An array of the item indices that are selected. 94 */ 95 private int[] selected; 96 97 /** 98 * @serial An index value used by <code>makeVisible()</code> and 99 * <code>getVisibleIndex</code>. 100 */ 101 private int visibleIndex = -1; 102 103 // The list of ItemListeners for this object. 104 private ItemListener item_listeners; 105 106 // The list of ActionListeners for this object. 107 private ActionListener action_listeners; 108 109 /** 110 * Initializes a new instance of <code>List</code> with no visible lines 111 * and multi-select disabled. 112 * 113 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 114 * @since 1.1 115 */ List()116 public List() 117 { 118 this(4, false); 119 } 120 121 /** 122 * Initializes a new instance of <code>List</code> with the specified 123 * number of visible lines and multi-select disabled. 124 * 125 * @param rows The number of visible rows in the list. 126 * 127 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 128 */ List(int rows)129 public List(int rows) 130 { 131 this(rows, false); 132 } 133 134 /** 135 * Initializes a new instance of <code>List</code> with the specified 136 * number of lines and the specified multi-select setting. 137 * 138 * @param rows The number of visible rows in the list. 139 * @param multipleMode <code>true</code> if multiple lines can be selected 140 * simultaneously, <code>false</code> otherwise. 141 * 142 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 143 */ List(int rows, boolean multipleMode)144 public List(int rows, boolean multipleMode) 145 { 146 if (rows == 0) 147 this.rows = 4; 148 else 149 this.rows = rows; 150 151 this.multipleMode = multipleMode; 152 selected = new int[0]; 153 154 if (GraphicsEnvironment.isHeadless()) 155 throw new HeadlessException(); 156 157 } 158 159 /** 160 * Returns the number of items in this list. 161 * 162 * @return The number of items in this list. 163 * 164 * @since 1.1 165 */ getItemCount()166 public int getItemCount() 167 { 168 return countItems(); 169 } 170 171 /** 172 * Returns the number of items in this list. 173 * 174 * @return The number of items in this list. 175 * 176 * @deprecated This method is deprecated in favor of 177 * <code>getItemCount()</code> 178 */ countItems()179 public int countItems() 180 { 181 return items.size(); 182 } 183 184 /** 185 * Returns the complete list of items. 186 * 187 * @return The complete list of items in the list. 188 * 189 * @since 1.1 190 */ getItems()191 public synchronized String[] getItems() 192 { 193 String[] l_items = new String[getItemCount()]; 194 195 items.copyInto(l_items); 196 return(l_items); 197 } 198 199 /** 200 * Returns the item at the specified index. 201 * 202 * @param index The index of the item to retrieve. 203 * 204 * @exception IndexOutOfBoundsException If the index value is not valid. 205 */ getItem(int index)206 public String getItem(int index) 207 { 208 return((String) items.elementAt(index)); 209 } 210 211 /** 212 * Returns the number of visible rows in the list. 213 * 214 * @return The number of visible rows in the list. 215 */ getRows()216 public int getRows() 217 { 218 return(rows); 219 } 220 221 /** 222 * Tests whether or not multi-select mode is enabled. 223 * 224 * @return <code>true</code> if multi-select mode is enabled, 225 * <code>false</code> otherwise. 226 * 227 * @since 1.1 228 */ isMultipleMode()229 public boolean isMultipleMode() 230 { 231 return allowsMultipleSelections (); 232 } 233 234 /** 235 * Tests whether or not multi-select mode is enabled. 236 * 237 * @return <code>true</code> if multi-select mode is enabled, 238 * <code>false</code> otherwise. 239 * 240 * @deprecated This method is deprecated in favor of 241 * <code>isMultipleMode()</code>. 242 */ allowsMultipleSelections()243 public boolean allowsMultipleSelections() 244 { 245 return multipleMode; 246 } 247 248 /** 249 * This method enables or disables multiple selection mode for this 250 * list. 251 * 252 * @param multipleMode <code>true</code> to enable multiple mode, 253 * <code>false</code> otherwise. 254 * 255 * @since 1.1 256 */ setMultipleMode(boolean multipleMode)257 public void setMultipleMode(boolean multipleMode) 258 { 259 setMultipleSelections (multipleMode); 260 } 261 262 /** 263 * This method enables or disables multiple selection mode for this 264 * list. 265 * 266 * @param multipleMode <code>true</code> to enable multiple mode, 267 * <code>false</code> otherwise. 268 * 269 * @deprecated 270 */ setMultipleSelections(boolean multipleMode)271 public void setMultipleSelections(boolean multipleMode) 272 { 273 this.multipleMode = multipleMode; 274 275 ListPeer peer = (ListPeer) getPeer(); 276 if (peer != null) 277 peer.setMultipleMode(multipleMode); 278 279 } 280 281 /** 282 * Returns the minimum size of this component. 283 * 284 * @return The minimum size of this component. 285 * 286 * @since 1.1 287 */ getMinimumSize()288 public Dimension getMinimumSize() 289 { 290 return getMinimumSize(getRows()); 291 } 292 293 /** 294 * Returns the minimum size of this component. 295 * 296 * @return The minimum size of this component. 297 * 298 * @deprecated This method is deprecated in favor of 299 * <code>getMinimumSize</code>. 300 */ minimumSize()301 public Dimension minimumSize() 302 { 303 return minimumSize(getRows()); 304 } 305 306 /** 307 * Returns the minimum size of this component assuming it had the specified 308 * number of rows. 309 * 310 * @param rows The number of rows to size for. 311 * 312 * @return The minimum size of this component. 313 * 314 * @since 1.1 315 */ getMinimumSize(int rows)316 public Dimension getMinimumSize(int rows) 317 { 318 return minimumSize(rows); 319 } 320 321 /** 322 * Returns the minimum size of this component assuming it had the specified 323 * number of rows. 324 * 325 * @param rows The number of rows to size for. 326 * 327 * @return The minimum size of this component. 328 * 329 * @deprecated This method is deprecated in favor of 330 * <code>getMinimumSize(int)</code>> 331 */ minimumSize(int rows)332 public Dimension minimumSize(int rows) 333 { 334 ListPeer peer = (ListPeer) getPeer(); 335 if (peer != null) 336 return peer.minimumSize(rows); 337 else 338 return new Dimension(0, 0); 339 } 340 341 /** 342 * Returns the preferred size of this component. 343 * 344 * @return The preferred size of this component. 345 * 346 * @since 1.1 347 */ getPreferredSize()348 public Dimension getPreferredSize() 349 { 350 return getPreferredSize(getRows()); 351 } 352 353 /** 354 * Returns the preferred size of this component. 355 * 356 * @return The preferred size of this component. 357 * 358 * @deprecated This method is deprecated in favor of 359 * <code>getPreferredSize</code>. 360 */ preferredSize()361 public Dimension preferredSize() 362 { 363 return preferredSize(getRows()); 364 } 365 366 /** 367 * Returns the preferred size of this component assuming it had the specified 368 * number of rows. 369 * 370 * @param rows The number of rows to size for. 371 * 372 * @return The preferred size of this component. 373 * 374 * @since 1.1 375 */ getPreferredSize(int rows)376 public Dimension getPreferredSize(int rows) 377 { 378 return preferredSize(rows); 379 } 380 381 /** 382 * Returns the preferred size of this component assuming it had the specified 383 * number of rows. 384 * 385 * @param rows The number of rows to size for. 386 * 387 * @return The preferred size of this component. 388 * 389 * @deprecated This method is deprecated in favor of 390 * <code>getPreferredSize(int)</code>> 391 */ preferredSize(int rows)392 public Dimension preferredSize(int rows) 393 { 394 ListPeer peer = (ListPeer)getPeer(); 395 if (peer != null) 396 return peer.preferredSize(rows); 397 else 398 return getSize(); 399 } 400 401 /** 402 * This method adds the specified item to the end of the list. 403 * 404 * @param item The item to add to the list. 405 * 406 * @since 1.1 407 */ add(String item)408 public void add(String item) 409 { 410 add (item, -1); 411 } 412 413 /** 414 * This method adds the specified item to the end of the list. 415 * 416 * @param item The item to add to the list. 417 * 418 * @deprecated Use add() instead. 419 */ addItem(String item)420 public void addItem(String item) 421 { 422 addItem(item, -1); 423 } 424 425 /** 426 * Adds the specified item to the specified location in the list. 427 * If the desired index is -1 or greater than the number of rows 428 * in the list, then the item is added to the end. 429 * 430 * @param item The item to add to the list. 431 * @param index The location in the list to add the item, or -1 to add 432 * to the end. 433 * 434 * @since 1.1 435 */ add(String item, int index)436 public void add(String item, int index) 437 { 438 addItem(item, index); 439 } 440 441 /** 442 * Adds the specified item to the specified location in the list. 443 * If the desired index is -1 or greater than the number of rows 444 * in the list, then the item is added to the end. 445 * 446 * @param item The item to add to the list. 447 * @param index The location in the list to add the item, or -1 to add 448 * to the end. 449 * 450 * @deprecated Use add() instead. 451 */ addItem(String item, int index)452 public void addItem(String item, int index) 453 { 454 if (item == null) 455 item = ""; 456 457 if (index < -1) 458 index = -1; 459 460 if ((index == -1) || (index >= items.size ())) 461 items.addElement (item); 462 else 463 items.insertElementAt(item, index); 464 465 ListPeer peer = (ListPeer) getPeer(); 466 if (peer != null) 467 peer.add (item, index); 468 } 469 470 /** 471 * Deletes the item at the specified index. 472 * 473 * @param index The index of the item to delete. 474 * 475 * @exception IllegalArgumentException If the index is not valid 476 * 477 * @deprecated 478 */ delItem(int index)479 public void delItem(int index) throws IllegalArgumentException 480 { 481 boolean selected = false; 482 if (isSelected(index)) 483 { 484 selected = true; 485 deselect(index); 486 } 487 488 items.removeElementAt (index); 489 490 if (selected) 491 select(index); 492 493 ListPeer peer = (ListPeer) getPeer(); 494 if (peer != null) 495 peer.delItems (index, index); 496 } 497 498 /** 499 * Deletes the item at the specified index. 500 * 501 * @param index The index of the item to delete. 502 * 503 * @exception IllegalArgumentException If the index is not valid 504 * 505 * @since 1.1 506 */ remove(int index)507 public void remove(int index) throws IllegalArgumentException 508 { 509 delItem(index); 510 } 511 512 /** 513 * Deletes all items in the specified index range. 514 * 515 * @param start The beginning index of the range to delete. 516 * @param end The ending index of the range to delete. 517 * 518 * @exception IllegalArgumentException If the indexes are not valid 519 * 520 * @deprecated This method is deprecated for some unknown reason. 521 */ delItems(int start, int end)522 public synchronized void delItems(int start, int end) 523 throws IllegalArgumentException 524 { 525 // We must run the loop in reverse direction. 526 for (int i = end; i >= start; --i) 527 items.removeElementAt (i); 528 if (peer != null) 529 { 530 ListPeer l = (ListPeer) peer; 531 l.delItems (start, end); 532 } 533 } 534 535 /** 536 * Deletes the first occurrence of the specified item from the list. 537 * 538 * @param item The item to delete. 539 * 540 * @exception IllegalArgumentException If the specified item does not exist. 541 * 542 * @since 1.1 543 */ remove(String item)544 public synchronized void remove(String item) throws IllegalArgumentException 545 { 546 int index = items.indexOf(item); 547 if (index == -1) 548 throw new IllegalArgumentException("List element to delete not found"); 549 550 remove(index); 551 } 552 553 /** 554 * Deletes all of the items from the list. 555 * 556 * @since 1.1 557 */ removeAll()558 public synchronized void removeAll() 559 { 560 clear(); 561 } 562 563 /** 564 * Deletes all of the items from the list. 565 * 566 * @deprecated This method is deprecated in favor of <code>removeAll()</code>. 567 */ clear()568 public void clear() 569 { 570 items.clear(); 571 572 ListPeer peer = (ListPeer) getPeer(); 573 if (peer != null) 574 peer.removeAll(); 575 576 selected = new int[0]; 577 } 578 579 /** 580 * Replaces the item at the specified index with the specified item. 581 * 582 * @param item The new item value. 583 * @param index The index of the item to replace. 584 * 585 * @exception ArrayIndexOutOfBoundsException If the index is not valid. 586 */ replaceItem(String item, int index)587 public synchronized void replaceItem(String item, int index) 588 throws ArrayIndexOutOfBoundsException 589 { 590 if ((index < 0) || (index >= items.size())) 591 throw new ArrayIndexOutOfBoundsException("Bad list index: " + index); 592 593 items.insertElementAt(item, index + 1); 594 items.removeElementAt (index); 595 596 if (peer != null) 597 { 598 ListPeer l = (ListPeer) peer; 599 600 /* We add first and then remove so that the selected 601 item remains the same */ 602 l.add (item, index + 1); 603 l.delItems (index, index); 604 } 605 } 606 607 /** 608 * Returns the index of the currently selected item. -1 will be returned 609 * if there are no selected rows or if there are multiple selected rows. 610 * 611 * @return The index of the selected row. 612 */ getSelectedIndex()613 public synchronized int getSelectedIndex() 614 { 615 if (peer != null) 616 { 617 ListPeer l = (ListPeer) peer; 618 selected = l.getSelectedIndexes (); 619 } 620 621 if (selected == null || selected.length != 1) 622 return -1; 623 624 return selected[0]; 625 } 626 627 /** 628 * Returns an array containing the indexes of the rows that are 629 * currently selected. 630 * 631 * @return A list of indexes of selected rows. 632 */ getSelectedIndexes()633 public synchronized int[] getSelectedIndexes() 634 { 635 if (peer != null) 636 { 637 ListPeer l = (ListPeer) peer; 638 selected = l.getSelectedIndexes(); 639 } 640 641 return selected; 642 } 643 644 /** 645 * Returns the item that is currently selected, or <code>null</code> if there 646 * is no item selected. FIXME: What happens if multiple items selected? 647 * 648 * @return The selected item, or <code>null</code> if there is no 649 * selected item. 650 */ getSelectedItem()651 public synchronized String getSelectedItem() 652 { 653 int index = getSelectedIndex(); 654 if (index == -1) 655 return(null); 656 657 return((String) items.elementAt(index)); 658 } 659 660 /** 661 * Returns the list of items that are currently selected in this list. 662 * 663 * @return The list of currently selected items. 664 */ getSelectedItems()665 public synchronized String[] getSelectedItems() 666 { 667 int[] indexes = getSelectedIndexes(); 668 if (indexes == null) 669 return(new String[0]); 670 671 String[] retvals = new String[indexes.length]; 672 if (retvals.length > 0) 673 for (int i = 0 ; i < retvals.length; i++) 674 retvals[i] = (String)items.elementAt(indexes[i]); 675 676 return(retvals); 677 } 678 679 /** 680 * Returns the list of items that are currently selected in this list as 681 * an array of type <code>Object[]</code> instead of <code>String[]</code>. 682 * 683 * @return The list of currently selected items. 684 */ getSelectedObjects()685 public synchronized Object[] getSelectedObjects() 686 { 687 int[] indexes = getSelectedIndexes(); 688 if (indexes == null) 689 return(new Object[0]); 690 691 Object[] retvals = new Object[indexes.length]; 692 if (retvals.length > 0) 693 for (int i = 0 ; i < retvals.length; i++) 694 retvals[i] = items.elementAt(indexes[i]); 695 696 return(retvals); 697 } 698 699 /** 700 * Tests whether or not the specified index is selected. 701 * 702 * @param index The index to test. 703 * 704 * @return <code>true</code> if the index is selected, <code>false</code> 705 * otherwise. 706 * 707 * @since 1.1 708 */ isIndexSelected(int index)709 public boolean isIndexSelected(int index) 710 { 711 return isSelected(index); 712 } 713 714 /** 715 * Tests whether or not the specified index is selected. 716 * 717 * @param index The index to test. 718 * 719 * @return <code>true</code> if the index is selected, <code>false</code> 720 * otherwise. 721 * 722 * @deprecated This method is deprecated in favor of 723 * <code>isIndexSelected(int)</code>. 724 */ isSelected(int index)725 public boolean isSelected(int index) 726 { 727 int[] indexes = getSelectedIndexes(); 728 729 for (int i = 0; i < indexes.length; i++) 730 if (indexes[i] == index) 731 return true; 732 733 return false; 734 } 735 736 /** 737 * This method ensures that the item at the specified index is visible. 738 * 739 * @param index The index of the item to be made visible. 740 */ makeVisible(int index)741 public synchronized void makeVisible(int index) 742 throws IllegalArgumentException 743 { 744 visibleIndex = index; 745 if (peer != null) 746 { 747 ListPeer l = (ListPeer) peer; 748 l.makeVisible (index); 749 } 750 } 751 752 /** 753 * Returns the index of the last item that was made visible via the 754 * <code>makeVisible()</code> method. 755 * 756 * @return The index of the last item made visible via the 757 * <code>makeVisible()</code> method. 758 */ getVisibleIndex()759 public int getVisibleIndex() 760 { 761 return visibleIndex; 762 } 763 764 /** 765 * Makes the item at the specified index selected. 766 * 767 * @param index The index of the item to select. 768 */ select(int index)769 public synchronized void select(int index) 770 { 771 ListPeer lp = (ListPeer) getPeer(); 772 if (lp != null) 773 lp.select(index); 774 775 if (selected != null) 776 { 777 boolean found = false; 778 for (int i = 0; i < selected.length; i++) 779 { 780 if (selected[i] == index) 781 found = true; 782 } 783 if (! found) 784 { 785 if (! isMultipleMode()) 786 { 787 selected = new int[] { index }; 788 return; 789 } 790 int[] temp = new int[selected.length + 1]; 791 System.arraycopy(selected, 0, temp, 0, selected.length); 792 temp[selected.length] = index; 793 selected = temp; 794 } 795 } 796 else 797 { 798 selected = new int[1]; 799 selected[0] = index; 800 } 801 } 802 803 /** 804 * Makes the item at the specified index not selected. 805 * 806 * @param index The index of the item to unselect. 807 */ deselect(int index)808 public synchronized void deselect(int index) 809 { 810 if (isSelected(index)) 811 { 812 ListPeer lp = (ListPeer)getPeer(); 813 if (lp != null) 814 lp.deselect(index); 815 816 int[] temp = new int[selected.length - 1]; 817 for (int i = 0; i < temp.length; i++) 818 { 819 if (selected[i] != index) 820 temp[i] = selected[i]; 821 else 822 { 823 System.arraycopy(selected, i + 1, temp, i, 824 selected.length - i - 1); 825 break; 826 } 827 } 828 selected = temp; 829 } 830 } 831 832 /** 833 * Notifies this object to create its native peer. 834 */ addNotify()835 public void addNotify() 836 { 837 if (peer == null) 838 peer = getToolkit ().createList(this); 839 super.addNotify (); 840 } 841 842 /** 843 * Notifies this object to destroy its native peer. 844 */ removeNotify()845 public void removeNotify() 846 { 847 super.removeNotify(); 848 } 849 850 /** 851 * Adds the specified <code>ActionListener</code> to the list of 852 * registered listeners for this object. 853 * 854 * @param listener The listener to add. 855 * 856 * @since 1.1 857 */ addActionListener(ActionListener listener)858 public synchronized void addActionListener(ActionListener listener) 859 { 860 action_listeners = AWTEventMulticaster.add(action_listeners, listener); 861 } 862 863 /** 864 * Removes the specified <code>ActionListener</code> from the list of 865 * registers listeners for this object. 866 * 867 * @param listener The listener to remove. 868 * 869 * @since 1.1 870 */ removeActionListener(ActionListener listener)871 public synchronized void removeActionListener(ActionListener listener) 872 { 873 action_listeners = AWTEventMulticaster.remove(action_listeners, listener); 874 } 875 876 /** 877 * Adds the specified <code>ItemListener</code> to the list of 878 * registered listeners for this object. 879 * 880 * @param listener The listener to add. 881 * 882 * @since 1.1 883 */ addItemListener(ItemListener listener)884 public synchronized void addItemListener(ItemListener listener) 885 { 886 item_listeners = AWTEventMulticaster.add(item_listeners, listener); 887 } 888 889 /** 890 * Removes the specified <code>ItemListener</code> from the list of 891 * registers listeners for this object. 892 * 893 * @param listener The listener to remove. 894 * 895 * @since 1.1 896 */ removeItemListener(ItemListener listener)897 public synchronized void removeItemListener(ItemListener listener) 898 { 899 item_listeners = AWTEventMulticaster.remove(item_listeners, listener); 900 } 901 902 /** 903 * Processes the specified event for this object. If the event is an 904 * instance of <code>ActionEvent</code> then the 905 * <code>processActionEvent()</code> method is called. Similarly, if the 906 * even is an instance of <code>ItemEvent</code> then the 907 * <code>processItemEvent()</code> method is called. Otherwise the 908 * superclass method is called to process this event. 909 * 910 * @param event The event to process. 911 * 912 * @since 1.1 913 */ processEvent(AWTEvent event)914 protected void processEvent(AWTEvent event) 915 { 916 if (event instanceof ActionEvent) 917 processActionEvent((ActionEvent)event); 918 else if (event instanceof ItemEvent) 919 processItemEvent((ItemEvent)event); 920 else 921 super.processEvent(event); 922 } 923 924 /** 925 * This method processes the specified event by dispatching it to any 926 * registered listeners. Note that this method will only get called if 927 * action events are enabled. This will happen automatically if any 928 * listeners are added, or it can be done "manually" by calling 929 * the <code>enableEvents()</code> method. 930 * 931 * @param event The event to process. 932 * 933 * @since 1.1 934 */ processActionEvent(ActionEvent event)935 protected void processActionEvent(ActionEvent event) 936 { 937 if (action_listeners != null) 938 action_listeners.actionPerformed(event); 939 } 940 941 /** 942 * This method processes the specified event by dispatching it to any 943 * registered listeners. Note that this method will only get called if 944 * item events are enabled. This will happen automatically if any 945 * listeners are added, or it can be done "manually" by calling 946 * the <code>enableEvents()</code> method. 947 * 948 * @param event The event to process. 949 * 950 * @since 1.1 951 */ processItemEvent(ItemEvent event)952 protected void processItemEvent(ItemEvent event) 953 { 954 if (item_listeners != null) 955 item_listeners.itemStateChanged(event); 956 } 957 dispatchEventImpl(AWTEvent e)958 void dispatchEventImpl(AWTEvent e) 959 { 960 if (e.id <= ItemEvent.ITEM_LAST 961 && e.id >= ItemEvent.ITEM_FIRST 962 && (item_listeners != null 963 || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0)) 964 processEvent(e); 965 else if (e.id <= ActionEvent.ACTION_LAST 966 && e.id >= ActionEvent.ACTION_FIRST 967 && (action_listeners != null 968 || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0)) 969 processEvent(e); 970 else 971 super.dispatchEventImpl(e); 972 } 973 974 /** 975 * Returns a debugging string for this object. 976 * 977 * @return A debugging string for this object. 978 */ paramString()979 protected String paramString() 980 { 981 return "multiple=" + multipleMode + ",rows=" + rows + super.paramString(); 982 } 983 984 /** 985 * Returns an array of all the objects currently registered as FooListeners 986 * upon this <code>List</code>. FooListeners are registered using the 987 * addFooListener method. 988 * 989 * @exception ClassCastException If listenerType doesn't specify a class or 990 * interface that implements java.util.EventListener. 991 * 992 * @since 1.3 993 */ getListeners(Class<T> listenerType)994 public <T extends EventListener> T[] getListeners (Class<T> listenerType) 995 { 996 if (listenerType == ActionListener.class) 997 return AWTEventMulticaster.getListeners (action_listeners, listenerType); 998 999 if (listenerType == ItemListener.class) 1000 return AWTEventMulticaster.getListeners (item_listeners, listenerType); 1001 1002 return super.getListeners (listenerType); 1003 } 1004 1005 /** 1006 * Returns all action listeners registered to this object. 1007 * 1008 * @since 1.4 1009 */ getActionListeners()1010 public ActionListener[] getActionListeners () 1011 { 1012 return (ActionListener[]) getListeners (ActionListener.class); 1013 } 1014 1015 /** 1016 * Returns all action listeners registered to this object. 1017 * 1018 * @since 1.4 1019 */ getItemListeners()1020 public ItemListener[] getItemListeners () 1021 { 1022 return (ItemListener[]) getListeners (ItemListener.class); 1023 } 1024 1025 // Accessibility internal class 1026 protected class AccessibleAWTList extends AccessibleAWTComponent 1027 implements AccessibleSelection, ItemListener, ActionListener 1028 { 1029 private static final long serialVersionUID = 7924617370136012829L; 1030 1031 protected class AccessibleAWTListChild extends AccessibleAWTComponent 1032 implements Accessible 1033 { 1034 private static final long serialVersionUID = 4412022926028300317L; 1035 1036 // Field names are fixed by serialization spec. 1037 private List parent; 1038 private int indexInParent; 1039 AccessibleAWTListChild(List parent, int indexInParent)1040 public AccessibleAWTListChild(List parent, int indexInParent) 1041 { 1042 this.parent = parent; 1043 this.indexInParent = indexInParent; 1044 if (parent == null) 1045 this.indexInParent = -1; 1046 } 1047 1048 /* (non-Javadoc) 1049 * @see javax.accessibility.Accessible#getAccessibleContext() 1050 */ getAccessibleContext()1051 public AccessibleContext getAccessibleContext() 1052 { 1053 return this; 1054 } 1055 getAccessibleRole()1056 public AccessibleRole getAccessibleRole() 1057 { 1058 return AccessibleRole.LIST_ITEM; 1059 } 1060 getAccessibleStateSet()1061 public AccessibleStateSet getAccessibleStateSet() 1062 { 1063 AccessibleStateSet states = super.getAccessibleStateSet(); 1064 if (parent.isIndexSelected(indexInParent)) 1065 states.add(AccessibleState.SELECTED); 1066 return states; 1067 } 1068 getAccessibleIndexInParent()1069 public int getAccessibleIndexInParent() 1070 { 1071 return indexInParent; 1072 } 1073 1074 } 1075 AccessibleAWTList()1076 public AccessibleAWTList() 1077 { 1078 addItemListener(this); 1079 addActionListener(this); 1080 } 1081 getAccessibleRole()1082 public AccessibleRole getAccessibleRole() 1083 { 1084 return AccessibleRole.LIST; 1085 } 1086 getAccessibleStateSet()1087 public AccessibleStateSet getAccessibleStateSet() 1088 { 1089 AccessibleStateSet states = super.getAccessibleStateSet(); 1090 states.add(AccessibleState.SELECTABLE); 1091 if (isMultipleMode()) 1092 states.add(AccessibleState.MULTISELECTABLE); 1093 return states; 1094 } 1095 getAccessibleChildrenCount()1096 public int getAccessibleChildrenCount() 1097 { 1098 return getItemCount(); 1099 } 1100 getAccessibleChild(int i)1101 public Accessible getAccessibleChild(int i) 1102 { 1103 if (i >= getItemCount()) 1104 return null; 1105 return new AccessibleAWTListChild(List.this, i); 1106 } 1107 1108 /* (non-Javadoc) 1109 * @see javax.accessibility.AccessibleSelection#getAccessibleSelectionCount() 1110 */ getAccessibleSelectionCount()1111 public int getAccessibleSelectionCount() 1112 { 1113 return getSelectedIndexes().length; 1114 } 1115 1116 /* (non-Javadoc) 1117 * @see javax.accessibility.AccessibleSelection#getAccessibleSelection() 1118 */ getAccessibleSelection()1119 public AccessibleSelection getAccessibleSelection() 1120 { 1121 return this; 1122 } 1123 1124 /* (non-Javadoc) 1125 * @see javax.accessibility.AccessibleSelection#getAccessibleSelection(int) 1126 */ getAccessibleSelection(int i)1127 public Accessible getAccessibleSelection(int i) 1128 { 1129 int[] items = getSelectedIndexes(); 1130 if (i >= items.length) 1131 return null; 1132 return new AccessibleAWTListChild(List.this, items[i]); 1133 } 1134 1135 /* (non-Javadoc) 1136 * @see javax.accessibility.AccessibleSelection#isAccessibleChildSelected(int) 1137 */ isAccessibleChildSelected(int i)1138 public boolean isAccessibleChildSelected(int i) 1139 { 1140 return isIndexSelected(i); 1141 } 1142 1143 /* (non-Javadoc) 1144 * @see javax.accessibility.AccessibleSelection#addAccessibleSelection(int) 1145 */ addAccessibleSelection(int i)1146 public void addAccessibleSelection(int i) 1147 { 1148 select(i); 1149 } 1150 1151 /* (non-Javadoc) 1152 * @see javax.accessibility.AccessibleSelection#removeAccessibleSelection(int) 1153 */ removeAccessibleSelection(int i)1154 public void removeAccessibleSelection(int i) 1155 { 1156 deselect(i); 1157 } 1158 1159 /* (non-Javadoc) 1160 * @see javax.accessibility.AccessibleSelection#clearAccessibleSelection() 1161 */ clearAccessibleSelection()1162 public void clearAccessibleSelection() 1163 { 1164 for (int i = 0; i < getItemCount(); i++) 1165 deselect(i); 1166 } 1167 1168 /* (non-Javadoc) 1169 * @see javax.accessibility.AccessibleSelection#selectAllAccessibleSelection() 1170 */ selectAllAccessibleSelection()1171 public void selectAllAccessibleSelection() 1172 { 1173 if (isMultipleMode()) 1174 for (int i = 0; i < getItemCount(); i++) 1175 select(i); 1176 } 1177 1178 /* (non-Javadoc) 1179 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) 1180 */ itemStateChanged(ItemEvent event)1181 public void itemStateChanged(ItemEvent event) 1182 { 1183 } 1184 1185 /* (non-Javadoc) 1186 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) 1187 */ actionPerformed(ActionEvent event)1188 public void actionPerformed(ActionEvent event) 1189 { 1190 } 1191 1192 } 1193 1194 /** 1195 * Gets the AccessibleContext associated with this <code>List</code>. 1196 * The context is created, if necessary. 1197 * 1198 * @return the associated context 1199 */ getAccessibleContext()1200 public AccessibleContext getAccessibleContext() 1201 { 1202 /* Create the context if this is the first request */ 1203 if (accessibleContext == null) 1204 accessibleContext = new AccessibleAWTList(); 1205 return accessibleContext; 1206 } 1207 1208 /** 1209 * Generate a unique name for this <code>List</code>. 1210 * 1211 * @return A unique name for this <code>List</code>. 1212 */ generateName()1213 String generateName() 1214 { 1215 return "list" + getUniqueLong(); 1216 } 1217 getUniqueLong()1218 private static synchronized long getUniqueLong() 1219 { 1220 return next_list_number++; 1221 } 1222 } // class List 1223