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