/* * @(#)PopupMenu.java 1.29 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package java.awt; import sun.awt.peer.PopupMenuPeer; import sun.awt.PeerBasedToolkit; /** * A class that implements a menu which can be dynamically popped up * at a specified position within a component.<p> * As the inheritance hierarchy implies, a PopupMenu can be used anywhere * a Menu can be used. However, if you use a PopupMenu like a Menu (e.g., * you add it to a MenuBar), then you <b>cannot</b> call <code>show</code> * on that PopupMenu. * * @version 1.25 08/19/02 * @author Amy Fowler */ public class PopupMenu extends Menu { private static final String base = "popup"; static int nameCounter = 0; /* * JDK 1.1 serialVersionUID */ private static final long serialVersionUID = -4620452533522760060L; /** * Creates a new popup menu. */ public PopupMenu() { this(""); } /** * Creates a new popup menu with the specified name. * * @param label a non-null string specifying the popup menu's label */ public PopupMenu(String label) { super(label); } /** * Construct a name for this MenuComponent. Called by getName() when * the name is null. */ String constructComponentName() { return base + nameCounter++; } /** * Creates the popup menu's peer. The peer allows us to change the * appearance of the popup menu without changing any of the popup menu's * functionality. */ public void addNotify() { synchronized (getTreeLock()) { if (peer == null) { peer = ((PeerBasedToolkit) Toolkit.getDefaultToolkit()).createPopupMenu(this); } int nitems = getItemCount(); for (int i = 0; i < nitems; i++) { MenuItem mi = getItem(i); mi.parent = this; mi.addNotify(); } } } /** * Shows the popup menu at the x, y position relative to an origin component. * The origin component must be contained within the component * hierarchy of the popup menu's parent. Both the origin and the parent * must be showing on the screen for this method to be valid.<p> * If this PopupMenu is being used as a Menu (i.e., it has a non-Component * parent), then you cannot call this method on the PopupMenu. * * @param origin the component which defines the coordinate space * @param x the x coordinate position to popup the menu * @param y the y coordinate position to popup the menu * @exception IllegalArgumentException if this PopupMenu has a non- * Component parent */ public void show(Component origin, int x, int y) { // added for Bug #4698597 if (!(parent instanceof Component)) { throw new IllegalArgumentException( "PopupMenus with non-Component parents cannot be shown"); } Component p = (Component) parent; if (p == null) { throw new NullPointerException("parent is null"); } if (p != origin && p instanceof Container && !((Container) p).isAncestorOf(origin)) { throw new IllegalArgumentException("origin not in parent's hierarchy"); } if (p.peer == null || !p.isShowing()) { throw new RuntimeException("parent not showing on screen"); } if (peer == null) { addNotify(); } synchronized (getTreeLock()) { if (peer != null) { ((PopupMenuPeer) peer).show(origin, x, y); } } } }