Source for java.awt.MenuItem

   1: /* MenuItem.java -- An item in a menu
   2:    Copyright (C) 1999, 2000, 2001, 2002, 2003, 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.peer.MenuItemPeer;
  44: import java.io.Serializable;
  45: import java.lang.reflect.Array;
  46: import java.util.EventListener;
  47: 
  48: import javax.accessibility.Accessible;
  49: import javax.accessibility.AccessibleAction;
  50: import javax.accessibility.AccessibleContext;
  51: import javax.accessibility.AccessibleRole;
  52: import javax.accessibility.AccessibleValue;
  53: 
  54: /**
  55:   * This class represents an item in a menu.
  56:   *
  57:   * @author Aaron M. Renn (arenn@urbanophile.com)
  58:   */
  59: public class MenuItem extends MenuComponent
  60:   implements Serializable, Accessible
  61: {
  62: 
  63: /*
  64:  * Static Variables
  65:  */
  66: 
  67: // Serialization Constant
  68: private static final long serialVersionUID = -21757335363267194L;
  69: 
  70: /*************************************************************************/
  71: 
  72: /*
  73:  * Instance Variables
  74:  */
  75: 
  76: /**
  77:   * @serial The name of the action command generated by this item.
  78:   * This is package-private to avoid an accessor method.
  79:   */
  80: String actionCommand;
  81: 
  82: /**
  83:   * @serial Indicates whether or not this menu item is enabled.
  84:   * This is package-private to avoid an accessor method.
  85:   */
  86: boolean enabled = true;
  87: 
  88: /**
  89:   * @serial The mask of events that are enabled for this menu item.
  90:   */
  91: long eventMask;
  92: 
  93: /**
  94:   * @serial This menu item's label
  95:   * This is package-private to avoid an accessor method.
  96:   */
  97: String label = "";
  98: 
  99: /**
 100:   * @serial The shortcut for this menu item, if any
 101:   */
 102: private MenuShortcut shortcut;
 103: 
 104: // The list of action listeners for this menu item.
 105: private transient ActionListener action_listeners;
 106: 
 107:   protected class AccessibleAWTMenuItem
 108:     extends MenuComponent.AccessibleAWTMenuComponent
 109:     implements AccessibleAction, AccessibleValue
 110:   {
 111:     /** Constructor */
 112:     public AccessibleAWTMenuItem()
 113:     {
 114:       super();
 115:     }
 116:   
 117:   
 118:   
 119:     public String getAccessibleName()
 120:     {
 121:       return label;
 122:     }
 123:   
 124:     public AccessibleAction getAccessibleAction()
 125:     {
 126:       return this;
 127:     }
 128:   
 129:     public AccessibleRole getAccessibleRole()
 130:     {
 131:       return AccessibleRole.MENU_ITEM;
 132:     }
 133:   
 134:     /* (non-Javadoc)
 135:      * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
 136:      */
 137:     public int getAccessibleActionCount()
 138:     {
 139:       return 1;
 140:     }
 141: 
 142:     /* (non-Javadoc)
 143:      * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
 144:      */
 145:     public String getAccessibleActionDescription(int i)
 146:     {
 147:       if (i == 0)
 148:     return label;
 149:       else
 150:     return null;
 151:     }
 152: 
 153:     /* (non-Javadoc)
 154:      * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
 155:      */
 156:     public boolean doAccessibleAction(int i)
 157:     {
 158:       if (i != 0)
 159:     return false;
 160:       processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
 161:       return true;
 162:     }
 163: 
 164:     public AccessibleValue getAccessibleValue()
 165:     {
 166:       return this;
 167:     }
 168:   
 169:     /* (non-Javadoc)
 170:      * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
 171:      */
 172:     public Number getCurrentAccessibleValue()
 173:     {
 174:       return (enabled) ? new Integer(1) : new Integer(0);
 175:     }
 176: 
 177:     /* (non-Javadoc)
 178:      * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
 179:      */
 180:     public boolean setCurrentAccessibleValue(Number number)
 181:     {
 182:       if (number.intValue() == 0)
 183:     {
 184:       setEnabled(false);
 185:       return false;
 186:     }
 187:     
 188:       setEnabled(true);
 189:       return true;
 190:     }
 191: 
 192:     /* (non-Javadoc)
 193:      * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
 194:      */
 195:     public Number getMinimumAccessibleValue()
 196:     {
 197:       return new Integer(0);
 198:     }
 199: 
 200:     /* (non-Javadoc)
 201:      * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
 202:      */
 203:     public Number getMaximumAccessibleValue()
 204:     {
 205:       return new Integer(0);
 206:     }
 207:   
 208:   }
 209: 
 210: 
 211: /*************************************************************************/
 212: 
 213: /*
 214:  * Constructors
 215:  */
 216: 
 217: /**
 218:   * Initializes a new instance of <code>MenuItem</code> with no label
 219:   * and no shortcut.
 220:   */
 221: public
 222: MenuItem()
 223: {
 224: }
 225: 
 226: /*************************************************************************/
 227: 
 228: /**
 229:   * Initializes a new instance of <code>MenuItem</code> with the specified
 230:   * label and no shortcut.
 231:   *
 232:   * @param label The label for this menu item.
 233:   */
 234: public 
 235: MenuItem(String label)
 236: {
 237:   this.label = label;
 238: }
 239: 
 240: /*************************************************************************/
 241: 
 242: /**
 243:   * Initializes a new instance of <code>MenuItem</code> with the specified
 244:   * label and shortcut.
 245:   *
 246:   * @param label The label for this menu item.
 247:   * @param shortcut The shortcut for this menu item.
 248:   */
 249: public
 250: MenuItem(String label, MenuShortcut shortcut)
 251: {
 252:   this.label = label;
 253:   this.shortcut = shortcut;
 254: }
 255: 
 256: /*************************************************************************/
 257: 
 258: /*
 259:  * Instance Methods
 260:  */
 261: 
 262: /**
 263:   * Returns the label for this menu item, which may be <code>null</code>.
 264:   *
 265:   * @return The label for this menu item.
 266:   */
 267: public String
 268: getLabel()
 269: {
 270:   return(label);
 271: }
 272: 
 273: /*************************************************************************/
 274: 
 275: /**
 276:   * This method sets the label for this menu to the specified value.
 277:   *
 278:   * @param label The new label for this menu item.
 279:   */
 280: public synchronized void
 281: setLabel(String label)
 282: {
 283:   this.label = label;
 284:   if (peer != null)
 285:     {
 286:       MenuItemPeer mp = (MenuItemPeer) peer;
 287:       mp.setLabel (label);
 288:     }
 289: }
 290: 
 291: /*************************************************************************/
 292: 
 293: /**
 294:   * Tests whether or not this menu item is enabled.
 295:   *
 296:   * @return <code>true</code> if this menu item is enabled, <code>false</code>
 297:   * otherwise.
 298:   */
 299: public boolean
 300: isEnabled()
 301: {
 302:   return(enabled);
 303: }
 304: 
 305: /*************************************************************************/
 306: 
 307: /**
 308:   * Sets the enabled status of this menu item.
 309:   * 
 310:   * @param enabled <code>true</code> to enable this menu item,
 311:   * <code>false</code> otherwise.
 312:   */
 313: public synchronized void
 314: setEnabled(boolean enabled)
 315: {
 316:   enable (enabled);
 317: }
 318: 
 319: /*************************************************************************/
 320: 
 321: /**
 322:   * Sets the enabled status of this menu item.
 323:   * 
 324:   * @param enabled <code>true</code> to enable this menu item,
 325:   * <code>false</code> otherwise.
 326:   *
 327:   * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
 328:   */
 329: public void
 330: enable(boolean enabled)
 331: {
 332:   if (enabled)
 333:     enable ();
 334:   else
 335:     disable ();
 336: }
 337: 
 338: /*************************************************************************/
 339: 
 340: /**
 341:   * Enables this menu item.
 342:   *
 343:   * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
 344:   */
 345: public void
 346: enable()
 347: {
 348:   if (enabled)
 349:     return;
 350: 
 351:   this.enabled = true;
 352:   if (peer != null)
 353:     ((MenuItemPeer) peer).setEnabled (true);
 354: }
 355: 
 356: /*************************************************************************/
 357: 
 358: /**
 359:   * Disables this menu item.
 360:   *
 361:   * @deprecated This method is deprecated in favor of <code>setEnabled()</code>.
 362:   */
 363: public void
 364: disable()
 365: {
 366:   if (!enabled)
 367:     return;
 368: 
 369:   this.enabled = false;
 370:   if (peer != null)
 371:     ((MenuItemPeer) peer).setEnabled (false);
 372: }
 373: 
 374: /*************************************************************************/
 375: 
 376: /**
 377:   * Returns the shortcut for this menu item, which may be <code>null</code>.
 378:   *
 379:   * @return The shortcut for this menu item.
 380:   */
 381: public MenuShortcut
 382: getShortcut()
 383: {
 384:   return(shortcut);
 385: }
 386: 
 387: /*************************************************************************/
 388: 
 389: /**
 390:   * Sets the shortcut for this menu item to the specified value.  This
 391:   * must be done before the native peer is created.
 392:   *
 393:   * @param shortcut The new shortcut for this menu item.
 394:   */
 395: public void
 396: setShortcut(MenuShortcut shortcut)
 397: {
 398:   this.shortcut = shortcut;
 399: }
 400: 
 401: /*************************************************************************/
 402: 
 403: /**
 404:   * Deletes the shortcut for this menu item if one exists.  This must be
 405:   * done before the native peer is created.
 406:   */
 407: public void
 408: deleteShortcut()
 409: {
 410:   shortcut = null;
 411: }
 412: 
 413: /*************************************************************************/
 414: 
 415: /**
 416:   * Returns the name of the action command in the action events
 417:   * generated by this menu item.
 418:   *
 419:   * @return The action command name
 420:   */
 421: public String
 422: getActionCommand()
 423: {
 424:   if (actionCommand == null)
 425:     return label;
 426:   else
 427:     return actionCommand;
 428: }
 429: 
 430: /*************************************************************************/
 431: 
 432: /**
 433:   * Sets the name of the action command in the action events generated by
 434:   * this menu item.
 435:   *
 436:   * @param actionCommand The new action command name.
 437:   */
 438: public void
 439: setActionCommand(String actionCommand)
 440: {
 441:   this.actionCommand = actionCommand;
 442: }
 443: 
 444: /*************************************************************************/
 445: 
 446: /**
 447:   * Enables the specified events.  This is done automatically when a 
 448:   * listener is added and does not normally need to be done by
 449:   * application code.
 450:   *
 451:   * @param events The events to enable, which should be the bit masks
 452:   * from <code>AWTEvent</code>.
 453:   */
 454: protected final void
 455: enableEvents(long events)
 456: {
 457:   eventMask |= events;
 458:   // TODO: see comment in Component.enableEvents().    
 459: }
 460: 
 461: /*************************************************************************/
 462: 
 463: /**
 464:   * Disables the specified events.
 465:   *
 466:   * @param events The events to enable, which should be the bit masks
 467:   * from <code>AWTEvent</code>.
 468:   */
 469: protected final void
 470: disableEvents(long events)
 471: {
 472:   eventMask &= ~events;
 473: }
 474: 
 475: /*************************************************************************/
 476: 
 477: /**
 478:   * Creates the native peer for this object.
 479:   */
 480: public void
 481: addNotify()
 482: {
 483:   if (peer == null)
 484:     peer = getToolkit ().createMenuItem (this);
 485: }
 486: 
 487: /*************************************************************************/
 488: 
 489: /**
 490:   * Adds the specified listener to the list of registered action listeners
 491:   * for this component.
 492:   *
 493:   * @param listener The listener to add.
 494:   */
 495: public synchronized void
 496: addActionListener(ActionListener listener)
 497: {
 498:   action_listeners = AWTEventMulticaster.add(action_listeners, listener);
 499: 
 500:   enableEvents(AWTEvent.ACTION_EVENT_MASK);
 501: }
 502: 
 503: public synchronized void
 504: removeActionListener(ActionListener l)
 505: {
 506:   action_listeners = AWTEventMulticaster.remove(action_listeners, l);
 507: }
 508: 
 509:   public synchronized ActionListener[] getActionListeners()
 510:   {
 511:     return (ActionListener[])
 512:       AWTEventMulticaster.getListeners(action_listeners,
 513:                                        ActionListener.class);
 514:   }
 515: 
 516: /** Returns all registered EventListers of the given listenerType. 
 517:  * listenerType must be a subclass of EventListener, or a 
 518:  * ClassClassException is thrown.
 519:  * @since 1.3 
 520:  */
 521:   public EventListener[] getListeners(Class listenerType)
 522:   {
 523:     if (listenerType == ActionListener.class)
 524:       return getActionListeners();
 525:     return (EventListener[]) Array.newInstance(listenerType, 0);
 526:   }
 527: 
 528: /*************************************************************************/
 529: 
 530: void
 531: dispatchEventImpl(AWTEvent e)
 532: {
 533:   if (e.id <= ActionEvent.ACTION_LAST 
 534:       && e.id >= ActionEvent.ACTION_FIRST
 535:       && (action_listeners != null
 536:       || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
 537:     processEvent(e);
 538: 
 539:   // Send the event to the parent menu if it has not yet been
 540:   // consumed.
 541:   if (!e.isConsumed ())
 542:     ((Menu) getParent ()).processEvent (e);
 543: }
 544: 
 545: /**
 546:   * Processes the specified event by calling <code>processActionEvent()</code>
 547:   * if it is an instance of <code>ActionEvent</code>.
 548:   *
 549:   * @param event The event to process.
 550:   */
 551: protected void
 552: processEvent(AWTEvent event)
 553: {
 554:   if (event instanceof ActionEvent)
 555:     processActionEvent((ActionEvent)event);
 556: }
 557: 
 558: /*************************************************************************/
 559: 
 560: /**
 561:   * Processes the specified event by dispatching it to any registered listeners.
 562:   *
 563:   * @param event The event to process.
 564:   */
 565: protected void
 566: processActionEvent(ActionEvent event)
 567: {
 568:   if (action_listeners != null)
 569:     {
 570:       event.setSource(this);
 571:       action_listeners.actionPerformed(event);
 572:     }
 573: }
 574: 
 575: /*************************************************************************/
 576: 
 577: /**
 578:   * Returns a debugging string for this object.
 579:   *
 580:   * @return A debugging string for this object.
 581:   */
 582: public String
 583: paramString()
 584: {
 585:   return ("label=" + label + ",enabled=" + enabled +
 586:       ",actionCommand=" + actionCommand + "," + super.paramString());
 587: }
 588: 
 589: /**
 590:  * Gets the AccessibleContext associated with this <code>MenuItem</code>.
 591:  * The context is created, if necessary.
 592:  *
 593:  * @return the associated context
 594:  */
 595: public AccessibleContext getAccessibleContext()
 596: {
 597:   /* Create the context if this is the first request */
 598:   if (accessibleContext == null)
 599:     accessibleContext = new AccessibleAWTMenuItem();
 600:   return accessibleContext;
 601: }
 602: 
 603: } // class MenuItem