GNU Classpath (0.92) | |
Frames | No Frames |
1: /* Choice.java -- Java choice button widget. 2: Copyright (C) 1999, 2000, 2001, 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.ItemEvent; 42: import java.awt.event.ItemListener; 43: import java.awt.peer.ChoicePeer; 44: import java.io.Serializable; 45: import java.util.EventListener; 46: import java.util.Vector; 47: 48: import javax.accessibility.Accessible; 49: import javax.accessibility.AccessibleAction; 50: import javax.accessibility.AccessibleContext; 51: import javax.accessibility.AccessibleRole; 52: 53: /** 54: * This class implements a drop down choice list. 55: * 56: * @author Aaron M. Renn (arenn@urbanophile.com) 57: */ 58: public class Choice extends Component 59: implements ItemSelectable, Serializable, Accessible 60: { 61: 62: /* 63: * Static Variables 64: */ 65: 66: /** 67: * The number used to generate the name returned by getName. 68: */ 69: private static transient long next_choice_number; 70: 71: // Serialization constant 72: private static final long serialVersionUID = -4075310674757313071L; 73: 74: /*************************************************************************/ 75: 76: /* 77: * Instance Variables 78: */ 79: 80: /** 81: * @serial A list of items for the choice box, which can be <code>null</code>. 82: * This is package-private to avoid an accessor method. 83: */ 84: Vector pItems = new Vector(); 85: 86: /** 87: * @serial The index of the selected item in the choice box. 88: */ 89: private int selectedIndex = -1; 90: 91: // Listener chain 92: private ItemListener item_listeners; 93: 94: /** 95: * This class provides accessibility support for the 96: * combo box. 97: * 98: * @author Jerry Quinn (jlquinn@optonline.net) 99: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 100: */ 101: protected class AccessibleAWTChoice 102: extends AccessibleAWTComponent 103: implements AccessibleAction 104: { 105: 106: /** 107: * Serialization constant to match JDK 1.5 108: */ 109: private static final long serialVersionUID = 7175603582428509322L; 110: 111: /** 112: * Default constructor which simply calls the 113: * super class for generic component accessibility 114: * handling. 115: */ 116: public AccessibleAWTChoice() 117: { 118: super(); 119: } 120: 121: /** 122: * Returns an implementation of the <code>AccessibleAction</code> 123: * interface for this accessible object. In this case, the 124: * current instance is simply returned (with a more appropriate 125: * type), as it also implements the accessible action as well as 126: * the context. 127: * 128: * @return the accessible action associated with this context. 129: * @see javax.accessibility.AccessibleAction 130: */ 131: public AccessibleAction getAccessibleAction() 132: { 133: return this; 134: } 135: 136: /** 137: * Returns the role of this accessible object. 138: * 139: * @return the instance of <code>AccessibleRole</code>, 140: * which describes this object. 141: * @see javax.accessibility.AccessibleRole 142: */ 143: public AccessibleRole getAccessibleRole() 144: { 145: return AccessibleRole.COMBO_BOX; 146: } 147: 148: /** 149: * Returns the number of actions associated with this accessible 150: * object. In this case, it is the number of choices available. 151: * 152: * @return the number of choices available. 153: * @see javax.accessibility.AccessibleAction#getAccessibleActionCount() 154: */ 155: public int getAccessibleActionCount() 156: { 157: return pItems.size(); 158: } 159: 160: /** 161: * Returns a description of the action with the supplied id. 162: * In this case, it is the text used in displaying the particular 163: * choice on-screen. 164: * 165: * @param i the id of the choice whose description should be 166: * retrieved. 167: * @return the <code>String</code> used to describe the choice. 168: * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int) 169: */ 170: public String getAccessibleActionDescription(int i) 171: { 172: return (String) pItems.get(i); 173: } 174: 175: /** 176: * Executes the action with the specified id. In this case, 177: * calling this method provides the same behaviour as would 178: * choosing a choice from the list in a visual manner. 179: * 180: * @param i the id of the choice to select. 181: * @return true if a valid choice was specified. 182: * @see javax.accessibility.AccessibleAction#doAccessibleAction(int) 183: */ 184: public boolean doAccessibleAction(int i) 185: { 186: if (i < 0 || i >= pItems.size()) 187: return false; 188: 189: Choice.this.processItemEvent(new ItemEvent(Choice.this, 190: ItemEvent.ITEM_STATE_CHANGED, 191: this, ItemEvent.SELECTED)); 192: return true; 193: } 194: } 195: 196: /*************************************************************************/ 197: 198: /* 199: * Constructors 200: */ 201: 202: /** 203: * Initializes a new instance of <code>Choice</code>. 204: * 205: * @exception HeadlessException If GraphicsEnvironment.isHeadless() 206: * returns true 207: */ 208: public Choice() 209: { 210: if (GraphicsEnvironment.isHeadless()) 211: throw new HeadlessException (); 212: } 213: 214: /*************************************************************************/ 215: 216: /* 217: * Instance Methods 218: */ 219: 220: /** 221: * Returns the number of items in the list. 222: * 223: * @return The number of items in the list. 224: */ 225: public int 226: getItemCount() 227: { 228: return countItems (); 229: } 230: 231: /*************************************************************************/ 232: 233: /** 234: * Returns the number of items in the list. 235: * 236: * @return The number of items in the list. 237: * 238: * @deprecated This method is deprecated in favor of <code>getItemCount</code>. 239: */ 240: public int 241: countItems() 242: { 243: return(pItems.size()); 244: } 245: 246: /*************************************************************************/ 247: 248: /** 249: * Returns the item at the specified index in the list. 250: * 251: * @param index The index into the list to return the item from. 252: * 253: * @exception ArrayIndexOutOfBoundsException If the index is invalid. 254: */ 255: public String 256: getItem(int index) 257: { 258: return((String)pItems.elementAt(index)); 259: } 260: 261: /*************************************************************************/ 262: 263: /** 264: * Adds the specified item to this choice box. 265: * 266: * @param item The item to add. 267: * 268: * @exception NullPointerException If the item's value is null 269: * 270: * @since 1.1 271: */ 272: public synchronized void 273: add(String item) 274: { 275: if (item == null) 276: throw new NullPointerException ("item must be non-null"); 277: 278: pItems.addElement(item); 279: 280: int i = pItems.size () - 1; 281: if (peer != null) 282: { 283: ChoicePeer cp = (ChoicePeer) peer; 284: cp.add (item, i); 285: } 286: else if (selectedIndex == -1) 287: select(0); 288: } 289: 290: /*************************************************************************/ 291: 292: /** 293: * Adds the specified item to this choice box. 294: * 295: * This method is oboslete since Java 2 platform 1.1. Please use @see add 296: * instead. 297: * 298: * @param item The item to add. 299: * 300: * @exception NullPointerException If the item's value is equal to null 301: */ 302: public synchronized void 303: addItem(String item) 304: { 305: add(item); 306: } 307: 308: /*************************************************************************/ 309: 310: /** Inserts an item into this Choice. Existing items are shifted 311: * upwards. If the new item is the only item, then it is selected. 312: * If the currently selected item is shifted, then the first item is 313: * selected. If the currently selected item is not shifted, then it 314: * remains selected. 315: * 316: * @param item The item to add. 317: * @param index The index at which the item should be inserted. 318: * 319: * @exception IllegalArgumentException If index is less than 0 320: */ 321: public synchronized void 322: insert(String item, int index) 323: { 324: if (index < 0) 325: throw new IllegalArgumentException ("index may not be less then 0"); 326: 327: if (index > getItemCount ()) 328: index = getItemCount (); 329: 330: pItems.insertElementAt(item, index); 331: 332: if (peer != null) 333: { 334: ChoicePeer cp = (ChoicePeer) peer; 335: cp.add (item, index); 336: } 337: else if (selectedIndex == -1 || selectedIndex >= index) 338: select(0); 339: } 340: 341: /*************************************************************************/ 342: 343: /** 344: * Removes the specified item from the choice box. 345: * 346: * @param item The item to remove. 347: * 348: * @exception IllegalArgumentException If the specified item doesn't exist. 349: */ 350: public synchronized void 351: remove(String item) 352: { 353: int index = pItems.indexOf(item); 354: if (index == -1) 355: throw new IllegalArgumentException ("item \"" 356: + item + "\" not found in Choice"); 357: remove(index); 358: } 359: 360: /*************************************************************************/ 361: 362: /** 363: * Removes the item at the specified index from the choice box. 364: * 365: * @param index The index of the item to remove. 366: * 367: * @exception IndexOutOfBoundsException If the index is not valid. 368: */ 369: public synchronized void 370: remove(int index) 371: { 372: if ((index < 0) || (index > getItemCount())) 373: throw new IllegalArgumentException("Bad index: " + index); 374: 375: pItems.removeElementAt(index); 376: 377: if (peer != null) 378: { 379: ChoicePeer cp = (ChoicePeer) peer; 380: cp.remove (index); 381: } 382: else 383: { 384: if (getItemCount() == 0) 385: selectedIndex = -1; 386: else if (index == selectedIndex) 387: select(0); 388: } 389: 390: if (selectedIndex > index) 391: --selectedIndex; 392: } 393: 394: /*************************************************************************/ 395: 396: /** 397: * Removes all of the objects from this choice box. 398: */ 399: public synchronized void 400: removeAll() 401: { 402: if (getItemCount() <= 0) 403: return; 404: 405: pItems.removeAllElements (); 406: 407: if (peer != null) 408: { 409: ChoicePeer cp = (ChoicePeer) peer; 410: cp.removeAll (); 411: } 412: 413: selectedIndex = -1; 414: } 415: 416: /*************************************************************************/ 417: 418: /** 419: * Returns the currently selected item, or null if no item is 420: * selected. 421: * 422: * @return The currently selected item. 423: */ 424: public synchronized String 425: getSelectedItem() 426: { 427: return (selectedIndex == -1 428: ? null 429: : ((String)pItems.elementAt(selectedIndex))); 430: } 431: 432: /*************************************************************************/ 433: 434: /** 435: * Returns an array with one row containing the selected item. 436: * 437: * @return An array containing the selected item. 438: */ 439: public synchronized Object[] 440: getSelectedObjects() 441: { 442: if (selectedIndex == -1) 443: return null; 444: 445: Object[] objs = new Object[1]; 446: objs[0] = pItems.elementAt(selectedIndex); 447: 448: return(objs); 449: } 450: 451: /*************************************************************************/ 452: 453: /** 454: * Returns the index of the selected item. 455: * 456: * @return The index of the selected item. 457: */ 458: public int 459: getSelectedIndex() 460: { 461: return(selectedIndex); 462: } 463: 464: /*************************************************************************/ 465: 466: /** 467: * Forces the item at the specified index to be selected. 468: * 469: * @param index The index of the row to make selected. 470: * 471: * @exception IllegalArgumentException If the specified index is invalid. 472: */ 473: public synchronized void 474: select(int index) 475: { 476: if ((index < 0) || (index >= getItemCount())) 477: throw new IllegalArgumentException("Bad index: " + index); 478: 479: if (pItems.size() > 0) { 480: selectedIndex = index; 481: ChoicePeer cp = (ChoicePeer) peer; 482: if (cp != null) { 483: cp.select(index); 484: } 485: } 486: } 487: 488: /*************************************************************************/ 489: 490: /** 491: * Forces the named item to be selected. 492: * 493: * @param item The item to be selected. 494: * 495: * @exception IllegalArgumentException If the specified item does not exist. 496: */ 497: public synchronized void 498: select(String item) 499: { 500: int index = pItems.indexOf(item); 501: if (index >= 0) 502: select(index); 503: } 504: 505: /*************************************************************************/ 506: 507: /** 508: * Creates the native peer for this object. 509: */ 510: public void 511: addNotify() 512: { 513: if (peer == null) 514: peer = getToolkit ().createChoice (this); 515: super.addNotify (); 516: } 517: 518: /*************************************************************************/ 519: 520: /** 521: * Adds the specified listener to the list of registered listeners for 522: * this object. 523: * 524: * @param listener The listener to add. 525: */ 526: public synchronized void 527: addItemListener(ItemListener listener) 528: { 529: item_listeners = AWTEventMulticaster.add(item_listeners, listener); 530: } 531: 532: /*************************************************************************/ 533: 534: /** 535: * Removes the specified listener from the list of registered listeners for 536: * this object. 537: * 538: * @param listener The listener to remove. 539: */ 540: public synchronized void 541: removeItemListener(ItemListener listener) 542: { 543: item_listeners = AWTEventMulticaster.remove(item_listeners, listener); 544: } 545: 546: /*************************************************************************/ 547: 548: /** 549: * Processes this event by invoking <code>processItemEvent()</code> if the 550: * event is an instance of <code>ItemEvent</code>, otherwise the event 551: * is passed to the superclass. 552: * 553: * @param event The event to process. 554: */ 555: protected void 556: processEvent(AWTEvent event) 557: { 558: if (event instanceof ItemEvent) 559: processItemEvent((ItemEvent)event); 560: else 561: super.processEvent(event); 562: } 563: 564: void 565: dispatchEventImpl(AWTEvent e) 566: { 567: if (e.id <= ItemEvent.ITEM_LAST 568: && e.id >= ItemEvent.ITEM_FIRST 569: && (item_listeners != null || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0)) 570: processEvent(e); 571: else 572: super.dispatchEventImpl(e); 573: } 574: 575: /*************************************************************************/ 576: 577: /** 578: * Processes item event by dispatching to any registered listeners. 579: * 580: * @param event The event to process. 581: */ 582: protected void 583: processItemEvent(ItemEvent event) 584: { 585: int index = pItems.indexOf((String) event.getItem()); 586: // Don't call back into the peers when selecting index here 587: if (event.getStateChange() == ItemEvent.SELECTED) 588: this.selectedIndex = index; 589: if (item_listeners != null) 590: item_listeners.itemStateChanged(event); 591: } 592: 593: /*************************************************************************/ 594: 595: /** 596: * Returns a debugging string for this object. 597: * 598: * @return A debugging string for this object. 599: */ 600: protected String 601: paramString() 602: { 603: return ("selectedIndex=" + selectedIndex + "," + super.paramString()); 604: } 605: 606: /** 607: * Returns an array of all the objects currently registered as FooListeners 608: * upon this Choice. FooListeners are registered using the addFooListener 609: * method. 610: * 611: * @exception ClassCastException If listenerType doesn't specify a class or 612: * interface that implements java.util.EventListener. 613: * 614: * @since 1.3 615: */ 616: public EventListener[] getListeners (Class listenerType) 617: { 618: if (listenerType == ItemListener.class) 619: return AWTEventMulticaster.getListeners (item_listeners, listenerType); 620: 621: return super.getListeners (listenerType); 622: } 623: 624: /** 625: * Returns all registered item listeners. 626: * 627: * @since 1.4 628: */ 629: public ItemListener[] getItemListeners () 630: { 631: return (ItemListener[]) getListeners (ItemListener.class); 632: } 633: 634: /** 635: * Gets the AccessibleContext associated with this <code>Choice</code>. 636: * The context is created, if necessary. 637: * 638: * @return the associated context 639: */ 640: public AccessibleContext getAccessibleContext() 641: { 642: /* Create the context if this is the first request */ 643: if (accessibleContext == null) 644: accessibleContext = new AccessibleAWTChoice(); 645: return accessibleContext; 646: } 647: 648: /** 649: * Generate a unique name for this <code>Choice</code>. 650: * 651: * @return A unique name for this <code>Choice</code>. 652: */ 653: String generateName() 654: { 655: return "choice" + getUniqueLong(); 656: } 657: 658: private static synchronized long getUniqueLong() 659: { 660: return next_choice_number++; 661: } 662: } // class Choice
GNU Classpath (0.92) |