2362N/A * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * An implementation of a menu -- a popup window containing 0N/A * <code>JMenuItem</code>s that 0N/A * is displayed when the user selects an item on the <code>JMenuBar</code>. 0N/A * In addition to <code>JMenuItem</code>s, a <code>JMenu</code> can 0N/A * also contain <code>JSeparator</code>s. 0N/A * In essence, a menu is a button with an associated <code>JPopupMenu</code>. 0N/A * When the "button" is pressed, the <code>JPopupMenu</code> appears. If the 0N/A * "button" is on the <code>JMenuBar</code>, the menu is a top-level window. 0N/A * If the "button" is another menu item, then the <code>JPopupMenu</code> is 0N/A * "pull-right" menu. 0N/A * Menus can be configured, and to some degree controlled, by 0N/A * <code>Action</code> with a menu has many benefits beyond directly 0N/A * Swing Components Supporting <code>Action</code></a> for more 0N/A * details, and you can find more information in <a 0N/A * to Use Actions</a>, a section in <em>The Java Tutorial</em>. 0N/A * For information and examples of using menus see 0N/A * a section in <em>The Java Tutorial.</em> 0N/A * <strong>Warning:</strong> Swing is not thread safe. For more 0N/A * information see <a 0N/A * <strong>Warning:</strong> 0N/A * Serialized objects of this class will not be compatible with 0N/A * future Swing releases. The current serialization support is 0N/A * appropriate for short term storage or RMI between applications running 0N/A * the same version of Swing. As of 1.4, support for long term storage 0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup> 0N/A * has been added to the <code>java.beans</code> package. 0N/A * attribute: isContainer true 0N/A * description: A popup window containing menu items displayed in a menu bar. 0N/A * @author Georges Saab 0N/A * @author David Karlton 0N/A * @author Arnaud Weber 0N/A * @see #getUIClassID 0N/A * The popup menu portion of the menu. 0N/A * The button's model listeners. Default is <code>null</code>. 0N/A * Only one <code>MenuEvent</code> is needed for each menu since the 0N/A * event's only state is the source property. The source of events 0N/A * generated is always "this". Default is <code>null</code>. 0N/A /* Registry of listeners created for <code>Action-JMenuItem</code> 0N/A * linkage. This is needed so that references can 0N/A * be cleaned up at remove time to allow garbage collection 0N/A * Default is <code>null</code>. 0N/A * Used by the look and feel (L&F) code to handle 0N/A * implementation specific menu behaviors. 0N/A * Location of the popup component. Location is <code>null</code> 0N/A * if it was not customized by <code>setMenuLocation</code> 0N/A /* Diagnostic aids -- should be false for production builds. */ 0N/A private static final boolean TRACE =
false;
// trace creates and disposes 0N/A private static final boolean DEBUG =
false;
// show bad params, misc. 0N/A * Constructs a new <code>JMenu</code> with no text. 0N/A * Constructs a new <code>JMenu</code> with the supplied string 0N/A * @param s the text for the menu label 0N/A * Constructs a menu whose properties are taken from the 0N/A * <code>Action</code> supplied. 0N/A * @param a an <code>Action</code> 0N/A * Constructs a new <code>JMenu</code> with the supplied string as 0N/A * its text and specified as a tear-off menu or not. 0N/A * @param s the text for the menu label 0N/A * @param b can the menu be torn off (not yet implemented) 0N/A * Overriden to do nothing. We want JMenu to be focusable, but 0N/A * <code>JMenuItem</code> doesn't want to be, thus we override this 0N/A * do nothing. We don't invoke <code>setFocusable(true)</code> after 0N/A * super's constructor has completed as this has the side effect that 0N/A * <code>JMenu</code> will be considered traversable via the 0N/A * keyboard, which we don't want. Making a Component traversable by 0N/A * the keyboard after invoking <code>setFocusable(true)</code> is OK, 0N/A * as <code>setFocusable</code> is new API 0N/A * and is speced as such, but internally we don't want to use it like 0N/A * this else we change the keyboard traversability. 0N/A * Resets the UI property with a value from the current look and feel. 0N/A * @see JComponent#updateUI 0N/A * Returns the name of the L&F class that renders this component. 0N/A * @return the string "MenuUI" 0N/A * @see JComponent#getUIClassID 0N/A * @see UIDefaults#getUI 0N/A // public void repaint(long tm, int x, int y, int width, int height) { 0N/A // Thread.currentThread().dumpStack(); 0N/A // super.repaint(tm,x,y,width,height); 0N/A * Sets the data model for the "menu button" -- the label 0N/A * that the user clicks to open or close the menu. 0N/A * @param newModel the <code>ButtonModel</code> 0N/A * description: The menu's model 0N/A * Returns true if the menu is currently selected (highlighted). 0N/A * @return true if the menu is selected, else false 0N/A * Sets the selection status of the menu. 0N/A * @param b true to select (highlight) the menu; false to de-select 0N/A * description: When the menu is selected, its popup child is shown. 0N/A // Removed code which fired an AccessibleState.SELECTED 0N/A // PropertyChangeEvent since this resulted in two 0N/A // identical events being fired since 0N/A // AbstractButton.fireItemStateChanged also fires the 0N/A // same event. This caused screen readers to speak the 0N/A // name of the item twice. 0N/A * Returns true if the menu's popup window is visible. 0N/A * @return true if the menu is visible, else false 0N/A * Sets the visibility of the menu's popup. If the menu is 0N/A * not enabled, this method will have no effect. 0N/A * @param b a boolean value -- true to make the menu visible, 0N/A * description: The popup menu's visibility 0N/A // Thread.dumpStack(); 0N/A // Set location of popupMenu (pulldown or pullright) 0N/A * Computes the origin for the <code>JMenu</code>'s popup menu. 0N/A * This method uses Look and Feel properties named 0N/A * <code>Menu.menuPopupOffsetX</code>, 0N/A * <code>Menu.menuPopupOffsetY</code>, 0N/A * <code>Menu.submenuPopupOffsetX</code>, and 0N/A * <code>Menu.submenuPopupOffsetY</code> 0N/A * to adjust the exact location of popup. 0N/A * @return a <code>Point</code> in the coordinate space of the 0N/A * menu which should be used as the origin 0N/A * of the <code>JMenu</code>'s popup menu 0N/A // Figure out the sizes needed to caclulate the menu position 0N/A // For the first time the menu is popped up, 0N/A // the size has not yet been initiated 0N/A // take screen insets (e.g. taskbar) into account 0N/A // We are a submenu (pull-right) 0N/A // First determine x: 0N/A // popup doesn't fit - place it wherever there's more room 0N/A // First determine x: 0N/A // popup doesn't fit - place it wherever there's more room 0N/A // popup doesn't fit - place it wherever there's more room 0N/A // We are a toplevel menu (pull-down) 0N/A // First determine the x: 0N/A // popup doesn't fit - place it wherever there's more room 0N/A // First determine the x: 0N/A // popup doesn't fit - place it wherever there's more room 0N/A // popup doesn't fit - place it wherever there's more room 0N/A * Returns the suggested delay, in milliseconds, before submenus 0N/A * are popped up or down. 0N/A * Each look and feel (L&F) may determine its own policy for 0N/A * observing the <code>delay</code> property. 0N/A * In most cases, the delay is not observed for top level menus 0N/A * or while dragging. The default for <code>delay</code> is 0. 0N/A * This method is a property of the look and feel code and is used 0N/A * to manage the idiosyncracies of the various UI implementations. 0N/A * @return the <code>delay</code> property 0N/A * Sets the suggested delay before the menu's <code>PopupMenu</code> 0N/A * is popped up or down. Each look and feel (L&F) may determine 0N/A * it's own policy for observing the delay property. In most cases, 0N/A * the delay is not observed for top level menus or while dragging. 0N/A * This method is a property of the look and feel code and is used 0N/A * to manage the idiosyncracies of the various UI implementations. 0N/A * @param d the number of milliseconds to delay 0N/A * @exception IllegalArgumentException if <code>d</code> 0N/A * description: The delay between menu selection and making the popup menu visible 0N/A * The window-closing listener for the popup. 0N/A * Return the customized location of the popup component. 0N/A * Sets the location of the popup component. 0N/A * @param x the x coordinate of the popup's new position 0N/A * @param y the y coordinate of the popup's new position 0N/A * Appends a menu item to the end of this menu. 0N/A * Returns the menu item added. 0N/A * @param menuItem the <code>JMenuitem</code> to be added 0N/A * @return the <code>JMenuItem</code> added 0N/A * Appends a component to the end of this menu. 0N/A * Returns the component added. 0N/A * @param c the <code>Component</code> to add 0N/A * @return the <code>Component</code> added 0N/A * Adds the specified component to this container at the given 0N/A * position. If <code>index</code> equals -1, the component will 0N/A * be appended to the end. 0N/A * @param c the <code>Component</code> to add 0N/A * @param index the position at which to insert the component 0N/A * @return the <code>Component</code> added 0N/A * @see java.awt.Container#add(Component, int) 0N/A * Creates a new menu item with the specified text and appends 0N/A * it to the end of this menu. 0N/A * @param s the string for the menu item to be added 0N/A * Creates a new menu item attached to the specified 0N/A * <code>Action</code> object and appends it to the end of this menu. 0N/A * @param a the <code>Action</code> for the menu item to be added 0N/A * Factory method which creates the <code>JMenuItem</code> for 0N/A * <code>Action</code>s added to the <code>JMenu</code>. 0N/A * @param a the <code>Action</code> for the menu item to be added 0N/A * @return the new menu item 0N/A * Returns a properly configured <code>PropertyChangeListener</code> 0N/A * which updates the control as changes to the <code>Action</code> occur. 0N/A * Appends a new separator to the end of the menu. 0N/A * Inserts a new menu item with the specified text at a 0N/A * @param s the text for the menu item to add 0N/A * @param pos an integer specifying the position at which to add the 0N/A * @exception IllegalArgumentException when the value of 0N/A * <code>pos</code> < 0 0N/A * Inserts the specified <code>JMenuitem</code> at a given position. 0N/A * @param mi the <code>JMenuitem</code> to add 0N/A * @param pos an integer specifying the position at which to add the 0N/A * new <code>JMenuitem</code> 0N/A * @return the new menu item 0N/A * @exception IllegalArgumentException if the value of 0N/A * <code>pos</code> < 0 0N/A * Inserts a new menu item attached to the specified <code>Action</code> 0N/A * object at a given position. 0N/A * @param a the <code>Action</code> object for the menu item to add 0N/A * @param pos an integer specifying the position at which to add the 0N/A * @exception IllegalArgumentException if the value of 0N/A * <code>pos</code> < 0 0N/A * Inserts a separator at the specified position. 0N/A * @param index an integer specifying the position at which to 0N/A * insert the menu separator 0N/A * @exception IllegalArgumentException if the value of 0N/A * <code>index</code> < 0 0N/A * Returns the <code>JMenuItem</code> at the specified position. 0N/A * If the component at <code>pos</code> is not a menu item, 0N/A * <code>null</code> is returned. 0N/A * This method is included for AWT compatibility. 0N/A * @param pos an integer specifying the position 0N/A * @exception IllegalArgumentException if the value of 0N/A * <code>pos</code> < 0 0N/A * @return the menu item at the specified position; or <code>null</code> 0N/A * if the item as the specified position is not a menu item 0N/A * Returns the number of items on the menu, including separators. 0N/A * This method is included for AWT compatibility. 0N/A * @return an integer equal to the number of items on the menu 0N/A * @see #getMenuComponentCount 0N/A * Returns true if the menu can be torn off. This method is not 0N/A * @return true if the menu can be torn off, else false 0N/A * @exception Error if invoked -- this method is not yet implemented 0N/A throw new Error(
"boolean isTearOff() {} not yet implemented");
0N/A * Removes the specified menu item from this menu. If there is no 0N/A * popup menu, this method will have no effect. 0N/A * @param item the <code>JMenuItem</code> to be removed from the menu 0N/A * Removes the menu item at the specified index from this menu. 0N/A * @param pos the position of the item to be removed 0N/A * @exception IllegalArgumentException if the value of 0N/A * <code>pos</code> < 0, or if <code>pos</code> 0N/A * is greater than the number of menu items 0N/A * Removes the component <code>c</code> from this menu. 0N/A * @param c the component to be removed 0N/A * Removes all menu items from this menu. 0N/A * Returns the number of components on the menu. 0N/A * @return an integer containing the number of components on the menu 0N/A * Returns the component at position <code>n</code>. 0N/A * @param n the position of the component to be returned 0N/A * @return the component requested, or <code>null</code> 0N/A * if there is no popup menu 0N/A * Returns an array of <code>Component</code>s of the menu's 0N/A * subcomponents. Note that this returns all <code>Component</code>s 0N/A * in the popup menu, including separators. 0N/A * @return an array of <code>Component</code>s or an empty array 0N/A * if there is no popup menu 0N/A * Returns true if the menu is a 'top-level menu', that is, if it is 0N/A * the direct child of a menubar. 0N/A * @return true if the menu is activated from the menu bar; 0N/A * false if the menu is activated from a menu item 0N/A * Returns true if the specified component exists in the 0N/A * submenu hierarchy. 0N/A * @param c the <code>Component</code> to be tested 0N/A * @return true if the <code>Component</code> exists, false otherwise 0N/A // Are we in the MenuItem part of the menu 0N/A // Are we in the PopupMenu? 0N/A // Are we in a Component on the PopupMenu 0N/A // Are we in the current component? 0N/A // Hmmm, what about Non-menu containers? 0N/A // Recursive call for the Menu case 0N/A * Returns a point in the coordinate space of this menu's popupmenu 0N/A * which corresponds to the point <code>p</code> in the menu's 0N/A * @param p the point to be translated 0N/A * @return the point in the coordinate space of this menu's popupmenu 0N/A * Returns a point in the coordinate space of this menu's popupmenu 0N/A * which corresponds to the point (x,y) in the menu's coordinate space. 0N/A * @param x the x coordinate of the point to be translated 0N/A * @param y the y coordinate of the point to be translated 0N/A * @return the point in the coordinate space of this menu's popupmenu 0N/A * Returns the popupmenu associated with this menu. If there is 0N/A * no popupmenu, it will create one. 0N/A * Adds a listener for menu events. 0N/A * @param l the listener to be added 0N/A * Removes a listener for menu events. 0N/A * @param l the listener to be removed 0N/A * Returns an array of all the <code>MenuListener</code>s added 0N/A * to this JMenu with addMenuListener(). 0N/A * @return all of the <code>MenuListener</code>s added or an empty 0N/A * array if no listeners have been added 0N/A * Notifies all listeners that have registered interest for 0N/A * notification on this event type. The event instance 0N/A * is created lazily. 0N/A * @exception Error if there is a <code>null</code> listener 0N/A * @see EventListenerList 0N/A // Guaranteed to return a non-null array 0N/A // Process the listeners last to first, notifying 0N/A // those that are interested in this event 0N/A // Lazily create the event: 0N/A * Notifies all listeners that have registered interest for 0N/A * notification on this event type. The event instance 0N/A * is created lazily. 0N/A * @exception Error if there is a <code>null</code> listener 0N/A * @see EventListenerList 0N/A // Guaranteed to return a non-null array 0N/A // Process the listeners last to first, notifying 0N/A // those that are interested in this event 0N/A // Lazily create the event: 0N/A * Notifies all listeners that have registered interest for 0N/A * notification on this event type. The event instance 0N/A * is created lazily. 0N/A * @exception Error if there is a <code>null</code> listener 0N/A * @see EventListenerList 0N/A // Guaranteed to return a non-null array 0N/A // Process the listeners last to first, notifying 0N/A // those that are interested in this event 0N/A // Lazily create the event: 0N/A // Overriden to do nothing, JMenu doesn't support an accelerator 0N/A * Creates a window-closing listener for the popup. 0N/A * @param p the <code>JPopupMenu</code> 0N/A * @return the new window-closing listener 0N/A * A listener class that watches for a popup window closing. 0N/A * When the popup is closing, the listener deselects the menu. 0N/A * <strong>Warning:</strong> 0N/A * Serialized objects of this class will not be compatible with 0N/A * future Swing releases. The current serialization support is 0N/A * appropriate for short term storage or RMI between applications running 0N/A * the same version of Swing. As of 1.4, support for long term storage 0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup> 0N/A * has been added to the <code>java.beans</code> package. 0N/A * Create the window listener for the specified popup. 0N/A * Deselect the menu when the popup is closed from outside. 0N/A * Messaged when the menubar selection changes to activate or 0N/A * deactivate this menu. 0N/A * Overrides <code>JMenuItem.menuSelectionChanged</code>. 0N/A * @param isIncluded true if this menu is active, false if 0N/A * Returns an array of <code>MenuElement</code>s containing the submenu 0N/A * for this menu component. If popup menu is <code>null</code> returns 0N/A * an empty array. This method is required to conform to the 0N/A * <code>MenuElement</code> interface. Note that since 0N/A * <code>JSeparator</code>s do not conform to the <code>MenuElement</code> 0N/A * interface, this array will only contain <code>JMenuItem</code>s. 0N/A * @return an array of <code>MenuElement</code> objects 0N/A // implements javax.swing.MenuElement 0N/A * Returns the <code>java.awt.Component</code> used to 0N/A * paint this <code>MenuElement</code>. 0N/A * The returned component is used to convert events and detect if 0N/A * an event is inside a menu component. 0N/A * Sets the <code>ComponentOrientation</code> property of this menu 0N/A * and all components contained within it. This includes all 0N/A * components returned by {@link #getMenuComponents getMenuComponents}. 0N/A * @param o the new component orientation of this menu and 0N/A * the components contained within it. 0N/A * @exception NullPointerException if <code>orientation</code> is null. 0N/A * @see java.awt.Component#setComponentOrientation 0N/A * @see java.awt.Component#getComponentOrientation 0N/A * <code>setAccelerator</code> is not defined for <code>JMenu</code>. 0N/A * Use <code>setMnemonic</code> instead. 0N/A * @param keyStroke the keystroke combination which will invoke 0N/A * the <code>JMenuItem</code>'s actionlisteners 0N/A * without navigating the menu hierarchy 0N/A * @exception Error if invoked -- this method is not defined for JMenu. 0N/A * Use <code>setMnemonic</code> instead 0N/A * description: The keystroke combination which will invoke the JMenuItem's 0N/A * actionlisteners without navigating the menu hierarchy 0N/A throw new Error(
"setAccelerator() is not defined for JMenu. Use setMnemonic() instead.");
0N/A * Processes key stroke events such as mnemonics and accelerators. 0N/A * @param evt the key event to be processed 0N/A * Programmatically performs a "click". This overrides the method 0N/A * <code>AbstractButton.doClick</code> in order to make the menu pop up. 0N/A * @param pressTime indicates the number of milliseconds the 0N/A * button was pressed for 0N/A * Build an array of menu elements - from <code>PopupMenu</code> to 0N/A * the root <code>JMenuBar</code>. 0N/A * @param leaf the leaf node from which to start building up the array 0N/A * @return the array of menu items 0N/A * See <code>readObject</code> and <code>writeObject</code> in 0N/A * <code>JComponent</code> for more 0N/A * information about serialization in Swing. 0N/A * Returns a string representation of this <code>JMenu</code>. This 0N/A * method is intended to be used only for debugging purposes, and the 0N/A * content and format of the returned string may vary between 0N/A * implementations. The returned string may be empty but may not 0N/A * be <code>null</code>. 0N/A * @return a string representation of this JMenu. 0N/A// Accessibility support 0N/A * Gets the AccessibleContext associated with this JMenu. 0N/A * For JMenus, the AccessibleContext takes the form of an 0N/A * A new AccessibleJMenu instance is created if necessary. 0N/A * @return an AccessibleJMenu that serves as the 0N/A * AccessibleContext of this JMenu 0N/A * This class implements accessibility support for the 0N/A * <code>JMenu</code> class. It provides an implementation of the 0N/A * Java Accessibility API appropriate to menu user-interface elements. 0N/A * <strong>Warning:</strong> 0N/A * Serialized objects of this class will not be compatible with 0N/A * future Swing releases. The current serialization support is 0N/A * appropriate for short term storage or RMI between applications running 0N/A * the same version of Swing. As of 1.4, support for long term storage 0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup> 0N/A * has been added to the <code>java.beans</code> package. 0N/A * Returns the number of accessible children in the object. If all 0N/A * of the children of this object implement Accessible, than this 0N/A * method should return the number of children of this object. 0N/A * @return the number of accessible children in the object. 0N/A * Returns the nth Accessible child of the object. 0N/A * @param i zero-based index of child 0N/A * @return the nth Accessible child of the object 0N/A // FIXME: [[[WDW - probably should set this when 0N/A // the component is added to the menu. I tried 0N/A // to do this in most cases, but the separators 0N/A // added by addSeparator are hard to get to.]]] 0N/A * Get the role of this object. 0N/A * @return an instance of AccessibleRole describing the role of the 0N/A * @see AccessibleRole 0N/A * Get the AccessibleSelection associated with this object. In the 0N/A * implementation of the Java Accessibility API for this class, 0N/A * return this object, which is responsible for implementing the 0N/A * AccessibleSelection interface on behalf of itself. 0N/A * @return this object 0N/A * Returns 1 if a sub-menu is currently selected in this menu. 0N/A * @return 1 if a menu is currently selected, else 0 0N/A if (
me[i] ==
JMenu.
this) {
// this menu is selected 0N/A * Returns the currently selected sub-menu if one is selected, 0N/A * otherwise null (there can only be one selection, and it can 0N/A * only be a sub-menu, as otherwise menu items don't remain 0N/A // if i is a sub-menu & popped, return it 0N/A if (
me[j] ==
JMenu.
this) {
// this menu is selected 0N/A // so find the next JMenuItem in the MenuElement 0N/A // array, and return it! 0N/A * Returns true if the current child of this object is selected 0N/A * (that is, if this child is a popped-up submenu). 0N/A * @param i the zero-based index of the child in this Accessible 0N/A * @see AccessibleContext#getAccessibleChild 0N/A // if i is a sub-menu and is pop-ed up, return true, else false 0N/A * Selects the <code>i</code>th menu in the menu. 0N/A * If that item is a submenu, 0N/A * it will pop up in response. If a different item is already 0N/A * popped up, this will force it to close. If this is a sub-menu 0N/A * that is already popped up (selected), this method has no 0N/A * @param i the index of the item to be selected 0N/A * @see #getAccessibleStateSet 0N/A * Removes the nth item from the selection. In general, menus 0N/A * can only have one item within them selected at a time 0N/A * (e.g. one sub-menu popped open). 0N/A * @param i the zero-based index of the selected item 0N/A * Clears the selection in the object, so that nothing in the 0N/A * object is selected. This will close any open sub-menu. 0N/A // if this menu is selected, reset selection to only go 0N/A // to this menu; else do nothing 0N/A if (
old[j] ==
JMenu.
this) {
// menu is in the selection! 0N/A * Normally causes every selected item in the object to be selected 0N/A * if the object supports multiple selections. This method 0N/A * makes no sense in a menu bar, and so does nothing. 0N/A }
// inner class AccessibleJMenu