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