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