| GNU Classpath (0.95) | |
| Frames | No Frames |
1: /* JMenu.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.Dimension; 43: import java.awt.GraphicsConfiguration; 44: import java.awt.GraphicsDevice; 45: import java.awt.GraphicsEnvironment; 46: import java.awt.Insets; 47: import java.awt.Point; 48: import java.awt.Rectangle; 49: import java.awt.Toolkit; 50: import java.awt.event.KeyEvent; 51: import java.awt.event.WindowAdapter; 52: import java.awt.event.WindowEvent; 53: import java.beans.PropertyChangeEvent; 54: import java.beans.PropertyChangeListener; 55: import java.io.Serializable; 56: import java.util.ArrayList; 57: import java.util.EventListener; 58: 59: import javax.accessibility.Accessible; 60: import javax.accessibility.AccessibleContext; 61: import javax.accessibility.AccessibleRole; 62: import javax.accessibility.AccessibleSelection; 63: import javax.swing.event.ChangeEvent; 64: import javax.swing.event.ChangeListener; 65: import javax.swing.event.MenuEvent; 66: import javax.swing.event.MenuListener; 67: import javax.swing.plaf.MenuItemUI; 68: 69: /** 70: * This class represents a menu that can be added to a menu bar or 71: * can be a submenu in some other menu. When JMenu is selected it 72: * displays JPopupMenu containing its menu items. 73: * 74: * <p> 75: * JMenu's fires MenuEvents when this menu's selection changes. If this menu 76: * is selected, then fireMenuSelectedEvent() is invoked. In case when menu is 77: * deselected or cancelled, then fireMenuDeselectedEvent() or 78: * fireMenuCancelledEvent() is invoked, respectivelly. 79: * </p> 80: */ 81: public class JMenu extends JMenuItem implements Accessible, MenuElement 82: { 83: /** 84: * Receives notifications when the JMenu's ButtonModel is changed and 85: * fires menuSelected or menuDeselected events when appropriate. 86: */ 87: private class MenuChangeListener 88: implements ChangeListener 89: { 90: /** 91: * Indicates the last selected state. 92: */ 93: private boolean selected; 94: 95: /** 96: * Receives notification when the JMenu's ButtonModel changes. 97: */ 98: public void stateChanged(ChangeEvent ev) 99: { 100: ButtonModel m = (ButtonModel) ev.getSource(); 101: boolean s = m.isSelected(); 102: if (s != selected) 103: { 104: if (s) 105: fireMenuSelected(); 106: else 107: fireMenuDeselected(); 108: selected = s; 109: } 110: } 111: } 112: 113: private static final long serialVersionUID = 4227225638931828014L; 114: 115: /** A Popup menu associated with this menu, which pops up when menu is selected */ 116: private JPopupMenu popupMenu = null; 117: 118: /** Whenever menu is selected or deselected the MenuEvent is fired to 119: menu's registered listeners. */ 120: private MenuEvent menuEvent = new MenuEvent(this); 121: 122: /*Amount of time, in milliseconds, that should pass before popupMenu 123: associated with this menu appears or disappers */ 124: private int delay; 125: 126: /* PopupListener */ 127: protected WinListener popupListener; 128: 129: /** 130: * Location at which popup menu associated with this menu will be 131: * displayed 132: */ 133: private Point menuLocation; 134: 135: /** 136: * The ChangeListener for the ButtonModel. 137: * 138: * @see MenuChangeListener 139: */ 140: private ChangeListener menuChangeListener; 141: 142: /** 143: * Creates a new JMenu object. 144: */ 145: public JMenu() 146: { 147: super(); 148: setOpaque(false); 149: } 150: 151: /** 152: * Creates a new <code>JMenu</code> with the specified label. 153: * 154: * @param text label for this menu 155: */ 156: public JMenu(String text) 157: { 158: super(text); 159: popupMenu = new JPopupMenu(); 160: popupMenu.setInvoker(this); 161: setOpaque(false); 162: } 163: 164: /** 165: * Creates a new <code>JMenu</code> object. 166: * 167: * @param action Action that is used to create menu item tha will be 168: * added to the menu. 169: */ 170: public JMenu(Action action) 171: { 172: super(action); 173: createActionChangeListener(this); 174: popupMenu = new JPopupMenu(); 175: popupMenu.setInvoker(this); 176: setOpaque(false); 177: } 178: 179: /** 180: * Creates a new <code>JMenu</code> with specified label and an option 181: * for this menu to be tear-off menu. 182: * 183: * @param text label for this menu 184: * @param tearoff true if this menu should be tear-off and false otherwise 185: */ 186: public JMenu(String text, boolean tearoff) 187: { 188: // FIXME: tearoff not implemented 189: this(text); 190: } 191: 192: /** 193: * Adds specified menu item to this menu 194: * 195: * @param item Menu item to add to this menu 196: * 197: * @return Menu item that was added 198: */ 199: public JMenuItem add(JMenuItem item) 200: { 201: return getPopupMenu().add(item); 202: } 203: 204: /** 205: * Adds specified component to this menu. 206: * 207: * @param component Component to add to this menu 208: * 209: * @return Component that was added 210: */ 211: public Component add(Component component) 212: { 213: getPopupMenu().insert(component, -1); 214: return component; 215: } 216: 217: /** 218: * Adds specified component to this menu at the given index 219: * 220: * @param component Component to add 221: * @param index Position of this menu item in the menu 222: * 223: * @return Component that was added 224: */ 225: public Component add(Component component, int index) 226: { 227: return getPopupMenu().add(component, index); 228: } 229: 230: /** 231: * Adds JMenuItem constructed with the specified label to this menu 232: * 233: * @param text label for the menu item that will be added 234: * 235: * @return Menu Item that was added to this menu 236: */ 237: public JMenuItem add(String text) 238: { 239: return add(new JMenuItem(text)); 240: } 241: 242: /** 243: * Adds JMenuItem constructed using properties from specified action. 244: * 245: * @param action action to construct the menu item with 246: * 247: * @return Menu Item that was added to this menu 248: */ 249: public JMenuItem add(Action action) 250: { 251: JMenuItem i = createActionComponent(action); 252: i.setAction(action); 253: add(i); 254: return i; 255: } 256: 257: /** 258: * Removes given menu item from this menu. Nothing happens if 259: * this menu doesn't contain specified menu item. 260: * 261: * @param item Menu Item which needs to be removed 262: */ 263: public void remove(JMenuItem item) 264: { 265: getPopupMenu().remove(item); 266: } 267: 268: /** 269: * Removes component at the specified index from this menu 270: * 271: * @param index Position of the component that needs to be removed in the menu 272: */ 273: public void remove(int index) 274: { 275: if (index < 0 || (index > 0 && getMenuComponentCount() == 0)) 276: throw new IllegalArgumentException(); 277: 278: if (getMenuComponentCount() > 0) 279: popupMenu.remove(index); 280: } 281: 282: /** 283: * Removes given component from this menu. 284: * 285: * @param component Component to remove 286: */ 287: public void remove(Component component) 288: { 289: int index = getPopupMenu().getComponentIndex(component); 290: if (index >= 0) 291: getPopupMenu().remove(index); 292: } 293: 294: /** 295: * Removes all menu items from the menu 296: */ 297: public void removeAll() 298: { 299: if (popupMenu != null) 300: popupMenu.removeAll(); 301: } 302: 303: /** 304: * Creates JMenuItem with the specified text and inserts it in the 305: * at the specified index 306: * 307: * @param text label for the new menu item 308: * @param index index at which to insert newly created menu item. 309: */ 310: public void insert(String text, int index) 311: { 312: this.insert(new JMenuItem(text), index); 313: } 314: 315: /** 316: * Creates JMenuItem with the specified text and inserts it in the 317: * at the specified index. IllegalArgumentException is thrown 318: * if index is less than 0 319: * 320: * @param item menu item to insert 321: * @param index index at which to insert menu item. 322: * @return Menu item that was added to the menu 323: */ 324: public JMenuItem insert(JMenuItem item, int index) 325: { 326: if (index < 0) 327: throw new IllegalArgumentException("index less than zero"); 328: 329: getPopupMenu().insert(item, index); 330: return item; 331: } 332: 333: /** 334: * Creates JMenuItem with the associated action and inserts it to the menu 335: * at the specified index. IllegalArgumentException is thrown 336: * if index is less than 0 337: * 338: * @param action Action for the new menu item 339: * @param index index at which to insert newly created menu item. 340: * @return Menu item that was added to the menu 341: */ 342: public JMenuItem insert(Action action, int index) 343: { 344: JMenuItem item = new JMenuItem(action); 345: this.insert(item, index); 346: 347: return item; 348: } 349: 350: /** 351: * This method sets this menuItem's UI to the UIManager's default for the 352: * current look and feel. 353: */ 354: public void updateUI() 355: { 356: setUI((MenuItemUI) UIManager.getUI(this)); 357: } 358: 359: /** 360: * This method returns a name to identify which look and feel class will be 361: * the UI delegate for the menu. 362: * 363: * @return The Look and Feel classID. "MenuUI" 364: */ 365: public String getUIClassID() 366: { 367: return "MenuUI"; 368: } 369: 370: /** 371: * Sets model for this menu. 372: * 373: * @param model model to set 374: */ 375: public void setModel(ButtonModel model) 376: { 377: ButtonModel oldModel = getModel(); 378: if (oldModel != null && menuChangeListener != null) 379: oldModel.removeChangeListener(menuChangeListener); 380: 381: super.setModel(model); 382: 383: if (model != null) 384: { 385: if (menuChangeListener == null) 386: menuChangeListener = new MenuChangeListener(); 387: model.addChangeListener(menuChangeListener); 388: } 389: } 390: 391: /** 392: * Returns true if the menu is selected and false otherwise 393: * 394: * @return true if the menu is selected and false otherwise 395: */ 396: public boolean isSelected() 397: { 398: return super.isSelected(); 399: } 400: 401: /** 402: * Changes this menu selected state if selected is true and false otherwise 403: * This method fires menuEvents to menu's registered listeners. 404: * 405: * @param selected true if the menu should be selected and false otherwise 406: */ 407: public void setSelected(boolean selected) 408: { 409: ButtonModel m = getModel(); 410: if (selected != m.isSelected()) 411: m.setSelected(selected); 412: } 413: 414: /** 415: * Checks if PopupMenu associated with this menu is visible 416: * 417: * @return true if the popup associated with this menu is currently visible 418: * on the screen and false otherwise. 419: */ 420: public boolean isPopupMenuVisible() 421: { 422: return getPopupMenu().isVisible(); 423: } 424: 425: /** 426: * Sets popup menu visibility 427: * 428: * @param popup true if popup should be visible and false otherwise 429: */ 430: public void setPopupMenuVisible(boolean popup) 431: { 432: if (popup != isPopupMenuVisible() && (isEnabled() || ! popup)) 433: { 434: if (popup && isShowing()) 435: { 436: // Set location as determined by getPopupLocation(). 437: Point loc = menuLocation == null ? getPopupMenuOrigin() 438: : menuLocation; 439: getPopupMenu().show(this, loc.x, loc.y); 440: } 441: else 442: getPopupMenu().setVisible(false); 443: } 444: } 445: 446: /** 447: * Returns origin point of the popup menu. This takes the screen bounds 448: * into account and places the popup where it fits best. 449: * 450: * @return the origin of the popup menu 451: */ 452: protected Point getPopupMenuOrigin() 453: { 454: // The menu's screen location and size. 455: Point screenLoc = getLocationOnScreen(); 456: Dimension size = getSize(); 457: 458: // Determine the popup's size. 459: JPopupMenu popup = getPopupMenu(); 460: Dimension popupSize = popup.getSize(); 461: if (popupSize.width == 0 || popupSize.height == 0) 462: popupSize = popup.getPreferredSize(); 463: 464: // Determine screen bounds. 465: Toolkit tk = Toolkit.getDefaultToolkit(); 466: Rectangle screenBounds = new Rectangle(tk.getScreenSize()); 467: GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 468: GraphicsDevice gd = ge.getDefaultScreenDevice(); 469: GraphicsConfiguration gc = gd.getDefaultConfiguration(); 470: Insets screenInsets = tk.getScreenInsets(gc); 471: screenBounds.x -= screenInsets.left; 472: screenBounds.width -= screenInsets.left + screenInsets.right; 473: screenBounds.y -= screenInsets.top; 474: screenBounds.height -= screenInsets.top + screenInsets.bottom; 475: screenLoc.x -= screenInsets.left; 476: screenLoc.y -= screenInsets.top; 477: 478: Point point = new Point(); 479: if (isTopLevelMenu()) 480: { 481: // If menu in the menu bar. 482: int xOffset = UIManager.getInt("Menu.menuPopupOffsetX"); 483: int yOffset = UIManager.getInt("Menu.menuPopupOffsetY"); 484: // Determine X location. 485: if (getComponentOrientation().isLeftToRight()) 486: { 487: // Prefer popup to the right. 488: point.x = xOffset; 489: // Check if it fits, otherwise place popup wherever it fits. 490: if (screenLoc.x + point.x + popupSize.width 491: > screenBounds.width + screenBounds.width 492: && screenBounds.width - size.width 493: < 2 * (screenLoc.x - screenBounds.x)) 494: // Popup to the right if there's not enough room. 495: point.x = size.width - xOffset - popupSize.width; 496: } 497: else 498: { 499: // Prefer popup to the left. 500: point.x = size.width - xOffset - popupSize.width; 501: if (screenLoc.x + point.x < screenBounds.x 502: && screenBounds.width - size.width 503: > 2 * (screenLoc.x - screenBounds.x)) 504: // Popup to the left if there's not enough room. 505: point.x = xOffset; 506: } 507: // Determine Y location. Prefer popping down. 508: point.y = size.height + yOffset; 509: if (screenLoc.y + point.y + popupSize.height >= screenBounds.height 510: && screenBounds.height - size.height 511: < 2 * (screenLoc.y - screenBounds.y)) 512: // Position above if there's not enough room below. 513: point.y = - yOffset - popupSize.height; 514: } 515: else 516: { 517: // If submenu. 518: int xOffset = UIManager.getInt("Menu.submenuPopupOffsetX"); 519: int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY"); 520: // Determine X location. 521: if (getComponentOrientation().isLeftToRight()) 522: { 523: // Prefer popup to the right. 524: point.x = size.width + xOffset; 525: if (screenLoc.x + point.x + popupSize.width 526: >= screenBounds.x + screenBounds.width 527: && screenBounds.width - size.width 528: < 2 * (screenLoc.x - screenBounds.x)) 529: // Position to the left if there's not enough room on the right. 530: point.x = - xOffset - popupSize.width; 531: } 532: else 533: { 534: // Prefer popup on the left side. 535: point.x = - xOffset - popupSize.width; 536: if (screenLoc.x + point.x < screenBounds.x 537: && screenBounds.width - size.width 538: > 2 * (screenLoc.x - screenBounds.x)) 539: // Popup to the right if there's not enough room. 540: point.x = size.width + xOffset; 541: } 542: // Determine Y location. Prefer popping down. 543: point.y = yOffset; 544: if (screenLoc.y + point.y + popupSize.height 545: >= screenBounds.y + screenBounds.height 546: && screenBounds.height - size.height 547: < 2 * (screenLoc.y - screenBounds.y)) 548: // Pop up if there's not enough room below. 549: point.y = size.height - yOffset - popupSize.height; 550: } 551: return point; 552: } 553: 554: /** 555: * Returns delay property. 556: * 557: * @return delay property, indicating number of milliseconds before 558: * popup menu associated with the menu appears or disappears after 559: * menu was selected or deselected respectively 560: */ 561: public int getDelay() 562: { 563: return delay; 564: } 565: 566: /** 567: * Sets delay property for this menu. If given time for the delay 568: * property is negative, then IllegalArgumentException is thrown 569: * 570: * @param delay number of milliseconds before 571: * popup menu associated with the menu appears or disappears after 572: * menu was selected or deselected respectively 573: */ 574: public void setDelay(int delay) 575: { 576: if (delay < 0) 577: throw new IllegalArgumentException("delay less than 0"); 578: this.delay = delay; 579: } 580: 581: /** 582: * Sets location at which popup menu should be displayed 583: * The location given is relative to this menu item 584: * 585: * @param x x-coordinate of the menu location 586: * @param y y-coordinate of the menu location 587: */ 588: public void setMenuLocation(int x, int y) 589: { 590: menuLocation = new Point(x, y); 591: if (popupMenu != null) 592: popupMenu.setLocation(x, y); 593: } 594: 595: /** 596: * Creates and returns JMenuItem associated with the given action 597: * 598: * @param action Action to use for creation of JMenuItem 599: * 600: * @return JMenuItem that was creted with given action 601: */ 602: protected JMenuItem createActionComponent(Action action) 603: { 604: return new JMenuItem(action); 605: } 606: 607: /** 608: * Creates ActionChangeListener to listen for PropertyChangeEvents occuring 609: * in the action that is associated with this menu 610: * 611: * @param item menu that contains action to listen to 612: * 613: * @return The PropertyChangeListener 614: */ 615: protected PropertyChangeListener createActionChangeListener(JMenuItem item) 616: { 617: return new ActionChangedListener(item); 618: } 619: 620: /** 621: * Adds separator to the end of the menu items in the menu. 622: */ 623: public void addSeparator() 624: { 625: getPopupMenu().addSeparator(); 626: } 627: 628: /** 629: * Inserts separator in the menu at the specified index. 630: * 631: * @param index Index at which separator should be inserted 632: */ 633: public void insertSeparator(int index) 634: { 635: if (index < 0) 636: throw new IllegalArgumentException("index less than 0"); 637: 638: getPopupMenu().insert(new JPopupMenu.Separator(), index); 639: } 640: 641: /** 642: * Returns menu item located at the specified index in the menu 643: * 644: * @param index Index at which to look for the menu item 645: * 646: * @return menu item located at the specified index in the menu 647: */ 648: public JMenuItem getItem(int index) 649: { 650: if (index < 0) 651: throw new IllegalArgumentException("index less than 0"); 652: 653: if (getItemCount() == 0) 654: return null; 655: 656: Component c = popupMenu.getComponentAtIndex(index); 657: 658: if (c instanceof JMenuItem) 659: return (JMenuItem) c; 660: else 661: return null; 662: } 663: 664: /** 665: * Returns number of items in the menu including separators. 666: * 667: * @return number of items in the menu 668: * 669: * @see #getMenuComponentCount() 670: */ 671: public int getItemCount() 672: { 673: return getMenuComponentCount(); 674: } 675: 676: /** 677: * Checks if this menu is a tear-off menu. 678: * 679: * @return true if this menu is a tear-off menu and false otherwise 680: */ 681: public boolean isTearOff() 682: { 683: // NOT YET IMPLEMENTED 684: throw new Error("The method isTearOff() has not yet been implemented."); 685: } 686: 687: /** 688: * Returns number of menu components in this menu 689: * 690: * @return number of menu components in this menu 691: */ 692: public int getMenuComponentCount() 693: { 694: return getPopupMenu().getComponentCount(); 695: } 696: 697: /** 698: * Returns menu component located at the givent index 699: * in the menu 700: * 701: * @param index index at which to get the menu component in the menu 702: * 703: * @return Menu Component located in the menu at the specified index 704: */ 705: public Component getMenuComponent(int index) 706: { 707: if (getPopupMenu() == null || getMenuComponentCount() == 0) 708: return null; 709: 710: return popupMenu.getComponentAtIndex(index); 711: } 712: 713: /** 714: * Return components belonging to this menu 715: * 716: * @return components belonging to this menu 717: */ 718: public Component[] getMenuComponents() 719: { 720: return getPopupMenu().getComponents(); 721: } 722: 723: /** 724: * Checks if this menu is a top level menu. The menu is top 725: * level menu if it is inside the menu bar. While if the menu 726: * inside some other menu, it is considered to be a pull-right menu. 727: * 728: * @return true if this menu is top level menu, and false otherwise 729: */ 730: public boolean isTopLevelMenu() 731: { 732: return getParent() instanceof JMenuBar; 733: } 734: 735: /** 736: * Checks if given component exists in this menu. The submenus of 737: * this menu are checked as well 738: * 739: * @param component Component to look for 740: * 741: * @return true if the given component exists in this menu, and false otherwise 742: */ 743: public boolean isMenuComponent(Component component) 744: { 745: return false; 746: } 747: 748: /** 749: * Returns popup menu associated with the menu. 750: * 751: * @return popup menu associated with the menu. 752: */ 753: public JPopupMenu getPopupMenu() 754: { 755: if (popupMenu == null) 756: { 757: popupMenu = new JPopupMenu(); 758: popupMenu.setInvoker(this); 759: } 760: return popupMenu; 761: } 762: 763: /** 764: * Adds MenuListener to the menu 765: * 766: * @param listener MenuListener to add 767: */ 768: public void addMenuListener(MenuListener listener) 769: { 770: listenerList.add(MenuListener.class, listener); 771: } 772: 773: /** 774: * Removes MenuListener from the menu 775: * 776: * @param listener MenuListener to remove 777: */ 778: public void removeMenuListener(MenuListener listener) 779: { 780: listenerList.remove(MenuListener.class, listener); 781: } 782: 783: /** 784: * Returns all registered <code>MenuListener</code> objects. 785: * 786: * @return an array of listeners 787: * 788: * @since 1.4 789: */ 790: public MenuListener[] getMenuListeners() 791: { 792: return (MenuListener[]) listenerList.getListeners(MenuListener.class); 793: } 794: 795: /** 796: * This method fires MenuEvents to all menu's MenuListeners. In this case 797: * menuSelected() method of MenuListeners is called to indicated that the menu 798: * was selected. 799: */ 800: protected void fireMenuSelected() 801: { 802: MenuListener[] listeners = getMenuListeners(); 803: 804: for (int index = 0; index < listeners.length; ++index) 805: listeners[index].menuSelected(menuEvent); 806: } 807: 808: /** 809: * This method fires MenuEvents to all menu's MenuListeners. In this case 810: * menuDeselected() method of MenuListeners is called to indicated that the menu 811: * was deselected. 812: */ 813: protected void fireMenuDeselected() 814: { 815: EventListener[] ll = listenerList.getListeners(MenuListener.class); 816: 817: for (int i = 0; i < ll.length; i++) 818: ((MenuListener) ll[i]).menuDeselected(menuEvent); 819: } 820: 821: /** 822: * This method fires MenuEvents to all menu's MenuListeners. In this case 823: * menuSelected() method of MenuListeners is called to indicated that the menu 824: * was cancelled. The menu is cancelled when it's popup menu is close without selection. 825: */ 826: protected void fireMenuCanceled() 827: { 828: EventListener[] ll = listenerList.getListeners(MenuListener.class); 829: 830: for (int i = 0; i < ll.length; i++) 831: ((MenuListener) ll[i]).menuCanceled(menuEvent); 832: } 833: 834: /** 835: * Creates WinListener that listens to the menu;s popup menu. 836: * 837: * @param popup JPopupMenu to listen to 838: * 839: * @return The WinListener 840: */ 841: protected WinListener createWinListener(JPopupMenu popup) 842: { 843: return new WinListener(popup); 844: } 845: 846: /** 847: * Method of the MenuElementInterface. It reacts to the selection 848: * changes in the menu. If this menu was selected, then it 849: * displayes popup menu associated with it and if this menu was 850: * deselected it hides the popup menu. 851: * 852: * @param changed true if the menu was selected and false otherwise 853: */ 854: public void menuSelectionChanged(boolean changed) 855: { 856: // if this menu selection is true, then activate this menu and 857: // display popup associated with this menu 858: setSelected(changed); 859: } 860: 861: /** 862: * Method of MenuElement interface. Returns sub components of 863: * this menu. 864: * 865: * @return array containing popupMenu that is associated with this menu 866: */ 867: public MenuElement[] getSubElements() 868: { 869: return new MenuElement[] { popupMenu }; 870: } 871: 872: /** 873: * @return Returns reference to itself 874: */ 875: public Component getComponent() 876: { 877: return this; 878: } 879: 880: /** 881: * This method is overriden with empty implementation, s.t the 882: * accelerator couldn't be set for the menu. The mnemonic should 883: * be used for the menu instead. 884: * 885: * @param keystroke accelerator for this menu 886: */ 887: public void setAccelerator(KeyStroke keystroke) 888: { 889: throw new Error("setAccelerator() is not defined for JMenu. Use setMnemonic() instead."); 890: } 891: 892: /** 893: * This method process KeyEvent occuring when the menu is visible 894: * 895: * @param event The KeyEvent 896: */ 897: protected void processKeyEvent(KeyEvent event) 898: { 899: MenuSelectionManager.defaultManager().processKeyEvent(event); 900: } 901: 902: /** 903: * Programatically performs click 904: * 905: * @param time Number of milliseconds for which this menu stays pressed 906: */ 907: public void doClick(int time) 908: { 909: getModel().setArmed(true); 910: getModel().setPressed(true); 911: try 912: { 913: java.lang.Thread.sleep(time); 914: } 915: catch (java.lang.InterruptedException e) 916: { 917: // probably harmless 918: } 919: 920: getModel().setPressed(false); 921: getModel().setArmed(false); 922: popupMenu.show(this, this.getWidth(), 0); 923: } 924: 925: /** 926: * A string that describes this JMenu. Normally only used 927: * for debugging. 928: * 929: * @