Source for javax.swing.JMenuItem

   1: /* JMenuItem.java --
   2:    Copyright (C) 2002, 2004, 2005, 2006  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 javax.swing;
  40: 
  41: import gnu.classpath.NotImplementedException;
  42: 
  43: import java.awt.Component;
  44: import java.awt.event.InputEvent;
  45: import java.awt.event.KeyEvent;
  46: import java.awt.event.MouseEvent;
  47: import java.beans.PropertyChangeEvent;
  48: import java.beans.PropertyChangeListener;
  49: import java.util.EventListener;
  50: 
  51: import javax.accessibility.Accessible;
  52: import javax.accessibility.AccessibleContext;
  53: import javax.accessibility.AccessibleRole;
  54: import javax.swing.event.ChangeEvent;
  55: import javax.swing.event.ChangeListener;
  56: import javax.swing.event.MenuDragMouseEvent;
  57: import javax.swing.event.MenuDragMouseListener;
  58: import javax.swing.event.MenuKeyEvent;
  59: import javax.swing.event.MenuKeyListener;
  60: import javax.swing.plaf.MenuItemUI;
  61: 
  62: /**
  63:  * JMenuItem represents element in the menu. It inherits most of
  64:  * its functionality from AbstractButton, however its behavior somewhat
  65:  * varies from it. JMenuItem fire different kinds of events.
  66:  * PropertyChangeEvents are fired when menuItems properties are modified;
  67:  * ChangeEvents are fired when menuItem's state changes and actionEvents are
  68:  * fired when menu item is selected. In addition to this events menuItem also
  69:  * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
  70:  * the menu item or associated key with menu item is invoked respectively.
  71:  */
  72: public class JMenuItem extends AbstractButton implements Accessible,
  73:                                                          MenuElement
  74: {
  75:   private static final long serialVersionUID = -1681004643499461044L;
  76: 
  77:   /** Combination of keyboard keys that can be used to activate this menu item */
  78:   private KeyStroke accelerator;
  79: 
  80:   /**
  81:    * Creates a new JMenuItem object.
  82:    */
  83:   public JMenuItem()
  84:   {
  85:     super();
  86:     init(null, null);
  87:   }
  88: 
  89:   /**
  90:    * Creates a new JMenuItem with the given icon.
  91:    *
  92:    * @param icon Icon that will be displayed on the menu item
  93:    */
  94:   public JMenuItem(Icon icon)
  95:   {
  96:     // FIXME: The requestedFocusEnabled property should
  97:     // be set to false, when only icon is set for menu item.
  98:     super();
  99:     init(null, icon);
 100:   }
 101: 
 102:   /**
 103:    * Creates a new JMenuItem with the given label.
 104:    *
 105:    * @param text label for the menu item
 106:    */
 107:   public JMenuItem(String text)
 108:   {
 109:     this(text, null);
 110:   }
 111: 
 112:   /**
 113:    * Creates a new JMenuItem associated with the specified action.
 114:    *
 115:    * @param action action for this menu item
 116:    */
 117:   public JMenuItem(Action action)
 118:   {
 119:     super();
 120:     super.setAction(action);
 121:     init(null, null);
 122:     if (action != null)
 123:       {
 124:     String name = (String) action.getValue(Action.NAME);
 125:     if (name != null)
 126:           setName(name);
 127: 
 128:     KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
 129:     if (accel != null)
 130:           setAccelerator(accel);
 131: 
 132:     Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY);
 133:     if (mnemonic != null)
 134:           setMnemonic(mnemonic.intValue());
 135: 
 136:     String command = (String) action.getValue(Action.ACTION_COMMAND_KEY);
 137:     if (command != null)
 138:           setActionCommand(command);
 139:       }
 140:   }
 141: 
 142:   /**
 143:    * Creates a new JMenuItem with specified text and icon.
 144:    * Text is displayed to the left of icon by default.
 145:    *
 146:    * @param text label for this menu item
 147:    * @param icon icon that will be displayed on this menu item
 148:    */
 149:   public JMenuItem(String text, Icon icon)
 150:   {
 151:     super();
 152:     init(text, icon);
 153:   }
 154: 
 155:   /**
 156:    * Creates a new JMenuItem object.
 157:    *
 158:    * @param text label for this menu item
 159:    * @param mnemonic - Single key that can be used with a
 160:    * look-and-feel meta key to activate this menu item. However
 161:    * menu item should be visible on the screen when mnemonic is used.
 162:    */
 163:   public JMenuItem(String text, int mnemonic)
 164:   {
 165:     this(text, null);
 166:     setMnemonic(mnemonic);
 167:   }
 168: 
 169:   /**
 170:    * Initializes this menu item
 171:    *
 172:    * @param text label for this menu item
 173:    * @param icon icon to be displayed for this menu item
 174:    */
 175:   protected void init(String text, Icon icon)
 176:   {
 177:     super.init(text, icon);
 178:     setModel(new DefaultButtonModel());
 179: 
 180:     // Initializes properties for this menu item, that are different
 181:     // from Abstract button properties. 
 182:     /* NOTE: According to java specifications paint_border should be set to false,
 183:       since menu item should not have a border. However running few java programs
 184:       it seems that menu items and menues can have a border. Commenting
 185:       out statement below for now. */
 186:     //borderPainted = false;
 187:     focusPainted = false;
 188:     horizontalAlignment = JButton.LEFT;
 189:     horizontalTextPosition = JButton.TRAILING;
 190:   }
 191: 
 192:   /**
 193:    * Set the "UI" property of the menu item, which is a look and feel class
 194:    * responsible for handling menuItem's input events and painting it.
 195:    *
 196:    * @param ui The new "UI" property
 197:    */
 198:   public void setUI(MenuItemUI ui)
 199:   {
 200:     super.setUI(ui);
 201:   }
 202:   
 203:   /**
 204:    * This method sets this menuItem's UI to the UIManager's default for the
 205:    * current look and feel.
 206:    */
 207:   public void updateUI()
 208:   {
 209:     setUI((MenuItemUI) UIManager.getUI(this));
 210:   }
 211: 
 212:   /**
 213:    * This method returns a name to identify which look and feel class will be
 214:    * the UI delegate for the menuItem.
 215:    *
 216:    * @return The Look and Feel classID. "MenuItemUI"
 217:    */
 218:   public String getUIClassID()
 219:   {
 220:     return "MenuItemUI";
 221:   }
 222: 
 223:   /**
 224:    * Returns true if button's model is armed and false otherwise. The
 225:    * button model is armed if menu item has focus or it is selected.
 226:    *
 227:    * @return $boolean$ true if button's model is armed and false otherwise
 228:    */
 229:   public boolean isArmed()
 230:   {
 231:     return getModel().isArmed();
 232:   }
 233: 
 234:   /**
 235:    * Sets menuItem's "ARMED" property
 236:    *
 237:    * @param armed DOCUMENT ME!
 238:    */
 239:   public void setArmed(boolean armed)
 240:   {
 241:     getModel().setArmed(armed);
 242:   }
 243: 
 244:   /**
 245:    * Enable or disable menu item. When menu item is disabled,
 246:    * its text and icon are grayed out if they exist.
 247:    *
 248:    * @param enabled if true enable menu item, and disable otherwise.
 249:    */
 250:   public void setEnabled(boolean enabled)
 251:   {
 252:     super.setEnabled(enabled);
 253:   }
 254: 
 255:   /**
 256:    * Return accelerator for this menu item.
 257:    *
 258:    * @return $KeyStroke$ accelerator for this menu item.
 259:    */
 260:   public KeyStroke getAccelerator()
 261:   {
 262:     return accelerator;
 263:   }
 264: 
 265:   /**
 266:    * Sets the key combination which invokes the menu item's action 
 267:    * listeners without navigating the menu hierarchy. Note that when the 
 268:    * keyboard accelerator is typed, it will work whether or not the 
 269:    * menu is currently displayed.
 270:    * 
 271:    * @param keystroke accelerator for this menu item.
 272:    */
 273:   public void setAccelerator(KeyStroke keystroke)
 274:   {
 275:     KeyStroke old = this.accelerator;
 276:     this.accelerator = keystroke;
 277:     firePropertyChange ("accelerator", old, keystroke);
 278:   }
 279: 
 280:   /**
 281:    * Configures menu items' properties from properties of the specified action.
 282:    * This method overrides configurePropertiesFromAction from AbstractButton
 283:    * to also set accelerator property.
 284:    *
 285:    * @param action action to configure properties from
 286:    */
 287:   protected void configurePropertiesFromAction(Action action)
 288:   {
 289:     super.configurePropertiesFromAction(action);
 290: 
 291:     if (! (this instanceof JMenu) && action != null)
 292:       {
 293:         setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
 294:         if (accelerator != null)
 295:           super.registerKeyboardAction(action, accelerator, 
 296:                                        JComponent.WHEN_IN_FOCUSED_WINDOW);
 297:       }
 298:   }
 299: 
 300:   /**
 301:    * Creates PropertyChangeListener to listen for the changes in action
 302:    * properties.
 303:    *
 304:    * @param action action to listen to for property changes
 305:    *
 306:    * @return $PropertyChangeListener$ Listener that listens to changes in
 307:    * action properties.
 308:    */
 309:   protected PropertyChangeListener createActionPropertyChangeListener(Action action)
 310:   {
 311:     return new PropertyChangeListener()
 312:       {
 313:     public void propertyChange(PropertyChangeEvent e)
 314:     {
 315:       Action act = (Action) (e.getSource());
 316:       configurePropertiesFromAction(act);
 317:     }
 318:       };
 319:   }
 320: 
 321:   /**
 322:    * Process mouse events forwarded from MenuSelectionManager.
 323:    *
 324:    * @param event event forwarded from MenuSelectionManager
 325:    * @param path path to the menu element from which event was generated
 326:    * @param manager MenuSelectionManager for the current menu hierarchy
 327:    */
 328:   public void processMouseEvent(MouseEvent event, MenuElement[] path,
 329:                                 MenuSelectionManager manager)
 330:   {
 331:     // Fire MenuDragMouseEvents if mouse is being dragged.
 332:     boolean dragged
 333:       = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0;
 334:     if (dragged)
 335:       processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager));
 336: 
 337:     switch (event.getID())
 338:       {
 339:       case MouseEvent.MOUSE_CLICKED:
 340:     break;
 341:       case MouseEvent.MOUSE_ENTERED:
 342:     if (isRolloverEnabled())
 343:       model.setRollover(true);
 344:     break;
 345:       case MouseEvent.MOUSE_EXITED:
 346:     if (isRolloverEnabled())
 347:       model.setRollover(false);
 348: 
 349:     // for JMenu last element on the path is its popupMenu.
 350:     // JMenu shouldn't me disarmed.    
 351:     if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged)
 352:       setArmed(false);
 353:     break;
 354:       case MouseEvent.MOUSE_PRESSED:
 355:     if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
 356:       {
 357:         model.setArmed(true);
 358:         model.setPressed(true);
 359:       }
 360:     break;
 361:       case MouseEvent.MOUSE_RELEASED:
 362:     break;
 363:       case MouseEvent.MOUSE_MOVED:
 364:     break;
 365:       case MouseEvent.MOUSE_DRAGGED:
 366:     break;
 367:       }
 368:   }
 369: 
 370:   /**
 371:    * Creates MenuDragMouseEvent.
 372:    *
 373:    * @param event MouseEvent that occured while mouse was pressed.
 374:    * @param path Path the the menu element where the dragging event was
 375:    *        originated
 376:    * @param manager MenuSelectionManager for the current menu hierarchy.
 377:    *
 378:    * @return new MenuDragMouseEvent
 379:    */
 380:   private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event,
 381:                                                       MenuElement[] path,
 382:                                                       MenuSelectionManager manager)
 383:   {
 384:     return new MenuDragMouseEvent((Component) event.getSource(),
 385:                                   event.getID(), event.getWhen(),
 386:                                   event.getModifiers(), event.getX(),
 387:                                   event.getY(), event.getClickCount(),
 388:                                   event.isPopupTrigger(), path, manager);
 389:   }
 390: 
 391:   /**
 392:    * Process key events forwarded from MenuSelectionManager.
 393:    *
 394:    * @param event event forwarded from MenuSelectionManager
 395:    * @param path path to the menu element from which event was generated
 396:    * @param manager MenuSelectionManager for the current menu hierarchy
 397:    */
 398:   public void processKeyEvent(KeyEvent event, MenuElement[] path,
 399:                               MenuSelectionManager manager)
 400:   {
 401:     MenuKeyEvent e = new MenuKeyEvent(event.getComponent(), event.getID(),
 402:                                       event.getWhen(), event.getModifiers(),
 403:                                       event.getKeyCode(), event.getKeyChar(),
 404:                                       path, manager);
 405:     processMenuKeyEvent(e);
 406: 
 407:     // Consume original key event, if the menu key event has been consumed.
 408:     if (e.isConsumed())
 409:       event.consume();
 410:   }
 411: 
 412:   /**
 413:    * This method fires MenuDragMouseEvents to registered listeners.
 414:    * Different types of MenuDragMouseEvents are fired depending
 415:    * on the observed mouse event.
 416:    *
 417:    * @param event Mouse
 418:    */
 419:   public void processMenuDragMouseEvent(MenuDragMouseEvent event)
 420:   {
 421:     switch (event.getID())
 422:       {
 423:       case MouseEvent.MOUSE_ENTERED:
 424:     fireMenuDragMouseEntered(event);
 425:     break;
 426:       case MouseEvent.MOUSE_EXITED:
 427:     fireMenuDragMouseExited(event);
 428:     break;
 429:       case MouseEvent.MOUSE_DRAGGED:
 430:     fireMenuDragMouseDragged(event);
 431:     break;
 432:       case MouseEvent.MOUSE_RELEASED:
 433:     fireMenuDragMouseReleased(event);
 434:     break;
 435:       }
 436:   }
 437: 
 438:   /**
 439:    * This method fires MenuKeyEvent to registered listeners.
 440:    * Different types of MenuKeyEvents are fired depending
 441:    * on the observed key event.
 442:    *
 443:    * @param event DOCUMENT ME!
 444:    */
 445:   public void processMenuKeyEvent(MenuKeyEvent event)
 446:   {
 447:     switch (event.getID())
 448:     {
 449:       case KeyEvent.KEY_PRESSED:
 450:         fireMenuKeyPressed(event);
 451:         break;
 452:       case KeyEvent.KEY_RELEASED:
 453:         fireMenuKeyReleased(event);
 454:         break;
 455:       case KeyEvent.KEY_TYPED:
 456:         fireMenuKeyTyped(event);
 457:         break;
 458:       default:
 459:         break;
 460:     }
 461:   }
 462: 
 463:   /**
 464:    * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
 465:    *
 466:    * @param event The event signifying that mouse entered menuItem while it was dragged
 467:    */
 468:   protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
 469:   {
 470:     EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
 471: 
 472:     for (int i = 0; i < ll.length; i++)
 473:       ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
 474:   }
 475: 
 476:   /**
 477:    * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
 478:    *
 479:    * @param event The event signifying that mouse has exited menu item, while it was dragged
 480:    */
 481:   protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
 482:   {
 483:     EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
 484: 
 485:     for (int i = 0; i < ll.length; i++)
 486:       ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
 487:   }
 488: 
 489:   /**
 490:    * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
 491:    *
 492:    * @param event The event signifying that mouse is being dragged over the menuItem
 493:    */
 494:   protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
 495:   {
 496:     EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
 497: 
 498:     for (int i = 0; i < ll.length; i++)
 499:       ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
 500:   }
 501: 
 502:   /**
 503:    * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
 504:    *
 505:    * @param event The event signifying that mouse was released while it was dragged over the menuItem
 506:    */
 507:   protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
 508:   {
 509:     EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
 510: 
 511:     for (int i = 0; i < ll.length; i++)
 512:       ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
 513:   }
 514: 
 515:   /**
 516:    * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
 517:    *
 518:    * @param event The event signifying that key associated with this menu was pressed
 519:    */
 520:   protected void fireMenuKeyPressed(MenuKeyEvent event)
 521:   {
 522:     EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
 523: 
 524:     for (int i = 0; i < ll.length; i++)
 525:       ((MenuKeyListener) ll[i]).menuKeyPressed(event);
 526:   }
 527: 
 528:   /**
 529:    * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
 530:    *
 531:    * @param event The event signifying that key associated with this menu was released
 532:    */
 533:   protected void fireMenuKeyReleased(MenuKeyEvent event)
 534:   {
 535:     EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
 536: 
 537:     for (int i = 0; i < ll.length; i++)
 538:       ((MenuKeyListener) ll[i]).menuKeyTyped(event);
 539:   }
 540: 
 541:   /**
 542:    * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
 543:    *
 544:    * @param event The event signifying that key associated with this menu was typed.
 545:    *        The key is typed when it was pressed and then released
 546:    */
 547:   protected void fireMenuKeyTyped(MenuKeyEvent event)
 548:   {
 549:     EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
 550: 
 551:     for (int i = 0; i < ll.length; i++)
 552:       ((MenuKeyListener) ll[i]).menuKeyTyped(event);
 553:   }
 554: 
 555:   /**
 556:    * Method of the MenuElement interface.
 557:    * This method is invoked by MenuSelectionManager when selection of
 558:    * this menu item has changed. If this menu item was selected then
 559:    * arm it's model, and disarm the model otherwise. The menu item
 560:    * is considered to be selected, and thus highlighted when its model
 561:    * is armed.
 562:    *
 563:    * @param changed indicates selection status of this menu item. If changed is
 564:    * true then menu item is selected and deselected otherwise.
 565:    */
 566:   public void menuSelectionChanged(boolean changed)
 567:   {
 568:     Component parent = this.getParent();
 569:     if (changed)
 570:       {
 571:     model.setArmed(true);
 572: 
 573:     if (parent != null && parent instanceof JPopupMenu)
 574:       ((JPopupMenu) parent).setSelected(this);
 575:       }
 576:     else
 577:       {
 578:     model.setArmed(false);
 579: 
 580:     if (parent != null && parent instanceof JPopupMenu)
 581:       ((JPopupMenu) parent).getSelectionModel().clearSelection();
 582:       }
 583:   }
 584: 
 585:   /**
 586:    * Method of the MenuElement interface.
 587:    *
 588:    * @return $MenuElement[]$ Returns array of sub-components for this menu
 589:    *         item. By default menuItem doesn't have any subcomponents and so
 590:    *         empty array is returned instead.
 591:    */
 592:   public MenuElement[] getSubElements()
 593:   {
 594:     return new MenuElement[0];
 595:   }
 596: 
 597:   /**
 598:    * Returns reference to the component that will paint this menu item.
 599:    *
 600:    * @return $Component$ Component that will paint this menu item.
 601:    *         Simply returns reference to this menu item.
 602:    */
 603:   public Component getComponent()
 604:   {
 605:     return this;
 606:   }
 607: 
 608:   /**
 609:    * Adds a MenuDragMouseListener to this menu item. When mouse
 610:    * is dragged over the menu item the MenuDragMouseEvents will be
 611:    * fired, and these listeners will be called.
 612:    *
 613:    * @param listener The new listener to add
 614:    */
 615:   public void addMenuDragMouseListener(MenuDragMouseListener listener)
 616:   {
 617:     listenerList.add(MenuDragMouseListener.class, listener);
 618:   }
 619: 
 620:   /**
 621:    * Removes a MenuDragMouseListener from the menuItem's listener list.
 622:    *
 623:    * @param listener The listener to remove
 624:    */
 625:   public void removeMenuDragMouseListener(MenuDragMouseListener listener)
 626:   {
 627:     listenerList.remove(MenuDragMouseListener.class, listener);
 628:   }
 629: 
 630:   /**
 631:    * Returns all added MenuDragMouseListener objects.
 632:    *
 633:    * @return an array of listeners
 634:    *
 635:    * @since 1.4
 636:    */
 637:   public MenuDragMouseListener[] getMenuDragMouseListeners()
 638:   {
 639:     return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
 640:   }
 641: 
 642:   /**
 643:    * Adds an MenuKeyListener to this menu item.  This listener will be
 644:    * invoked when MenuKeyEvents will be fired by this menu item.
 645:    *
 646:    * @param listener The new listener to add
 647:    */
 648:   public void addMenuKeyListener(MenuKeyListener listener)
 649:   {
 650:     listenerList.add(MenuKeyListener.class, listener);
 651:   }
 652: 
 653:   /**
 654:    * Removes an MenuKeyListener from the menuItem's listener list.
 655:    *
 656:    * @param listener The listener to remove
 657:    */
 658:   public void removeMenuKeyListener(MenuKeyListener listener)
 659:   {
 660:     listenerList.remove(MenuKeyListener.class, listener);
 661:   }
 662: 
 663:   /**
 664:    * Returns all added MenuKeyListener objects.
 665:    *
 666:    * @return an array of listeners
 667:    *
 668:    * @since 1.4
 669:    */
 670:   public MenuKeyListener[] getMenuKeyListeners()
 671:   {
 672:     return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
 673:   }
 674: 
 675:   /**
 676:    * Returns a string describing the attributes for the <code>JToolTip</code>
 677:    * component, for use in debugging.  The return value is guaranteed to be 
 678:    * non-<code>null</code>, but the format of the string may vary between
 679:    * implementations.
 680:    *
 681:    * @return A string describing the attributes of the <code>JMenuItem</code>.
 682:    */
 683:   protected String paramString()
 684:   {
 685:     // calling super seems to be sufficient here...
 686:     return super.paramString();
 687:   }
 688: 
 689:   /**
 690:    * Returns the object that provides accessibility features for this
 691:    * <code>JMenuItem</code> component.
 692:    *
 693:    * @return The accessible context (an instance of 
 694:    *     {@link AccessibleJMenuItem}).
 695:    */
 696:   public AccessibleContext getAccessibleContext()
 697:   {
 698:     if (accessibleContext == null)
 699:       accessibleContext = new AccessibleJMenuItem();
 700: 
 701:     return accessibleContext;
 702:   }
 703: 
 704:   /**
 705:    * Provides the accessibility features for the <code>JMenuItem</code> 
 706:    * component.
 707:    * 
 708:    * @see JMenuItem#getAccessibleContext()
 709:    */
 710:   protected class AccessibleJMenuItem extends AccessibleAbstractButton
 711:     implements ChangeListener
 712:   {
 713:     private static final long serialVersionUID = 6748924232082076534L;
 714: 
 715:     /**
 716:      * Creates a new <code>AccessibleJMenuItem</code> instance.
 717:      */
 718:     AccessibleJMenuItem()
 719:     {
 720:       //super(component);
 721:     }
 722: 
 723:     public void stateChanged(ChangeEvent event)
 724:       throws NotImplementedException
 725:     {
 726:       // TODO: What should be done here, if anything?
 727:     }
 728: 
 729:     /**
 730:      * Returns the accessible role for the <code>JMenuItem</code> component.
 731:      *
 732:      * @return {@link AccessibleRole#MENU_ITEM}.
 733:      */
 734:     public AccessibleRole getAccessibleRole()
 735:     {
 736:       return AccessibleRole.MENU_ITEM;
 737:     }
 738:   }
 739: }