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