Source for java.awt.List

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