JPopupMenu.java revision 5077
869N/A * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 869N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 869N/A * This code is free software; you can redistribute it and/or modify it 869N/A * under the terms of the GNU General Public License version 2 only, as 869N/A * published by the Free Software Foundation. Oracle designates this 869N/A * particular file as subject to the "Classpath" exception as provided 869N/A * by Oracle in the LICENSE file that accompanied this code. 869N/A * This code is distributed in the hope that it will be useful, but WITHOUT 869N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 869N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 869N/A * version 2 for more details (a copy is included in the LICENSE file that 869N/A * accompanied this code). 869N/A * You should have received a copy of the GNU General Public License version 873N/A * 2 along with this work; if not, write to the Free Software Foundation, 869N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 869N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 869N/A * or visit www.oracle.com if you need additional information or have any 1958N/A * An implementation of a popup menu -- a small window that pops up 1963N/A * and displays a series of choices. A <code>JPopupMenu</code> is used for the 2340N/A * menu that appears when the user selects an item on the menu bar. 3103N/A * It is also used for "pull-right" menu that appears when the 3127N/A * selects a menu item that activates it. Finally, a <code>JPopupMenu</code> 3679N/A * can also be used anywhere else you want a menu to appear. For 5244N/A * example, when the user right-clicks in a specified area. 1954N/A * For information and examples of using popup menus, see 1954N/A * in <em>The Java Tutorial.</em> 4306N/A * <strong>Warning:</strong> Swing is not thread safe. For more 1954N/A * <strong>Warning:</strong> 1954N/A * Serialized objects of this class will not be compatible with 5221N/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 869N/A * of all JavaBeans<sup><font size="-2">TM</font></sup> 868N/A * has been added to the <code>java.beans</code> package. 4563N/A * attribute: isContainer false 5408N/A * description: A small window that pops up and displays a series of choices. 2270N/A * Key used in AppContext to determine if light way popups are the default. 868N/A /** Bug#4425878-Property javax.swing.adjustPopupLocationToFit introduced */ 65N/A "javax.swing.adjustPopupLocationToFit",
"")).
equals(
"false");
65N/A * Used to indicate if lightweight popups should be used. 2266N/A * Model for the selected subcontrol. 2624N/A /* Lock object used in place of class object for synchronization. 2266N/A /* diagnostic aids -- should be false for production builds. */ 2266N/A private static final boolean TRACE =
false;
// trace creates and disposes 2266N/A private static final boolean DEBUG =
false;
// show bad params, misc. 2266N/A * Sets the default value of the <code>lightWeightPopupEnabled</code> 2266N/A * @param aFlag <code>true</code> if popups can be lightweight, 2266N/A * otherwise <code>false</code> 2266N/A * @see #getDefaultLightWeightPopupEnabled 2266N/A * @see #setLightWeightPopupEnabled 2266N/A * Gets the <code>defaultLightWeightPopupEnabled</code> property, 2266N/A * which by default is <code>true</code>. 2266N/A * @return the value of the <code>defaultLightWeightPopupEnabled</code> 868N/A * @see #setDefaultLightWeightPopupEnabled 0N/A * Constructs a <code>JPopupMenu</code> without an "invoker". 2624N/A * Constructs a <code>JPopupMenu</code> with the specified title. 2624N/A * @param label the string that a UI may use to display as a title 2624N/A * Returns the look and feel (L&F) object that renders this component. 5268N/A * @return the <code>PopupMenuUI</code> object that renders this component 2624N/A * Sets the L&F object that renders this component. 5203N/A * @param ui the new <code>PopupMenuUI</code> L&F object 0N/A * @see UIDefaults#getUI 0N/A * attribute: visualUpdate true 0N/A * description: The UI object that implements the Component's LookAndFeel. 2624N/A * Resets the UI property to a value from the current look and feel. 2624N/A * Returns the name of the L&F class that renders this component. 2222N/A * @return the string "PopupMenuUI" 5161N/A * @see JComponent#getUIClassID 2624N/A * Processes key stroke events such as mnemonics and accelerators. 2624N/A * @param evt the key event to be processed 2624N/A * Returns the model object that handles single selections. 2624N/A * @return the <code>selectionModel</code> property 2624N/A * @see SingleSelectionModel 868N/A * Sets the model object to handle single selections. 2624N/A * @param model the new <code>SingleSelectionModel</code> 868N/A * @see SingleSelectionModel 2624N/A * description: The selection model for the popup menu 868N/A * Appends the specified menu item to the end of this menu. 868N/A * @param menuItem the <code>JMenuItem</code> to add 2624N/A * @return the <code>JMenuItem</code> added 2624N/A * Creates a new menu item with the specified text and appends 2624N/A * it to the end of this menu. 868N/A * @param s the string for the menu item to be added 869N/A * Appends a new menu item to the end of the menu which 869N/A * dispatches the specified <code>Action</code> object. 2624N/A * @param a the <code>Action</code> to add to the menu 2624N/A * @return the new menu item 2624N/A * Returns an point which has been adjusted to take into account of the 869N/A * desktop bounds, taskbar and multi-monitor configuration. 2624N/A * This adustment may be cancelled by invoking the application with 869N/A * -Djavax.swing.adjustPopupLocationToFit=false 869N/A // If we have GraphicsConfiguration use it to get screen bounds 2334N/A // If we don't have GraphicsConfiguration use primary screen 2624N/A // Calculate the screen size that popup should fit 2624N/A // Insets include the task bar. Take them into account. 2624N/A // Ensure that popup menu fits the screen 869N/A * Tries to find GraphicsConfiguration 868N/A * that contains the mouse cursor position. 869N/A // If not found and we have invoker, ask invoker about his gc 2624N/A * Returns whether popup is allowed to be shown above the task bar. 869N/A * Factory method which creates the <code>JMenuItem</code> for 868N/A * <code>Actions</code> added to the <code>JPopupMenu</code>. 0N/A * @param a the <code>Action</code> for the menu item to be added 0N/A * @return the new menu item 869N/A * Returns a properly configured <code>PropertyChangeListener</code> 868N/A * which updates the control as changes to the <code>Action</code> occur. 2624N/A * Removes the component at the specified index from this popup menu. 869N/A * @param pos the position of the item to be removed 869N/A * @exception IllegalArgumentException if the value of 869N/A * <code>pos</code> < 0, or if the value of 2624N/A * <code>pos</code> is greater than the 2624N/A * Sets the value of the <code>lightWeightPopupEnabled</code> property, 869N/A * which by default is <code>true</code>. 2390N/A * By default, when a look and feel displays a popup, 2390N/A * use a lightweight (all-Java) popup. 2390N/A * Lightweight popup windows are more efficient than heavyweight 2624N/A * but lightweight and heavyweight components do not mix well in a GUI. 3702N/A * If your application mixes lightweight and heavyweight components, 2390N/A * you should disable lightweight popups. 2390N/A * Some look and feels might always use heavyweight popups, 2390N/A * no matter what the value of this property. 869N/A * @param aFlag <code>false</code> to disable lightweight popups 869N/A * description: Determines whether lightweight popups are used when possible 2624N/A * @see #isLightWeightPopupEnabled 869N/A // NOTE: this use to set the flag on a shared JPopupMenu, which meant 0N/A // this effected ALL JPopupMenus. 2917N/A * Gets the <code>lightWeightPopupEnabled</code> property. 2942N/A * @return the value of the <code>lightWeightPopupEnabled</code> property 2942N/A * @see #setLightWeightPopupEnabled 2917N/A * Returns the popup menu's label 0N/A * @return a string containing the popup menu's label 2917N/A * Sets the popup menu's label. Different look and feels may choose 2917N/A * to display or not display this. 2917N/A * @param label a string specifying the label for the popup menu 0N/A * description: The label for the popup menu. 2334N/A * Appends a new separator at the end of the menu. 0N/A * Inserts a menu item for the specified <code>Action</code> object at 46N/A * a given position. 2624N/A * @param a the <code>Action</code> object to insert 2624N/A * @param index specifies the position at which to insert the 2624N/A * <code>Action</code>, where 0 is the first 0N/A * @exception IllegalArgumentException if <code>index</code> < 0 0N/A * Inserts the specified component into the menu at a given 869N/A * @param component the <code>Component</code> to insert 2624N/A * @param index specifies the position at which 2624N/A * to insert the component, where 0 is the first 0N/A * @exception IllegalArgumentException if <code>index</code> < 0 2621N/A // PENDING(ges): Why not use an array? 0N/A /* Remove the item at index, nitems-index times 2334N/A storing them in a temporary vector in the 869N/A order they appear on the menu. 988N/A /* Add the removed items back to the menu, they are 988N/A already in the correct order in the temp vector. 756N/A * Adds a <code>PopupMenu</code> listener. 2334N/A * @param l the <code>PopupMenuListener</code> to add 1102N/A * Removes a <code>PopupMenu</code> listener. 1102N/A * @param l the <code>PopupMenuListener</code> to remove 0N/A * Returns an array of all the <code>PopupMenuListener</code>s added 0N/A * to this JMenuItem with addPopupMenuListener(). 0N/A * @return all of the <code>PopupMenuListener</code>s added or an empty 0N/A * array if no listeners have been added 2048N/A * Adds a <code>MenuKeyListener</code> to the popup menu. 2048N/A * @param l the <code>MenuKeyListener</code> to be added 824N/A * Removes a <code>MenuKeyListener</code> from the popup menu. 868N/A * @param l the <code>MenuKeyListener</code> to be removed 2624N/A * Returns an array of all the <code>MenuKeyListener</code>s added 2624N/A * to this JPopupMenu with addMenuKeyListener(). 869N/A * @return all of the <code>MenuKeyListener</code>s added or an empty 869N/A * array if no listeners have been added 2624N/A * Notifies <code>PopupMenuListener</code>s that this popup menu will 868N/A * Notifies <code>PopupMenuListener</code>s that this popup menu will 2624N/A * Notifies <code>PopupMenuListeners</code> that this popup menu is 2624N/A * Always returns true since popups, by definition, should always 2624N/A * be on top of all other windows. 1280N/A * Lays out the container so that it uses the minimum space 2624N/A * needed to display its contents. 2624N/A * Sets the visibility of the popup menu. 3030N/A * @param b true to make the popup visible, or false to 2624N/A * description: Makes the popup visible 2624N/A // if closing, first close all Submenus 2624N/A // 4234793: This is a workaround because JPopupMenu.firePopupMenuCanceled is 2624N/A // a protected method and cannot be called from BasicPopupMenuUI directly 868N/A // The real solution could be to make 2624N/A // firePopupMenuCanceled public and call it directly. 1280N/A // This is a popup menu with MenuElement children, 1280N/A // set selection path before popping up! 1280N/A // 4694797: When popup menu is made invisible, selected path 2624N/A * Returns a <code>Popup</code> instance from the 1280N/A * <code>PopupMenuUI</code> that has had <code>show</code> invoked on 1280N/A * it. If the current <code>popup</code> is non-null, 1280N/A * this will invoke <code>dispose</code> of it, and then 1280N/A * <code>show</code> the new one. 1280N/A * This does NOT fire any events, it is up the caller to dispatch 1280N/A // adjust the location of the popup 0N/A * Returns true if the popup menu is visible (currently 868N/A * Sets the location of the upper left corner of the 868N/A * popup menu using x, y coordinates. 0N/A * @param x the x coordinate of the popup's new position 4015N/A * in the screen's coordinate space 2624N/A * @param y the y coordinate of the popup's new position 0N/A * in the screen's coordinate space 0N/A * description: The location of the popup menu. 0N/A * Returns true if the popup menu is a standalone popup menu 0N/A * rather than the submenu of a <code>JMenu</code>. 868N/A * @return true if this menu is a standalone popup menu, otherwise false 868N/A * Returns the component which is the 'invoker' of this 0N/A * @return the <code>Component</code> in which the popup menu is displayed 0N/A * Sets the invoker of this popup menu -- the component in which 0N/A * the popup menu menu is to be displayed. 2624N/A * @param invoker the <code>Component</code> in which the popup 869N/A * description: The invoking component for the popup menu 0N/A * Displays the popup menu at the position x,y in the coordinate 868N/A * space of the component invoker. 0N/A * @param invoker the component in whose space the popup menu is to appear 869N/A * @param x the x coordinate in invoker's coordinate space at which 0N/A * the popup menu is to be displayed 4015N/A * @param y the y coordinate in invoker's coordinate space at which 2624N/A * the popup menu is to be displayed 869N/A // Use the invoker's frame so that events 869N/A // are propagated properly 0N/A // To avoid integer overflow 0N/A * Returns the popup menu which is at the root of the menu system 0N/A * for this popup menu. 0N/A * @return the topmost grandparent <code>JPopupMenu</code> 4015N/A * Returns the component at the specified index. 4015N/A * @param i the index of the component, where 0 is the first 4015N/A * @return the <code>Component</code> at that index 4015N/A * @deprecated replaced by {@link java.awt.Container#getComponent(int)} 4015N/A * Returns the index of the specified component. 4015N/A * @param c the <code>Component</code> to find 4015N/A * @return the index of the component, where 0 is the first; 4015N/A * or -1 if the component is not found 4015N/A * Sets the size of the Popup window using a <code>Dimension</code> object. 5384N/A * This is equivalent to <code>setPreferredSize(d)</code>. 4015N/A * @param d the <code>Dimension</code> specifying the new size 4015N/A * description: The size of the popup menu 4015N/A * Sets the size of the Popup window to the specified width and 4015N/A * height. This is equivalent to 4015N/A * <code>setPreferredSize(new Dimension(width, height))</code>. 4015N/A * @param width the new width of the Popup in pixels 4015N/A * @param height the new height of the Popup in pixels 4015N/A * description: The size of the popup menu 4015N/A * Sets the currently selected component, This will result 4015N/A * in a change to the selection model. 4015N/A * @param sel the <code>Component</code> to select 4015N/A * description: The selected component on the popup menu 4015N/A * Checks whether the border should be painted. 4015N/A * @return true if the border is painted, false otherwise 4015N/A * Sets whether the border should be painted. 4015N/A * @param b if true, the border is painted. 4015N/A * description: Is the border of the popup menu painted 4015N/A * Paints the popup menu's border if the <code>borderPainted</code> 4015N/A * property is <code>true</code>. 4015N/A * @param g the <code>Graphics</code> object 4015N/A * @see JComponent#setBorder 4015N/A * Returns the margin, in pixels, between the popup menu's border and 4015N/A * @return an <code>Insets</code> object containing the margin values. 4015N/A * Examines the list of menu items to determine whether 4015N/A * <code>popup</code> is a popup menu. 4015N/A * @param popup a <code>JPopupMenu</code> 4015N/A * @return true if <code>popup</code> 4015N/A * Returns a string representation of this <code>JPopupMenu</code>. 0N/A * is intended to be used only for debugging purposes, and the 869N/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 <code>JPopupMenu</code>. 0N/A// Accessibility support 4015N/A * Gets the AccessibleContext associated with this JPopupMenu. 2624N/A * For JPopupMenus, the AccessibleContext takes the form of an 0N/A * AccessibleJPopupMenu. 0N/A * A new AccessibleJPopupMenu instance is created if necessary. 0N/A * @return an AccessibleJPopupMenu that serves as the 0N/A * AccessibleContext of this JPopupMenu 4015N/A * This class implements accessibility support for the 2624N/A * <code>JPopupMenu</code> class. It provides an implementation of the 0N/A * Java Accessibility API appropriate to popup menu user-interface 2624N/A * AccessibleJPopupMenu constructor 868N/A * Get the role of this object. 0N/A * @return an instance of AccessibleRole describing the role of 868N/A * This method gets called when a bound property is changed. 868N/A * @param e A <code>PropertyChangeEvent</code> object describing 869N/A * the event source and the property that has changed. Must not be null. 4015N/A * @throws NullPointerException if the parameter is null. 0N/A * Handles popup "visible" PropertyChangeEvent 869N/A // notify listeners that the popup became visible 2624N/A // notify listeners that a popup list item is selected 0N/A // notify listeners that the popup became hidden 0N/A * Fires AccessibleActiveDescendant PropertyChangeEvent to notify listeners 0N/A * on the popup menu invoker that a popup list item has been selected 869N/A // get the first selected item 0N/A // fire the event with the popup invoker as the source. 869N/A // Check invokerContext because Component.getAccessibleContext 0N/A // returns null. Classes that extend Component are responsible 4015N/A // for returning a non-null AccessibleContext. 4015N/A }
// inner class AccessibleJPopupMenu 0N/A// Serialization support. 0N/A // Save the invoker, if its Serializable. 0N/A // Save the popup, if its Serializable. 0N/A // implements javax.swing.MenuElement 869N/A * This method is required to conform to the 0N/A * <code>MenuElement</code> interface, but it not implemented. 4015N/A * @see MenuElement#processMouseEvent(MouseEvent, MenuElement[], MenuSelectionManager) 0N/A * Processes a key event forwarded from the 869N/A * <code>MenuSelectionManager</code> and changes the menu selection, 0N/A * if necessary, by using <code>MenuSelectionManager</code>'s API. 2624N/A * Note: you do not have to forward the event to sub-components. 0N/A * This is done automatically by the <code>MenuSelectionManager</code>. 0N/A * @param e a <code>KeyEvent</code> 0N/A * @param path the <code>MenuElement</code> path array 1618N/A * @param manager the <code>MenuSelectionManager</code> 2624N/A * Handles a keystroke in a menu. 2917N/A * @param e a <code>MenuKeyEvent</code> object 869N/A * Notifies all listeners that have registered interest for 868N/A * notification on this event type. 869N/A * @param event a <code>MenuKeyEvent</code> 869N/A * Notifies all listeners that have registered interest for 868N/A * notification on this event type. 869N/A * @param event a <code>MenuKeyEvent</code> 869N/A * Notifies all listeners that have registered interest for 2624N/A * notification on this event type. 0N/A * @param event a <code>MenuKeyEvent</code> 0N/A * @see EventListenerList 5488N/A * Messaged when the menubar selection changes to activate or 869N/A * deactivate this menu. This implements the 869N/A * <code>javax.swing.MenuElement</code> interface. 2624N/A * Overrides <code>MenuElement.menuSelectionChanged</code>. 868N/A * @param isIncluded true if this menu is active, false if 869N/A * @see MenuElement#menuSelectionChanged(boolean) 1813N/A * Returns an array of <code>MenuElement</code>s containing the submenu 1874N/A * for this menu component. It will only return items conforming to 1874N/A * the <code>JMenuElement</code> interface. 0N/A * If popup menu is <code>null</code> returns 245N/A * an empty array. This method is required to conform to the 869N/A * <code>MenuElement</code> interface. 868N/A * @return an array of <code>MenuElement</code> objects 5488N/A * @see MenuElement#getSubElements 868N/A for(i=
0 ; i < c ; i++) {
245N/A * Returns this <code>JPopupMenu</code> component. 245N/A * @return this <code>JPopupMenu</code> object 1813N/A * @see MenuElement#getComponent 0N/A * A popup menu-specific separator. 0N/A * Returns the name of the L&F class that renders this component. 2334N/A * @return the string "PopupMenuSeparatorUI" 869N/A * @see JComponent#getUIClassID 2334N/A return "PopupMenuSeparatorUI";
5257N/A * Returns true if the <code>MouseEvent</code> is considered a popup trigger 2334N/A * by the <code>JPopupMenu</code>'s currently installed UI. 0N/A * @return true if the mouse event is a popup trigger