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