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