001: /*
002: * @(#)PopupMenu.java 1.29 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.awt;
029:
030: import sun.awt.peer.PopupMenuPeer;
031: import sun.awt.PeerBasedToolkit;
032:
033: /**
034: * A class that implements a menu which can be dynamically popped up
035: * at a specified position within a component.<p>
036: * As the inheritance hierarchy implies, a PopupMenu can be used anywhere
037: * a Menu can be used. However, if you use a PopupMenu like a Menu (e.g.,
038: * you add it to a MenuBar), then you <b>cannot</b> call <code>show</code>
039: * on that PopupMenu.
040: *
041: * @version 1.25 08/19/02
042: * @author Amy Fowler
043: */
044: public class PopupMenu extends Menu {
045: private static final String base = "popup";
046: static int nameCounter = 0;
047: /*
048: * JDK 1.1 serialVersionUID
049: */
050: private static final long serialVersionUID = -4620452533522760060L;
051:
052: /**
053: * Creates a new popup menu.
054: */
055: public PopupMenu() {
056: this ("");
057: }
058:
059: /**
060: * Creates a new popup menu with the specified name.
061: *
062: * @param label a non-null string specifying the popup menu's label
063: */
064: public PopupMenu(String label) {
065: super (label);
066: }
067:
068: /**
069: * Construct a name for this MenuComponent. Called by getName() when
070: * the name is null.
071: */
072: String constructComponentName() {
073: return base + nameCounter++;
074: }
075:
076: /**
077: * Creates the popup menu's peer. The peer allows us to change the
078: * appearance of the popup menu without changing any of the popup menu's
079: * functionality.
080: */
081: public void addNotify() {
082: synchronized (getTreeLock()) {
083: if (peer == null) {
084: peer = ((PeerBasedToolkit) Toolkit.getDefaultToolkit())
085: .createPopupMenu(this );
086: }
087: int nitems = getItemCount();
088: for (int i = 0; i < nitems; i++) {
089: MenuItem mi = getItem(i);
090: mi.parent = this ;
091: mi.addNotify();
092: }
093: }
094: }
095:
096: /**
097: * Shows the popup menu at the x, y position relative to an origin component.
098: * The origin component must be contained within the component
099: * hierarchy of the popup menu's parent. Both the origin and the parent
100: * must be showing on the screen for this method to be valid.<p>
101: * If this PopupMenu is being used as a Menu (i.e., it has a non-Component
102: * parent), then you cannot call this method on the PopupMenu.
103: *
104: * @param origin the component which defines the coordinate space
105: * @param x the x coordinate position to popup the menu
106: * @param y the y coordinate position to popup the menu
107: * @exception IllegalArgumentException if this PopupMenu has a non-
108: * Component parent
109: */
110: public void show(Component origin, int x, int y) {
111: // added for Bug #4698597
112: if (!(parent instanceof Component)) {
113: throw new IllegalArgumentException(
114: "PopupMenus with non-Component parents cannot be shown");
115: }
116: Component p = (Component) parent;
117: if (p == null) {
118: throw new NullPointerException("parent is null");
119: }
120: if (p != origin && p instanceof Container
121: && !((Container) p).isAncestorOf(origin)) {
122: throw new IllegalArgumentException(
123: "origin not in parent's hierarchy");
124: }
125: if (p.peer == null || !p.isShowing()) {
126: throw new RuntimeException("parent not showing on screen");
127: }
128: if (peer == null) {
129: addNotify();
130: }
131: synchronized (getTreeLock()) {
132: if (peer != null) {
133: ((PopupMenuPeer) peer).show(origin, x, y);
134: }
135: }
136: }
137: }
|