| /* |
| * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package javax.swing; |
| |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.beans.*; |
| |
| import java.util.Locale; |
| import java.util.Vector; |
| import java.util.Hashtable; |
| import javax.accessibility.*; |
| import javax.swing.plaf.PopupMenuUI; |
| import javax.swing.plaf.ComponentUI; |
| import javax.swing.plaf.basic.BasicComboPopup; |
| import javax.swing.event.*; |
| |
| import sun.awt.SunToolkit; |
| import sun.security.util.SecurityConstants; |
| |
| import java.applet.Applet; |
| |
| /** |
| * An implementation of a popup menu -- a small window that pops up |
| * and displays a series of choices. A <code>JPopupMenu</code> is used for the |
| * menu that appears when the user selects an item on the menu bar. |
| * It is also used for "pull-right" menu that appears when the |
| * selects a menu item that activates it. Finally, a <code>JPopupMenu</code> |
| * can also be used anywhere else you want a menu to appear. For |
| * example, when the user right-clicks in a specified area. |
| * <p> |
| * For information and examples of using popup menus, see |
| * <a |
| href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a> |
| * in <em>The Java Tutorial.</em> |
| * <p> |
| * <strong>Warning:</strong> Swing is not thread safe. For more |
| * information see <a |
| * href="package-summary.html#threading">Swing's Threading |
| * Policy</a>. |
| * <p> |
| * <strong>Warning:</strong> |
| * Serialized objects of this class will not be compatible with |
| * future Swing releases. The current serialization support is |
| * appropriate for short term storage or RMI between applications running |
| * the same version of Swing. As of 1.4, support for long term storage |
| * of all JavaBeans™ |
| * has been added to the <code>java.beans</code> package. |
| * Please see {@link java.beans.XMLEncoder}. |
| * |
| * @beaninfo |
| * attribute: isContainer false |
| * description: A small window that pops up and displays a series of choices. |
| * |
| * @author Georges Saab |
| * @author David Karlton |
| * @author Arnaud Weber |
| */ |
| @SuppressWarnings("serial") |
| public class JPopupMenu extends JComponent implements Accessible,MenuElement { |
| |
| /** |
| * @see #getUIClassID |
| * @see #readObject |
| */ |
| private static final String uiClassID = "PopupMenuUI"; |
| |
| /** |
| * Key used in AppContext to determine if light way popups are the default. |
| */ |
| private static final Object defaultLWPopupEnabledKey = |
| new StringBuffer("JPopupMenu.defaultLWPopupEnabledKey"); |
| |
| /** Bug#4425878-Property javax.swing.adjustPopupLocationToFit introduced */ |
| static boolean popupPostionFixDisabled = false; |
| |
| static { |
| popupPostionFixDisabled = java.security.AccessController.doPrivileged( |
| new sun.security.action.GetPropertyAction( |
| "javax.swing.adjustPopupLocationToFit","")).equals("false"); |
| |
| } |
| |
| transient Component invoker; |
| transient Popup popup; |
| transient Frame frame; |
| private int desiredLocationX,desiredLocationY; |
| |
| private String label = null; |
| private boolean paintBorder = true; |
| private Insets margin = null; |
| |
| /** |
| * Used to indicate if lightweight popups should be used. |
| */ |
| private boolean lightWeightPopup = true; |
| |
| /* |
| * Model for the selected subcontrol. |
| */ |
| private SingleSelectionModel selectionModel; |
| |
| /* Lock object used in place of class object for synchronization. |
| * (4187686) |
| */ |
| private static final Object classLock = new Object(); |
| |
| /* diagnostic aids -- should be false for production builds. */ |
| private static final boolean TRACE = false; // trace creates and disposes |
| private static final boolean VERBOSE = false; // show reuse hits/misses |
| private static final boolean DEBUG = false; // show bad params, misc. |
| |
| /** |
| * Sets the default value of the <code>lightWeightPopupEnabled</code> |
| * property. |
| * |
| * @param aFlag <code>true</code> if popups can be lightweight, |
| * otherwise <code>false</code> |
| * @see #getDefaultLightWeightPopupEnabled |
| * @see #setLightWeightPopupEnabled |
| */ |
| public static void setDefaultLightWeightPopupEnabled(boolean aFlag) { |
| SwingUtilities.appContextPut(defaultLWPopupEnabledKey, |
| Boolean.valueOf(aFlag)); |
| } |
| |
| /** |
| * Gets the <code>defaultLightWeightPopupEnabled</code> property, |
| * which by default is <code>true</code>. |
| * |
| * @return the value of the <code>defaultLightWeightPopupEnabled</code> |
| * property |
| * |
| * @see #setDefaultLightWeightPopupEnabled |
| */ |
| public static boolean getDefaultLightWeightPopupEnabled() { |
| Boolean b = (Boolean) |
| SwingUtilities.appContextGet(defaultLWPopupEnabledKey); |
| if (b == null) { |
| SwingUtilities.appContextPut(defaultLWPopupEnabledKey, |
| Boolean.TRUE); |
| return true; |
| } |
| return b.booleanValue(); |
| } |
| |
| /** |
| * Constructs a <code>JPopupMenu</code> without an "invoker". |
| */ |
| public JPopupMenu() { |
| this(null); |
| } |
| |
| /** |
| * Constructs a <code>JPopupMenu</code> with the specified title. |
| * |
| * @param label the string that a UI may use to display as a title |
| * for the popup menu. |
| */ |
| public JPopupMenu(String label) { |
| this.label = label; |
| lightWeightPopup = getDefaultLightWeightPopupEnabled(); |
| setSelectionModel(new DefaultSingleSelectionModel()); |
| enableEvents(AWTEvent.MOUSE_EVENT_MASK); |
| setFocusTraversalKeysEnabled(false); |
| updateUI(); |
| } |
| |
| |
| |
| /** |
| * Returns the look and feel (L&F) object that renders this component. |
| * |
| * @return the <code>PopupMenuUI</code> object that renders this component |
| */ |
| public PopupMenuUI getUI() { |
| return (PopupMenuUI)ui; |
| } |
| |
| /** |
| * Sets the L&F object that renders this component. |
| * |
| * @param ui the new <code>PopupMenuUI</code> L&F object |
| * @see UIDefaults#getUI |
| * @beaninfo |
| * bound: true |
| * hidden: true |
| * attribute: visualUpdate true |
| * description: The UI object that implements the Component's LookAndFeel. |
| */ |
| public void setUI(PopupMenuUI ui) { |
| super.setUI(ui); |
| } |
| |
| /** |
| * Resets the UI property to a value from the current look and feel. |
| * |
| * @see JComponent#updateUI |
| */ |
| public void updateUI() { |
| setUI((PopupMenuUI)UIManager.getUI(this)); |
| } |
| |
| |
| /** |
| * Returns the name of the L&F class that renders this component. |
| * |
| * @return the string "PopupMenuUI" |
| * @see JComponent#getUIClassID |
| * @see UIDefaults#getUI |
| */ |
| public String getUIClassID() { |
| return uiClassID; |
| } |
| |
| protected void processFocusEvent(FocusEvent evt) { |
| super.processFocusEvent(evt); |
| } |
| |
| /** |
| * Processes key stroke events such as mnemonics and accelerators. |
| * |
| * @param evt the key event to be processed |
| */ |
| protected void processKeyEvent(KeyEvent evt) { |
| MenuSelectionManager.defaultManager().processKeyEvent(evt); |
| if (evt.isConsumed()) { |
| return; |
| } |
| super.processKeyEvent(evt); |
| } |
| |
| |
| /** |
| * Returns the model object that handles single selections. |
| * |
| * @return the <code>selectionModel</code> property |
| * @see SingleSelectionModel |
| */ |
| public SingleSelectionModel getSelectionModel() { |
| return selectionModel; |
| } |
| |
| /** |
| * Sets the model object to handle single selections. |
| * |
| * @param model the new <code>SingleSelectionModel</code> |
| * @see SingleSelectionModel |
| * @beaninfo |
| * description: The selection model for the popup menu |
| * expert: true |
| */ |
| public void setSelectionModel(SingleSelectionModel model) { |
| selectionModel = model; |
| } |
| |
| /** |
| * 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 |
| */ |
| public JMenuItem add(JMenuItem menuItem) { |
| super.add(menuItem); |
| return menuItem; |
| } |
| |
| /** |
| * 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 |
| */ |
| public JMenuItem add(String s) { |
| return add(new JMenuItem(s)); |
| } |
| |
| /** |
| * 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 |
| * @see Action |
| */ |
| public JMenuItem add(Action a) { |
| JMenuItem mi = createActionComponent(a); |
| mi.setAction(a); |
| add(mi); |
| return mi; |
| } |
| |
| /** |
| * Returns an point which has been adjusted to take into account of the |
| * desktop bounds, taskbar and multi-monitor configuration. |
| * <p> |
| * This adustment may be cancelled by invoking the application with |
| * -Djavax.swing.adjustPopupLocationToFit=false |
| */ |
| Point adjustPopupLocationToFitScreen(int xPosition, int yPosition) { |
| Point popupLocation = new Point(xPosition, yPosition); |
| |
| if(popupPostionFixDisabled == true || GraphicsEnvironment.isHeadless()) { |
| return popupLocation; |
| } |
| |
| // Get screen bounds |
| Rectangle scrBounds; |
| GraphicsConfiguration gc = getCurrentGraphicsConfiguration(popupLocation); |
| Toolkit toolkit = Toolkit.getDefaultToolkit(); |
| if(gc != null) { |
| // If we have GraphicsConfiguration use it to get screen bounds |
| scrBounds = gc.getBounds(); |
| } else { |
| // If we don't have GraphicsConfiguration use primary screen |
| scrBounds = new Rectangle(toolkit.getScreenSize()); |
| } |
| |
| // Calculate the screen size that popup should fit |
| Dimension popupSize = JPopupMenu.this.getPreferredSize(); |
| long popupRightX = (long)popupLocation.x + (long)popupSize.width; |
| long popupBottomY = (long)popupLocation.y + (long)popupSize.height; |
| int scrWidth = scrBounds.width; |
| int scrHeight = scrBounds.height; |
| |
| if (!canPopupOverlapTaskBar()) { |
| // Insets include the task bar. Take them into account. |
| Insets scrInsets = toolkit.getScreenInsets(gc); |
| scrBounds.x += scrInsets.left; |
| scrBounds.y += scrInsets.top; |
| scrWidth -= scrInsets.left + scrInsets.right; |
| scrHeight -= scrInsets.top + scrInsets.bottom; |
| } |
| int scrRightX = scrBounds.x + scrWidth; |
| int scrBottomY = scrBounds.y + scrHeight; |
| |
| // Ensure that popup menu fits the screen |
| if (popupRightX > (long) scrRightX) { |
| popupLocation.x = scrRightX - popupSize.width; |
| } |
| |
| if (popupBottomY > (long) scrBottomY) { |
| popupLocation.y = scrBottomY - popupSize.height; |
| } |
| |
| if (popupLocation.x < scrBounds.x) { |
| popupLocation.x = scrBounds.x; |
| } |
| |
| if (popupLocation.y < scrBounds.y) { |
| popupLocation.y = scrBounds.y; |
| } |
| |
| return popupLocation; |
| } |
| |
| /** |
| * Tries to find GraphicsConfiguration |
| * that contains the mouse cursor position. |
| * Can return null. |
| */ |
| private GraphicsConfiguration getCurrentGraphicsConfiguration( |
| Point popupLocation) { |
| GraphicsConfiguration gc = null; |
| GraphicsEnvironment ge = |
| GraphicsEnvironment.getLocalGraphicsEnvironment(); |
| GraphicsDevice[] gd = ge.getScreenDevices(); |
| for(int i = 0; i < gd.length; i++) { |
| if(gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) { |
| GraphicsConfiguration dgc = |
| gd[i].getDefaultConfiguration(); |
| if(dgc.getBounds().contains(popupLocation)) { |
| gc = dgc; |
| break; |
| } |
| } |
| } |
| // If not found and we have invoker, ask invoker about his gc |
| if(gc == null && getInvoker() != null) { |
| gc = getInvoker().getGraphicsConfiguration(); |
| } |
| return gc; |
| } |
| |
| /** |
| * Returns whether popup is allowed to be shown above the task bar. |
| */ |
| static boolean canPopupOverlapTaskBar() { |
| boolean result = true; |
| |
| Toolkit tk = Toolkit.getDefaultToolkit(); |
| if (tk instanceof SunToolkit) { |
| result = ((SunToolkit)tk).canPopupOverlapTaskBar(); |
| } |
| |
| return result; |
| } |
| |
| /** |
| * 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 |
| * @see Action |
| * |
| * @since 1.3 |
| */ |
| protected JMenuItem createActionComponent(Action a) { |
| JMenuItem mi = new JMenuItem() { |
| protected PropertyChangeListener createActionPropertyChangeListener(Action a) { |
| PropertyChangeListener pcl = createActionChangeListener(this); |
| if (pcl == null) { |
| pcl = super.createActionPropertyChangeListener(a); |
| } |
| return pcl; |
| } |
| }; |
| mi.setHorizontalTextPosition(JButton.TRAILING); |
| mi.setVerticalTextPosition(JButton.CENTER); |
| return mi; |
| } |
| |
| /** |
| * Returns a properly configured <code>PropertyChangeListener</code> |
| * which updates the control as changes to the <code>Action</code> occur. |
| */ |
| protected PropertyChangeListener createActionChangeListener(JMenuItem b) { |
| return b.createActionPropertyChangeListener0(b.getAction()); |
| } |
| |
| /** |
| * 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 |
| * number of items |
| */ |
| public void remove(int pos) { |
| if (pos < 0) { |
| throw new IllegalArgumentException("index less than zero."); |
| } |
| if (pos > getComponentCount() -1) { |
| throw new IllegalArgumentException("index greater than the number of items."); |
| } |
| super.remove(pos); |
| } |
| |
| /** |
| * 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, |
| * it can choose to |
| * use a lightweight (all-Java) popup. |
| * Lightweight popup windows are more efficient than heavyweight |
| * (native peer) windows, |
| * 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 |
| * @beaninfo |
| * description: Determines whether lightweight popups are used when possible |
| * expert: true |
| * |
| * @see #isLightWeightPopupEnabled |
| */ |
| public void setLightWeightPopupEnabled(boolean aFlag) { |
| // NOTE: this use to set the flag on a shared JPopupMenu, which meant |
| // this effected ALL JPopupMenus. |
| lightWeightPopup = aFlag; |
| } |
| |
| /** |
| * Gets the <code>lightWeightPopupEnabled</code> property. |
| * |
| * @return the value of the <code>lightWeightPopupEnabled</code> property |
| * @see #setLightWeightPopupEnabled |
| */ |
| public boolean isLightWeightPopupEnabled() { |
| return lightWeightPopup; |
| } |
| |
| /** |
| * Returns the popup menu's label |
| * |
| * @return a string containing the popup menu's label |
| * @see #setLabel |
| */ |
| public String getLabel() { |
| return 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 |
| * |
| * @see #setLabel |
| * @beaninfo |
| * description: The label for the popup menu. |
| * bound: true |
| */ |
| public void setLabel(String label) { |
| String oldValue = this.label; |
| this.label = label; |
| firePropertyChange("label", oldValue, label); |
| if (accessibleContext != null) { |
| accessibleContext.firePropertyChange( |
| AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, |
| oldValue, label); |
| } |
| invalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Appends a new separator at the end of the menu. |
| */ |
| public void addSeparator() { |
| add( new JPopupMenu.Separator() ); |
| } |
| |
| /** |
| * Inserts a menu item for the specified <code>Action</code> object at |
| * a given position. |
| * |
| * @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 |
| * @see Action |
| */ |
| public void insert(Action a, int index) { |
| JMenuItem mi = createActionComponent(a); |
| mi.setAction(a); |
| insert(mi, index); |
| } |
| |
| /** |
| * Inserts the specified component into the menu at a given |
| * position. |
| * |
| * @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 |
| */ |
| public void insert(Component component, int index) { |
| if (index < 0) { |
| throw new IllegalArgumentException("index less than zero."); |
| } |
| |
| int nitems = getComponentCount(); |
| // PENDING(ges): Why not use an array? |
| Vector<Component> tempItems = new Vector<Component>(); |
| |
| /* Remove the item at index, nitems-index times |
| storing them in a temporary vector in the |
| order they appear on the menu. |
| */ |
| for (int i = index ; i < nitems; i++) { |
| tempItems.addElement(getComponent(index)); |
| remove(index); |
| } |
| |
| add(component); |
| |
| /* Add the removed items back to the menu, they are |
| already in the correct order in the temp vector. |
| */ |
| for (Component tempItem : tempItems) { |
| add(tempItem); |
| } |
| } |
| |
| /** |
| * Adds a <code>PopupMenu</code> listener. |
| * |
| * @param l the <code>PopupMenuListener</code> to add |
| */ |
| public void addPopupMenuListener(PopupMenuListener l) { |
| listenerList.add(PopupMenuListener.class,l); |
| } |
| |
| /** |
| * Removes a <code>PopupMenu</code> listener. |
| * |
| * @param l the <code>PopupMenuListener</code> to remove |
| */ |
| public void removePopupMenuListener(PopupMenuListener l) { |
| listenerList.remove(PopupMenuListener.class,l); |
| } |
| |
| /** |
| * 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 |
| * @since 1.4 |
| */ |
| public PopupMenuListener[] getPopupMenuListeners() { |
| return listenerList.getListeners(PopupMenuListener.class); |
| } |
| |
| /** |
| * Adds a <code>MenuKeyListener</code> to the popup menu. |
| * |
| * @param l the <code>MenuKeyListener</code> to be added |
| * @since 1.5 |
| */ |
| public void addMenuKeyListener(MenuKeyListener l) { |
| listenerList.add(MenuKeyListener.class, l); |
| } |
| |
| /** |
| * Removes a <code>MenuKeyListener</code> from the popup menu. |
| * |
| * @param l the <code>MenuKeyListener</code> to be removed |
| * @since 1.5 |
| */ |
| public void removeMenuKeyListener(MenuKeyListener l) { |
| listenerList.remove(MenuKeyListener.class, l); |
| } |
| |
| /** |
| * 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 |
| * @since 1.5 |
| */ |
| public MenuKeyListener[] getMenuKeyListeners() { |
| return listenerList.getListeners(MenuKeyListener.class); |
| } |
| |
| /** |
| * Notifies <code>PopupMenuListener</code>s that this popup menu will |
| * become visible. |
| */ |
| protected void firePopupMenuWillBecomeVisible() { |
| Object[] listeners = listenerList.getListenerList(); |
| PopupMenuEvent e=null; |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==PopupMenuListener.class) { |
| if (e == null) |
| e = new PopupMenuEvent(this); |
| ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeVisible(e); |
| } |
| } |
| } |
| |
| /** |
| * Notifies <code>PopupMenuListener</code>s that this popup menu will |
| * become invisible. |
| */ |
| protected void firePopupMenuWillBecomeInvisible() { |
| Object[] listeners = listenerList.getListenerList(); |
| PopupMenuEvent e=null; |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==PopupMenuListener.class) { |
| if (e == null) |
| e = new PopupMenuEvent(this); |
| ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeInvisible(e); |
| } |
| } |
| } |
| |
| /** |
| * Notifies <code>PopupMenuListeners</code> that this popup menu is |
| * cancelled. |
| */ |
| protected void firePopupMenuCanceled() { |
| Object[] listeners = listenerList.getListenerList(); |
| PopupMenuEvent e=null; |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==PopupMenuListener.class) { |
| if (e == null) |
| e = new PopupMenuEvent(this); |
| ((PopupMenuListener)listeners[i+1]).popupMenuCanceled(e); |
| } |
| } |
| } |
| |
| /** |
| * Always returns true since popups, by definition, should always |
| * be on top of all other windows. |
| * @return true |
| */ |
| // package private |
| boolean alwaysOnTop() { |
| return true; |
| } |
| |
| /** |
| * Lays out the container so that it uses the minimum space |
| * needed to display its contents. |
| */ |
| public void pack() { |
| if(popup != null) { |
| Dimension pref = getPreferredSize(); |
| |
| if (pref == null || pref.width != getWidth() || |
| pref.height != getHeight()) { |
| popup = getPopup(); |
| } else { |
| validate(); |
| } |
| } |
| } |
| |
| /** |
| * Sets the visibility of the popup menu. |
| * |
| * @param b true to make the popup visible, or false to |
| * hide it |
| * @beaninfo |
| * bound: true |
| * description: Makes the popup visible |
| */ |
| public void setVisible(boolean b) { |
| if (DEBUG) { |
| System.out.println("JPopupMenu.setVisible " + b); |
| } |
| |
| // Is it a no-op? |
| if (b == isVisible()) |
| return; |
| |
| // if closing, first close all Submenus |
| if (b == false) { |
| |
| // 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. |
| Boolean doCanceled = (Boolean)getClientProperty("JPopupMenu.firePopupMenuCanceled"); |
| if (doCanceled != null && doCanceled == Boolean.TRUE) { |
| putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.FALSE); |
| firePopupMenuCanceled(); |
| } |
| getSelectionModel().clearSelection(); |
| |
| } else { |
| // This is a popup menu with MenuElement children, |
| // set selection path before popping up! |
| if (isPopupMenu()) { |
| MenuElement me[] = new MenuElement[1]; |
| me[0] = this; |
| MenuSelectionManager.defaultManager().setSelectedPath(me); |
| } |
| } |
| |
| if(b) { |
| firePopupMenuWillBecomeVisible(); |
| popup = getPopup(); |
| firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE); |
| |
| |
| } else if(popup != null) { |
| firePopupMenuWillBecomeInvisible(); |
| popup.hide(); |
| popup = null; |
| firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE); |
| // 4694797: When popup menu is made invisible, selected path |
| // should be cleared |
| if (isPopupMenu()) { |
| MenuSelectionManager.defaultManager().clearSelectedPath(); |
| } |
| } |
| } |
| |
| /** |
| * 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. |
| * <p> |
| * This does NOT fire any events, it is up the caller to dispatch |
| * the necessary events. |
| */ |
| private Popup getPopup() { |
| Popup oldPopup = popup; |
| |
| if (oldPopup != null) { |
| oldPopup.hide(); |
| } |
| PopupFactory popupFactory = PopupFactory.getSharedInstance(); |
| |
| if (isLightWeightPopupEnabled()) { |
| popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP); |
| } |
| else { |
| popupFactory.setPopupType(PopupFactory.HEAVY_WEIGHT_POPUP); |
| } |
| |
| // adjust the location of the popup |
| Point p = adjustPopupLocationToFitScreen(desiredLocationX,desiredLocationY); |
| desiredLocationX = p.x; |
| desiredLocationY = p.y; |
| |
| Popup newPopup = getUI().getPopup(this, desiredLocationX, |
| desiredLocationY); |
| |
| popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP); |
| newPopup.show(); |
| return newPopup; |
| } |
| |
| /** |
| * Returns true if the popup menu is visible (currently |
| * being displayed). |
| */ |
| public boolean isVisible() { |
| return popup != null; |
| } |
| |
| /** |
| * Sets the location of the upper left corner of the |
| * popup menu using x, y coordinates. |
| * <p> |
| * The method changes the geometry-related data. Therefore, |
| * the native windowing system may ignore such requests, or it may modify |
| * the requested data, so that the {@code JPopupMenu} object is placed and sized |
| * in a way that corresponds closely to the desktop settings. |
| * |
| * @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 |
| * @beaninfo |
| * description: The location of the popup menu. |
| */ |
| public void setLocation(int x, int y) { |
| int oldX = desiredLocationX; |
| int oldY = desiredLocationY; |
| |
| desiredLocationX = x; |
| desiredLocationY = y; |
| if(popup != null && (x != oldX || y != oldY)) { |
| popup = getPopup(); |
| } |
| } |
| |
| /** |
| * 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 |
| */ |
| private boolean isPopupMenu() { |
| return ((invoker != null) && !(invoker instanceof JMenu)); |
| } |
| |
| /** |
| * Returns the component which is the 'invoker' of this |
| * popup menu. |
| * |
| * @return the <code>Component</code> in which the popup menu is displayed |
| */ |
| public Component getInvoker() { |
| return this.invoker; |
| } |
| |
| /** |
| * 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 |
| * menu is displayed |
| * @beaninfo |
| * description: The invoking component for the popup menu |
| * expert: true |
| */ |
| public void setInvoker(Component invoker) { |
| Component oldInvoker = this.invoker; |
| this.invoker = invoker; |
| if ((oldInvoker != this.invoker) && (ui != null)) { |
| ui.uninstallUI(this); |
| ui.installUI(this); |
| } |
| invalidate(); |
| } |
| |
| /** |
| * 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 |
| */ |
| public void show(Component invoker, int x, int y) { |
| if (DEBUG) { |
| System.out.println("in JPopupMenu.show " ); |
| } |
| setInvoker(invoker); |
| Frame newFrame = getFrame(invoker); |
| if (newFrame != frame) { |
| // Use the invoker's frame so that events |
| // are propagated properly |
| if (newFrame!=null) { |
| this.frame = newFrame; |
| if(popup != null) { |
| setVisible(false); |
| } |
| } |
| } |
| Point invokerOrigin; |
| if (invoker != null) { |
| invokerOrigin = invoker.getLocationOnScreen(); |
| |
| // To avoid integer overflow |
| long lx, ly; |
| lx = ((long) invokerOrigin.x) + |
| ((long) x); |
| ly = ((long) invokerOrigin.y) + |
| ((long) y); |
| if(lx > Integer.MAX_VALUE) lx = Integer.MAX_VALUE; |
| if(lx < Integer.MIN_VALUE) lx = Integer.MIN_VALUE; |
| if(ly > Integer.MAX_VALUE) ly = Integer.MAX_VALUE; |
| if(ly < Integer.MIN_VALUE) ly = Integer.MIN_VALUE; |
| |
| setLocation((int) lx, (int) ly); |
| } else { |
| setLocation(x, y); |
| } |
| setVisible(true); |
| } |
| |
| /** |
| * Returns the popup menu which is at the root of the menu system |
| * for this popup menu. |
| * |
| * @return the topmost grandparent <code>JPopupMenu</code> |
| */ |
| JPopupMenu getRootPopupMenu() { |
| JPopupMenu mp = this; |
| while((mp!=null) && (mp.isPopupMenu()!=true) && |
| (mp.getInvoker() != null) && |
| (mp.getInvoker().getParent() != null) && |
| (mp.getInvoker().getParent() instanceof JPopupMenu) |
| ) { |
| mp = (JPopupMenu) mp.getInvoker().getParent(); |
| } |
| return mp; |
| } |
| |
| /** |
| * 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)} |
| */ |
| @Deprecated |
| public Component getComponentAtIndex(int i) { |
| return getComponent(i); |
| } |
| |
| /** |
| * 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 |
| */ |
| public int getComponentIndex(Component c) { |
| int ncomponents = this.getComponentCount(); |
| Component[] component = this.getComponents(); |
| for (int i = 0 ; i < ncomponents ; i++) { |
| Component comp = component[i]; |
| if (comp == c) |
| return i; |
| } |
| return -1; |
| } |
| |
| /** |
| * 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 |
| * of this component. |
| * @beaninfo |
| * description: The size of the popup menu |
| */ |
| public void setPopupSize(Dimension d) { |
| Dimension oldSize = getPreferredSize(); |
| |
| setPreferredSize(d); |
| if (popup != null) { |
| Dimension newSize = getPreferredSize(); |
| |
| if (!oldSize.equals(newSize)) { |
| popup = getPopup(); |
| } |
| } |
| } |
| |
| /** |
| * 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 |
| * @beaninfo |
| * description: The size of the popup menu |
| */ |
| public void setPopupSize(int width, int height) { |
| setPopupSize(new Dimension(width, height)); |
| } |
| |
| /** |
| * Sets the currently selected component, This will result |
| * in a change to the selection model. |
| * |
| * @param sel the <code>Component</code> to select |
| * @beaninfo |
| * description: The selected component on the popup menu |
| * expert: true |
| * hidden: true |
| */ |
| public void setSelected(Component sel) { |
| SingleSelectionModel model = getSelectionModel(); |
| int index = getComponentIndex(sel); |
| model.setSelectedIndex(index); |
| } |
| |
| /** |
| * Checks whether the border should be painted. |
| * |
| * @return true if the border is painted, false otherwise |
| * @see #setBorderPainted |
| */ |
| public boolean isBorderPainted() { |
| return paintBorder; |
| } |
| |
| /** |
| * Sets whether the border should be painted. |
| * |
| * @param b if true, the border is painted. |
| * @see #isBorderPainted |
| * @beaninfo |
| * description: Is the border of the popup menu painted |
| */ |
| public void setBorderPainted(boolean b) { |
| paintBorder = b; |
| repaint(); |
| } |
| |
| /** |
| * 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#paint |
| * @see JComponent#setBorder |
| */ |
| protected void paintBorder(Graphics g) { |
| if (isBorderPainted()) { |
| super.paintBorder(g); |
| } |
| } |
| |
| /** |
| * Returns the margin, in pixels, between the popup menu's border and |
| * its containers. |
| * |
| * @return an <code>Insets</code> object containing the margin values. |
| */ |
| public Insets getMargin() { |
| if(margin == null) { |
| return new Insets(0,0,0,0); |
| } else { |
| return margin; |
| } |
| } |
| |
| |
| /** |
| * 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> |
| */ |
| boolean isSubPopupMenu(JPopupMenu popup) { |
| int ncomponents = this.getComponentCount(); |
| Component[] component = this.getComponents(); |
| for (int i = 0 ; i < ncomponents ; i++) { |
| Component comp = component[i]; |
| if (comp instanceof JMenu) { |
| JMenu menu = (JMenu)comp; |
| JPopupMenu subPopup = menu.getPopupMenu(); |
| if (subPopup == popup) |
| return true; |
| if (subPopup.isSubPopupMenu(popup)) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| |
| private static Frame getFrame(Component c) { |
| Component w = c; |
| |
| while(!(w instanceof Frame) && (w!=null)) { |
| w = w.getParent(); |
| } |
| return (Frame)w; |
| } |
| |
| |
| /** |
| * Returns a string representation of this <code>JPopupMenu</code>. |
| * This method |
| * 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 |
| * be <code>null</code>. |
| * |
| * @return a string representation of this <code>JPopupMenu</code>. |
| */ |
| protected String paramString() { |
| String labelString = (label != null ? |
| label : ""); |
| String paintBorderString = (paintBorder ? |
| "true" : "false"); |
| String marginString = (margin != null ? |
| margin.toString() : ""); |
| String lightWeightPopupEnabledString = (isLightWeightPopupEnabled() ? |
| "true" : "false"); |
| return super.paramString() + |
| ",desiredLocationX=" + desiredLocationX + |
| ",desiredLocationY=" + desiredLocationY + |
| ",label=" + labelString + |
| ",lightWeightPopupEnabled=" + lightWeightPopupEnabledString + |
| ",margin=" + marginString + |
| ",paintBorder=" + paintBorderString; |
| } |
| |
| ///////////////// |
| // Accessibility support |
| //////////////// |
| |
| /** |
| * Gets the AccessibleContext associated with this JPopupMenu. |
| * For JPopupMenus, the AccessibleContext takes the form of an |
| * AccessibleJPopupMenu. |
| * A new AccessibleJPopupMenu instance is created if necessary. |
| * |
| * @return an AccessibleJPopupMenu that serves as the |
| * AccessibleContext of this JPopupMenu |
| */ |
| public AccessibleContext getAccessibleContext() { |
| if (accessibleContext == null) { |
| accessibleContext = new AccessibleJPopupMenu(); |
| } |
| return accessibleContext; |
| } |
| |
| /** |
| * 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 |
| * elements. |
| */ |
| @SuppressWarnings("serial") |
| protected class AccessibleJPopupMenu extends AccessibleJComponent |
| implements PropertyChangeListener { |
| |
| /** |
| * AccessibleJPopupMenu constructor |
| * |
| * @since 1.5 |
| */ |
| protected AccessibleJPopupMenu() { |
| JPopupMenu.this.addPropertyChangeListener(this); |
| } |
| |
| /** |
| * Get the role of this object. |
| * |
| * @return an instance of AccessibleRole describing the role of |
| * the object |
| */ |
| public AccessibleRole getAccessibleRole() { |
| return AccessibleRole.POPUP_MENU; |
| } |
| |
| /** |
| * 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. |
| * @since 1.5 |
| */ |
| public void propertyChange(PropertyChangeEvent e) { |
| String propertyName = e.getPropertyName(); |
| if (propertyName == "visible") { |
| if (e.getOldValue() == Boolean.FALSE && |
| e.getNewValue() == Boolean.TRUE) { |
| handlePopupIsVisibleEvent(true); |
| |
| } else if (e.getOldValue() == Boolean.TRUE && |
| e.getNewValue() == Boolean.FALSE) { |
| handlePopupIsVisibleEvent(false); |
| } |
| } |
| } |
| |
| /* |
| * Handles popup "visible" PropertyChangeEvent |
| */ |
| private void handlePopupIsVisibleEvent(boolean visible) { |
| if (visible) { |
| // notify listeners that the popup became visible |
| firePropertyChange(ACCESSIBLE_STATE_PROPERTY, |
| null, AccessibleState.VISIBLE); |
| // notify listeners that a popup list item is selected |
| fireActiveDescendant(); |
| } else { |
| // notify listeners that the popup became hidden |
| firePropertyChange(ACCESSIBLE_STATE_PROPERTY, |
| AccessibleState.VISIBLE, null); |
| } |
| } |
| |
| /* |
| * Fires AccessibleActiveDescendant PropertyChangeEvent to notify listeners |
| * on the popup menu invoker that a popup list item has been selected |
| */ |
| private void fireActiveDescendant() { |
| if (JPopupMenu.this instanceof BasicComboPopup) { |
| // get the popup list |
| JList<?> popupList = ((BasicComboPopup)JPopupMenu.this).getList(); |
| if (popupList == null) { |
| return; |
| } |
| |
| // get the first selected item |
| AccessibleContext ac = popupList.getAccessibleContext(); |
| AccessibleSelection selection = ac.getAccessibleSelection(); |
| if (selection == null) { |
| return; |
| } |
| Accessible a = selection.getAccessibleSelection(0); |
| if (a == null) { |
| return; |
| } |
| AccessibleContext selectedItem = a.getAccessibleContext(); |
| |
| // fire the event with the popup invoker as the source. |
| if (selectedItem != null && invoker != null) { |
| AccessibleContext invokerContext = invoker.getAccessibleContext(); |
| if (invokerContext != null) { |
| // Check invokerContext because Component.getAccessibleContext |
| // returns null. Classes that extend Component are responsible |
| // for returning a non-null AccessibleContext. |
| invokerContext.firePropertyChange( |
| ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, |
| null, selectedItem); |
| } |
| } |
| } |
| } |
| } // inner class AccessibleJPopupMenu |
| |
| |
| //////////// |
| // Serialization support. |
| //////////// |
| private void writeObject(ObjectOutputStream s) throws IOException { |
| Vector<Object> values = new Vector<Object>(); |
| |
| s.defaultWriteObject(); |
| // Save the invoker, if its Serializable. |
| if(invoker != null && invoker instanceof Serializable) { |
| values.addElement("invoker"); |
| values.addElement(invoker); |
| } |
| // Save the popup, if its Serializable. |
| if(popup != null && popup instanceof Serializable) { |
| values.addElement("popup"); |
| values.addElement(popup); |
| } |
| s.writeObject(values); |
| |
| if (getUIClassID().equals(uiClassID)) { |
| byte count = JComponent.getWriteObjCounter(this); |
| JComponent.setWriteObjCounter(this, --count); |
| if (count == 0 && ui != null) { |
| ui.installUI(this); |
| } |
| } |
| } |
| |
| // implements javax.swing.MenuElement |
| private void readObject(ObjectInputStream s) |
| throws IOException, ClassNotFoundException { |
| s.defaultReadObject(); |
| |
| Vector<?> values = (Vector)s.readObject(); |
| int indexCounter = 0; |
| int maxCounter = values.size(); |
| |
| if(indexCounter < maxCounter && values.elementAt(indexCounter). |
| equals("invoker")) { |
| invoker = (Component)values.elementAt(++indexCounter); |
| indexCounter++; |
| } |
| if(indexCounter < maxCounter && values.elementAt(indexCounter). |
| equals("popup")) { |
| popup = (Popup)values.elementAt(++indexCounter); |
| indexCounter++; |
| } |
| } |
| |
| |
| /** |
| * This method is required to conform to the |
| * <code>MenuElement</code> interface, but it not implemented. |
| * @see MenuElement#processMouseEvent(MouseEvent, MenuElement[], MenuSelectionManager) |
| */ |
| public void processMouseEvent(MouseEvent event,MenuElement path[],MenuSelectionManager manager) {} |
| |
| /** |
| * Processes a key event forwarded from the |
| * <code>MenuSelectionManager</code> and changes the menu selection, |
| * if necessary, by using <code>MenuSelectionManager</code>'s API. |
| * <p> |
| * 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> |
| */ |
| public void processKeyEvent(KeyEvent e, MenuElement path[], |
| MenuSelectionManager manager) { |
| MenuKeyEvent mke = new MenuKeyEvent(e.getComponent(), e.getID(), |
| e.getWhen(), e.getModifiers(), |
| e.getKeyCode(), e.getKeyChar(), |
| path, manager); |
| processMenuKeyEvent(mke); |
| |
| if (mke.isConsumed()) { |
| e.consume(); |
| } |
| } |
| |
| /** |
| * Handles a keystroke in a menu. |
| * |
| * @param e a <code>MenuKeyEvent</code> object |
| * @since 1.5 |
| */ |
| private void processMenuKeyEvent(MenuKeyEvent e) { |
| switch (e.getID()) { |
| case KeyEvent.KEY_PRESSED: |
| fireMenuKeyPressed(e); break; |
| case KeyEvent.KEY_RELEASED: |
| fireMenuKeyReleased(e); break; |
| case KeyEvent.KEY_TYPED: |
| fireMenuKeyTyped(e); break; |
| default: |
| break; |
| } |
| } |
| |
| /** |
| * Notifies all listeners that have registered interest for |
| * notification on this event type. |
| * |
| * @param event a <code>MenuKeyEvent</code> |
| * @see EventListenerList |
| */ |
| private void fireMenuKeyPressed(MenuKeyEvent event) { |
| Object[] listeners = listenerList.getListenerList(); |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==MenuKeyListener.class) { |
| ((MenuKeyListener)listeners[i+1]).menuKeyPressed(event); |
| } |
| } |
| } |
| |
| /** |
| * Notifies all listeners that have registered interest for |
| * notification on this event type. |
| * |
| * @param event a <code>MenuKeyEvent</code> |
| * @see EventListenerList |
| */ |
| private void fireMenuKeyReleased(MenuKeyEvent event) { |
| Object[] listeners = listenerList.getListenerList(); |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==MenuKeyListener.class) { |
| ((MenuKeyListener)listeners[i+1]).menuKeyReleased(event); |
| } |
| } |
| } |
| |
| /** |
| * Notifies all listeners that have registered interest for |
| * notification on this event type. |
| * |
| * @param event a <code>MenuKeyEvent</code> |
| * @see EventListenerList |
| */ |
| private void fireMenuKeyTyped(MenuKeyEvent event) { |
| Object[] listeners = listenerList.getListenerList(); |
| for (int i = listeners.length-2; i>=0; i-=2) { |
| if (listeners[i]==MenuKeyListener.class) { |
| ((MenuKeyListener)listeners[i+1]).menuKeyTyped(event); |
| } |
| } |
| } |
| |
| /** |
| * 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 |
| * it is not |
| * @see MenuElement#menuSelectionChanged(boolean) |
| */ |
| public void menuSelectionChanged(boolean isIncluded) { |
| if (DEBUG) { |
| System.out.println("In JPopupMenu.menuSelectionChanged " + isIncluded); |
| } |
| if(invoker instanceof JMenu) { |
| JMenu m = (JMenu) invoker; |
| if(isIncluded) |
| m.setPopupMenuVisible(true); |
| else |
| m.setPopupMenuVisible(false); |
| } |
| if (isPopupMenu() && !isIncluded) |
| setVisible(false); |
| } |
| |
| /** |
| * 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 |
| */ |
| public MenuElement[] getSubElements() { |
| MenuElement result[]; |
| Vector<MenuElement> tmp = new Vector<MenuElement>(); |
| int c = getComponentCount(); |
| int i; |
| Component m; |
| |
| for(i=0 ; i < c ; i++) { |
| m = getComponent(i); |
| if(m instanceof MenuElement) |
| tmp.addElement((MenuElement) m); |
| } |
| |
| result = new MenuElement[tmp.size()]; |
| for(i=0,c=tmp.size() ; i < c ; i++) |
| result[i] = tmp.elementAt(i); |
| return result; |
| } |
| |
| /** |
| * Returns this <code>JPopupMenu</code> component. |
| * @return this <code>JPopupMenu</code> object |
| * @see MenuElement#getComponent |
| */ |
| public Component getComponent() { |
| return this; |
| } |
| |
| |
| /** |
| * A popup menu-specific separator. |
| */ |
| @SuppressWarnings("serial") |
| static public class Separator extends JSeparator |
| { |
| public Separator( ) |
| { |
| super( JSeparator.HORIZONTAL ); |
| } |
| |
| /** |
| * Returns the name of the L&F class that renders this component. |
| * |
| * @return the string "PopupMenuSeparatorUI" |
| * @see JComponent#getUIClassID |
| * @see UIDefaults#getUI |
| */ |
| public String 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 |
| * @since 1.3 |
| */ |
| public boolean isPopupTrigger(MouseEvent e) { |
| return getUI().isPopupTrigger(e); |
| } |
| } |