Source Code Cross Referenced for JPopupMenu.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.swing;
0027
0028        import java.awt.*;
0029        import java.awt.event.*;
0030        import java.io.IOException;
0031        import java.io.ObjectInputStream;
0032        import java.io.ObjectOutputStream;
0033        import java.io.Serializable;
0034        import java.beans.*;
0035
0036        import java.util.Locale;
0037        import java.util.Vector;
0038        import java.util.Hashtable;
0039        import javax.accessibility.*;
0040        import javax.swing.plaf.PopupMenuUI;
0041        import javax.swing.plaf.ComponentUI;
0042        import javax.swing.plaf.basic.BasicComboPopup;
0043        import javax.swing.event.*;
0044
0045        import java.applet.Applet;
0046
0047        /**
0048         * An implementation of a popup menu -- a small window that pops up
0049         * and displays a series of choices. A <code>JPopupMenu</code> is used for the
0050         * menu that appears when the user selects an item on the menu bar.
0051         * It is also used for "pull-right" menu that appears when the
0052         * selects a menu item that activates it. Finally, a <code>JPopupMenu</code>
0053         * can also be used anywhere else you want a menu to appear.  For
0054         * example, when the user right-clicks in a specified area.
0055         * <p>
0056         * For information and examples of using popup menus, see
0057         * <a
0058         href="http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html">How to Use Menus</a>
0059         * in <em>The Java Tutorial.</em>
0060         * <p>
0061         * <strong>Warning:</strong> Swing is not thread safe. For more
0062         * information see <a
0063         * href="package-summary.html#threading">Swing's Threading
0064         * Policy</a>.
0065         * <p>
0066         * <strong>Warning:</strong>
0067         * Serialized objects of this class will not be compatible with
0068         * future Swing releases. The current serialization support is
0069         * appropriate for short term storage or RMI between applications running
0070         * the same version of Swing.  As of 1.4, support for long term storage
0071         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0072         * has been added to the <code>java.beans</code> package.
0073         * Please see {@link java.beans.XMLEncoder}.
0074         *
0075         * @beaninfo
0076         *   attribute: isContainer false
0077         * description: A small window that pops up and displays a series of choices.
0078         *
0079         * @version 1.205 @(#)JPopupMenu.java	1.205
0080         * @author Georges Saab
0081         * @author David Karlton
0082         * @author Arnaud Weber
0083         */
0084        public class JPopupMenu extends JComponent implements  Accessible,
0085                MenuElement {
0086
0087            /**
0088             * @see #getUIClassID
0089             * @see #readObject
0090             */
0091            private static final String uiClassID = "PopupMenuUI";
0092
0093            /**
0094             * Key used in AppContext to determine if light way popups are the default.
0095             */
0096            private static final Object defaultLWPopupEnabledKey = new StringBuffer(
0097                    "JPopupMenu.defaultLWPopupEnabledKey");
0098
0099            /** Bug#4425878-Property javax.swing.adjustPopupLocationToFit introduced */
0100            static boolean popupPostionFixDisabled = false;
0101
0102            static {
0103                popupPostionFixDisabled = java.security.AccessController
0104                        .doPrivileged(
0105                                new sun.security.action.GetPropertyAction(
0106                                        "javax.swing.adjustPopupLocationToFit",
0107                                        "")).equals("false");
0108
0109            }
0110
0111            transient Component invoker;
0112            transient Popup popup;
0113            transient Frame frame;
0114            private int desiredLocationX, desiredLocationY;
0115
0116            private String label = null;
0117            private boolean paintBorder = true;
0118            private Insets margin = null;
0119
0120            /**
0121             * Used to indicate if lightweight popups should be used.
0122             */
0123            private boolean lightWeightPopup = true;
0124
0125            /*
0126             * Model for the selected subcontrol.
0127             */
0128            private SingleSelectionModel selectionModel;
0129
0130            /* Lock object used in place of class object for synchronization. 
0131             * (4187686)
0132             */
0133            private static final Object classLock = new Object();
0134
0135            /* diagnostic aids -- should be false for production builds. */
0136            private static final boolean TRACE = false; // trace creates and disposes
0137            private static final boolean VERBOSE = false; // show reuse hits/misses
0138            private static final boolean DEBUG = false; // show bad params, misc.
0139
0140            /**
0141             *  Sets the default value of the <code>lightWeightPopupEnabled</code>
0142             *  property.
0143             *
0144             *  @param aFlag <code>true</code> if popups can be lightweight,
0145             *               otherwise <code>false</code>
0146             *  @see #getDefaultLightWeightPopupEnabled
0147             *  @see #setLightWeightPopupEnabled
0148             */
0149            public static void setDefaultLightWeightPopupEnabled(boolean aFlag) {
0150                SwingUtilities.appContextPut(defaultLWPopupEnabledKey, Boolean
0151                        .valueOf(aFlag));
0152            }
0153
0154            /** 
0155             *  Gets the <code>defaultLightWeightPopupEnabled</code> property,
0156             *  which by default is <code>true</code>.
0157             *
0158             *  @return the value of the <code>defaultLightWeightPopupEnabled</code>
0159             *          property
0160             *
0161             *  @see #setDefaultLightWeightPopupEnabled
0162             */
0163            public static boolean getDefaultLightWeightPopupEnabled() {
0164                Boolean b = (Boolean) SwingUtilities
0165                        .appContextGet(defaultLWPopupEnabledKey);
0166                if (b == null) {
0167                    SwingUtilities.appContextPut(defaultLWPopupEnabledKey,
0168                            Boolean.TRUE);
0169                    return true;
0170                }
0171                return b.booleanValue();
0172            }
0173
0174            /**
0175             * Constructs a <code>JPopupMenu</code> without an "invoker".
0176             */
0177            public JPopupMenu() {
0178                this (null);
0179            }
0180
0181            /**
0182             * Constructs a <code>JPopupMenu</code> with the specified title.
0183             *
0184             * @param label  the string that a UI may use to display as a title 
0185             * for the popup menu.
0186             */
0187            public JPopupMenu(String label) {
0188                this .label = label;
0189                lightWeightPopup = getDefaultLightWeightPopupEnabled();
0190                setSelectionModel(new DefaultSingleSelectionModel());
0191                enableEvents(AWTEvent.MOUSE_EVENT_MASK);
0192                setFocusTraversalKeysEnabled(false);
0193                updateUI();
0194            }
0195
0196            /**
0197             * Returns the look and feel (L&F) object that renders this component.
0198             *
0199             * @return the <code>PopupMenuUI</code> object that renders this component
0200             */
0201            public PopupMenuUI getUI() {
0202                return (PopupMenuUI) ui;
0203            }
0204
0205            /**
0206             * Sets the L&F object that renders this component.
0207             *
0208             * @param ui the new <code>PopupMenuUI</code> L&F object
0209             * @see UIDefaults#getUI
0210             * @beaninfo
0211             *        bound: true
0212             *       hidden: true
0213             *    attribute: visualUpdate true
0214             *  description: The UI object that implements the Component's LookAndFeel. 
0215             */
0216            public void setUI(PopupMenuUI ui) {
0217                super .setUI(ui);
0218            }
0219
0220            /**
0221             * Resets the UI property to a value from the current look and feel.
0222             *
0223             * @see JComponent#updateUI
0224             */
0225            public void updateUI() {
0226                setUI((PopupMenuUI) UIManager.getUI(this ));
0227            }
0228
0229            /**
0230             * Returns the name of the L&F class that renders this component.
0231             *
0232             * @return the string "PopupMenuUI"
0233             * @see JComponent#getUIClassID
0234             * @see UIDefaults#getUI
0235             */
0236            public String getUIClassID() {
0237                return uiClassID;
0238            }
0239
0240            protected void processFocusEvent(FocusEvent evt) {
0241                super .processFocusEvent(evt);
0242            }
0243
0244            /**
0245             * Processes key stroke events such as mnemonics and accelerators.
0246             *
0247             * @param evt  the key event to be processed
0248             */
0249            protected void processKeyEvent(KeyEvent evt) {
0250                MenuSelectionManager.defaultManager().processKeyEvent(evt);
0251                if (evt.isConsumed()) {
0252                    return;
0253                }
0254                super .processKeyEvent(evt);
0255            }
0256
0257            /**
0258             * Returns the model object that handles single selections.
0259             *
0260             * @return the <code>selectionModel</code> property
0261             * @see SingleSelectionModel
0262             */
0263            public SingleSelectionModel getSelectionModel() {
0264                return selectionModel;
0265            }
0266
0267            /**
0268             * Sets the model object to handle single selections.
0269             *
0270             * @param model the new <code>SingleSelectionModel</code>
0271             * @see SingleSelectionModel
0272             * @beaninfo
0273             * description: The selection model for the popup menu
0274             *      expert: true
0275             */
0276            public void setSelectionModel(SingleSelectionModel model) {
0277                selectionModel = model;
0278            }
0279
0280            /**
0281             * Appends the specified menu item to the end of this menu. 
0282             *
0283             * @param menuItem the <code>JMenuItem</code> to add
0284             * @return the <code>JMenuItem</code> added
0285             */
0286            public JMenuItem add(JMenuItem menuItem) {
0287                super .add(menuItem);
0288                return menuItem;
0289            }
0290
0291            /**
0292             * Creates a new menu item with the specified text and appends
0293             * it to the end of this menu.
0294             *  
0295             * @param s the string for the menu item to be added
0296             */
0297            public JMenuItem add(String s) {
0298                return add(new JMenuItem(s));
0299            }
0300
0301            /**
0302             * Appends a new menu item to the end of the menu which 
0303             * dispatches the specified <code>Action</code> object.
0304             *
0305             * @param a the <code>Action</code> to add to the menu
0306             * @return the new menu item
0307             * @see Action
0308             */
0309            public JMenuItem add(Action a) {
0310                JMenuItem mi = createActionComponent(a);
0311                mi.setAction(a);
0312                add(mi);
0313                return mi;
0314            }
0315
0316            /**
0317             * Returns an point which has been adjusted to take into account of the 
0318             * desktop bounds, taskbar and multi-monitor configuration.
0319             * <p>
0320             * This adustment may be cancelled by invoking the application with
0321             * -Djavax.swing.adjustPopupLocationToFit=false
0322             */
0323            Point adjustPopupLocationToFitScreen(int xposition, int yposition) {
0324                Point p = new Point(xposition, yposition);
0325
0326                if (popupPostionFixDisabled == true
0327                        || GraphicsEnvironment.isHeadless())
0328                    return p;
0329
0330                Toolkit toolkit = Toolkit.getDefaultToolkit();
0331                Rectangle screenBounds;
0332                Insets screenInsets;
0333                GraphicsConfiguration gc = null;
0334                // Try to find GraphicsConfiguration, that includes mouse
0335                // pointer position
0336                GraphicsEnvironment ge = GraphicsEnvironment
0337                        .getLocalGraphicsEnvironment();
0338                GraphicsDevice[] gd = ge.getScreenDevices();
0339                for (int i = 0; i < gd.length; i++) {
0340                    if (gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
0341                        GraphicsConfiguration dgc = gd[i]
0342                                .getDefaultConfiguration();
0343                        if (dgc.getBounds().contains(p)) {
0344                            gc = dgc;
0345                            break;
0346                        }
0347                    }
0348                }
0349
0350                // If not found and we have invoker, ask invoker about his gc
0351                if (gc == null && getInvoker() != null) {
0352                    gc = getInvoker().getGraphicsConfiguration();
0353                }
0354
0355                if (gc != null) {
0356                    // If we have GraphicsConfiguration use it to get
0357                    // screen bounds and insets
0358                    screenInsets = toolkit.getScreenInsets(gc);
0359                    screenBounds = gc.getBounds();
0360                } else {
0361                    // If we don't have GraphicsConfiguration use primary screen
0362                    // and empty insets
0363                    screenInsets = new Insets(0, 0, 0, 0);
0364                    screenBounds = new Rectangle(toolkit.getScreenSize());
0365                }
0366
0367                int scrWidth = screenBounds.width
0368                        - Math.abs(screenInsets.left + screenInsets.right);
0369                int scrHeight = screenBounds.height
0370                        - Math.abs(screenInsets.top + screenInsets.bottom);
0371
0372                Dimension size;
0373
0374                size = JPopupMenu.this .getPreferredSize();
0375
0376                // Use long variables to prevent overflow
0377                long pw = (long) p.x + (long) size.width;
0378                long ph = (long) p.y + (long) size.height;
0379
0380                if (pw > screenBounds.x + scrWidth)
0381                    p.x = screenBounds.x + scrWidth - size.width;
0382
0383                if (ph > screenBounds.y + scrHeight)
0384                    p.y = screenBounds.y + scrHeight - size.height;
0385
0386                /* Change is made to the desired (X,Y) values, when the
0387                   PopupMenu is too tall OR too wide for the screen
0388                 */
0389                if (p.x < screenBounds.x)
0390                    p.x = screenBounds.x;
0391                if (p.y < screenBounds.y)
0392                    p.y = screenBounds.y;
0393
0394                return p;
0395            }
0396
0397            /**
0398             * Factory method which creates the <code>JMenuItem</code> for
0399             * <code>Actions</code> added to the <code>JPopupMenu</code>.
0400             *
0401             * @param a the <code>Action</code> for the menu item to be added
0402             * @return the new menu item
0403             * @see Action
0404             *
0405             * @since 1.3
0406             */
0407            protected JMenuItem createActionComponent(Action a) {
0408                JMenuItem mi = new JMenuItem() {
0409                    protected PropertyChangeListener createActionPropertyChangeListener(
0410                            Action a) {
0411                        PropertyChangeListener pcl = createActionChangeListener(this );
0412                        if (pcl == null) {
0413                            pcl = super .createActionPropertyChangeListener(a);
0414                        }
0415                        return pcl;
0416                    }
0417                };
0418                mi.setHorizontalTextPosition(JButton.TRAILING);
0419                mi.setVerticalTextPosition(JButton.CENTER);
0420                return mi;
0421            }
0422
0423            /**
0424             * Returns a properly configured <code>PropertyChangeListener</code>
0425             * which updates the control as changes to the <code>Action</code> occur.  
0426             */
0427            protected PropertyChangeListener createActionChangeListener(
0428                    JMenuItem b) {
0429                return b.createActionPropertyChangeListener0(b.getAction());
0430            }
0431
0432            /**
0433             * Removes the component at the specified index from this popup menu.
0434             *
0435             * @param       pos the position of the item to be removed
0436             * @exception   IllegalArgumentException if the value of 
0437             *                       	<code>pos</code> < 0, or if the value of
0438             *				<code>pos</code> is greater than the
0439             *				number of items
0440             */
0441            public void remove(int pos) {
0442                if (pos < 0) {
0443                    throw new IllegalArgumentException("index less than zero.");
0444                }
0445                if (pos > getComponentCount() - 1) {
0446                    throw new IllegalArgumentException(
0447                            "index greater than the number of items.");
0448                }
0449                super .remove(pos);
0450            }
0451
0452            /**
0453             * Sets the value of the <code>lightWeightPopupEnabled</code> property,
0454             * which by default is <code>true</code>.
0455             * By default, when a look and feel displays a popup, 
0456             * it can choose to
0457             * use a lightweight (all-Java) popup.
0458             * Lightweight popup windows are more efficient than heavyweight 
0459             * (native peer) windows,
0460             * but lightweight and heavyweight components do not mix well in a GUI.
0461             * If your application mixes lightweight and heavyweight components,
0462             * you should disable lightweight popups.
0463             * Some look and feels might always use heavyweight popups,
0464             * no matter what the value of this property.
0465             *
0466             * @param aFlag  <code>false</code> to disable lightweight popups
0467             * @beaninfo
0468             * description: Determines whether lightweight popups are used when possible
0469             *      expert: true
0470             *
0471             * @see #isLightWeightPopupEnabled
0472             */
0473            public void setLightWeightPopupEnabled(boolean aFlag) {
0474                // NOTE: this use to set the flag on a shared JPopupMenu, which meant
0475                // this effected ALL JPopupMenus.
0476                lightWeightPopup = aFlag;
0477            }
0478
0479            /**
0480             * Gets the <code>lightWeightPopupEnabled</code> property.
0481             *
0482             * @return the value of the <code>lightWeightPopupEnabled</code> property
0483             * @see #setLightWeightPopupEnabled
0484             */
0485            public boolean isLightWeightPopupEnabled() {
0486                return lightWeightPopup;
0487            }
0488
0489            /**
0490             * Returns the popup menu's label
0491             *
0492             * @return a string containing the popup menu's label
0493             * @see #setLabel
0494             */
0495            public String getLabel() {
0496                return label;
0497            }
0498
0499            /**
0500             * Sets the popup menu's label.  Different look and feels may choose
0501             * to display or not display this.
0502             *
0503             * @param label a string specifying the label for the popup menu
0504             *
0505             * @see #setLabel
0506             * @beaninfo
0507             * description: The label for the popup menu. 
0508             *       bound: true
0509             */
0510            public void setLabel(String label) {
0511                String oldValue = this .label;
0512                this .label = label;
0513                firePropertyChange("label", oldValue, label);
0514                if (accessibleContext != null) {
0515                    accessibleContext.firePropertyChange(
0516                            AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
0517                            oldValue, label);
0518                }
0519                invalidate();
0520                repaint();
0521            }
0522
0523            /**
0524             * Appends a new separator at the end of the menu.
0525             */
0526            public void addSeparator() {
0527                add(new JPopupMenu.Separator());
0528            }
0529
0530            /**
0531             * Inserts a menu item for the specified <code>Action</code> object at 
0532             * a given position.
0533             *
0534             * @param a  the <code>Action</code> object to insert
0535             * @param index      specifies the position at which to insert the
0536             *                   <code>Action</code>, where 0 is the first
0537             * @exception IllegalArgumentException if <code>index</code> < 0
0538             * @see Action
0539             */
0540            public void insert(Action a, int index) {
0541                JMenuItem mi = createActionComponent(a);
0542                mi.setAction(a);
0543                insert(mi, index);
0544            }
0545
0546            /**
0547             * Inserts the specified component into the menu at a given
0548             * position.
0549             *
0550             * @param component  the <code>Component</code> to insert
0551             * @param index      specifies the position at which
0552             *                   to insert the component, where 0 is the first
0553             * @exception IllegalArgumentException if <code>index</code> < 0
0554             */
0555            public void insert(Component component, int index) {
0556                if (index < 0) {
0557                    throw new IllegalArgumentException("index less than zero.");
0558                }
0559
0560                int nitems = getComponentCount();
0561                // PENDING(ges): Why not use an array?
0562                Vector tempItems = new Vector();
0563
0564                /* Remove the item at index, nitems-index times 
0565                   storing them in a temporary vector in the
0566                   order they appear on the menu.
0567                 */
0568                for (int i = index; i < nitems; i++) {
0569                    tempItems.addElement(getComponent(index));
0570                    remove(index);
0571                }
0572
0573                add(component);
0574
0575                /* Add the removed items back to the menu, they are
0576                   already in the correct order in the temp vector.
0577                 */
0578                for (int i = 0; i < tempItems.size(); i++) {
0579                    add((Component) tempItems.elementAt(i));
0580                }
0581            }
0582
0583            /**
0584             *  Adds a <code>PopupMenu</code> listener.
0585             *
0586             *  @param l  the <code>PopupMenuListener</code> to add
0587             */
0588            public void addPopupMenuListener(PopupMenuListener l) {
0589                listenerList.add(PopupMenuListener.class, l);
0590            }
0591
0592            /**
0593             * Removes a <code>PopupMenu</code> listener.
0594             *
0595             * @param l  the <code>PopupMenuListener</code> to remove
0596             */
0597            public void removePopupMenuListener(PopupMenuListener l) {
0598                listenerList.remove(PopupMenuListener.class, l);
0599            }
0600
0601            /**
0602             * Returns an array of all the <code>PopupMenuListener</code>s added
0603             * to this JMenuItem with addPopupMenuListener().
0604             * 
0605             * @return all of the <code>PopupMenuListener</code>s added or an empty
0606             *         array if no listeners have been added
0607             * @since 1.4
0608             */
0609            public PopupMenuListener[] getPopupMenuListeners() {
0610                return (PopupMenuListener[]) listenerList
0611                        .getListeners(PopupMenuListener.class);
0612            }
0613
0614            /**
0615             * Adds a <code>MenuKeyListener</code> to the popup menu.
0616             *
0617             * @param l the <code>MenuKeyListener</code> to be added
0618             * @since 1.5
0619             */
0620            public void addMenuKeyListener(MenuKeyListener l) {
0621                listenerList.add(MenuKeyListener.class, l);
0622            }
0623
0624            /**
0625             * Removes a <code>MenuKeyListener</code> from the popup menu.
0626             *
0627             * @param l the <code>MenuKeyListener</code> to be removed
0628             * @since 1.5
0629             */
0630            public void removeMenuKeyListener(MenuKeyListener l) {
0631                listenerList.remove(MenuKeyListener.class, l);
0632            }
0633
0634            /**
0635             * Returns an array of all the <code>MenuKeyListener</code>s added
0636             * to this JPopupMenu with addMenuKeyListener().
0637             *
0638             * @return all of the <code>MenuKeyListener</code>s added or an empty
0639             *         array if no listeners have been added
0640             * @since 1.5
0641             */
0642            public MenuKeyListener[] getMenuKeyListeners() {
0643                return (MenuKeyListener[]) listenerList
0644                        .getListeners(MenuKeyListener.class);
0645            }
0646
0647            /**
0648             * Notifies <code>PopupMenuListener</code>s that this popup menu will 
0649             * become visible.
0650             */
0651            protected void firePopupMenuWillBecomeVisible() {
0652                Object[] listeners = listenerList.getListenerList();
0653                PopupMenuEvent e = null;
0654                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0655                    if (listeners[i] == PopupMenuListener.class) {
0656                        if (e == null)
0657                            e = new PopupMenuEvent(this );
0658                        ((PopupMenuListener) listeners[i + 1])
0659                                .popupMenuWillBecomeVisible(e);
0660                    }
0661                }
0662            }
0663
0664            /**
0665             * Notifies <code>PopupMenuListener</code>s that this popup menu will 
0666             * become invisible.
0667             */
0668            protected void firePopupMenuWillBecomeInvisible() {
0669                Object[] listeners = listenerList.getListenerList();
0670                PopupMenuEvent e = null;
0671                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0672                    if (listeners[i] == PopupMenuListener.class) {
0673                        if (e == null)
0674                            e = new PopupMenuEvent(this );
0675                        ((PopupMenuListener) listeners[i + 1])
0676                                .popupMenuWillBecomeInvisible(e);
0677                    }
0678                }
0679            }
0680
0681            /**
0682             * Notifies <code>PopupMenuListeners</code> that this popup menu is 
0683             * cancelled.
0684             */
0685            protected void firePopupMenuCanceled() {
0686                Object[] listeners = listenerList.getListenerList();
0687                PopupMenuEvent e = null;
0688                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0689                    if (listeners[i] == PopupMenuListener.class) {
0690                        if (e == null)
0691                            e = new PopupMenuEvent(this );
0692                        ((PopupMenuListener) listeners[i + 1])
0693                                .popupMenuCanceled(e);
0694                    }
0695                }
0696            }
0697
0698            /**
0699             * Always returns true since popups, by definition, should always
0700             * be on top of all other windows.
0701             * @return true
0702             */
0703            // package private
0704            boolean alwaysOnTop() {
0705                return true;
0706            }
0707
0708            /**
0709             * Lays out the container so that it uses the minimum space
0710             * needed to display its contents.
0711             */
0712            public void pack() {
0713                if (popup != null) {
0714                    Dimension pref = getPreferredSize();
0715
0716                    if (pref == null || pref.width != getWidth()
0717                            || pref.height != getHeight()) {
0718                        popup = getPopup();
0719                    } else {
0720                        validate();
0721                    }
0722                }
0723            }
0724
0725            /**
0726             * Sets the visibility of the popup menu.
0727             * 
0728             * @param b true to make the popup visible, or false to
0729             *          hide it
0730             * @beaninfo
0731             *           bound: true
0732             *     description: Makes the popup visible
0733             */
0734            public void setVisible(boolean b) {
0735                if (DEBUG) {
0736                    System.out.println("JPopupMenu.setVisible " + b);
0737                }
0738
0739                // Is it a no-op?
0740                if (b == isVisible())
0741                    return;
0742
0743                // if closing, first close all Submenus
0744                if (b == false) {
0745
0746                    // 4234793: This is a workaround because JPopupMenu.firePopupMenuCanceled is
0747                    // a protected method and cannot be called from BasicPopupMenuUI directly
0748                    // The real solution could be to make 
0749                    // firePopupMenuCanceled public and call it directly.
0750                    Boolean doCanceled = (Boolean) getClientProperty("JPopupMenu.firePopupMenuCanceled");
0751                    if (doCanceled != null && doCanceled == Boolean.TRUE) {
0752                        putClientProperty("JPopupMenu.firePopupMenuCanceled",
0753                                Boolean.FALSE);
0754                        firePopupMenuCanceled();
0755                    }
0756                    getSelectionModel().clearSelection();
0757
0758                } else {
0759                    // This is a popup menu with MenuElement children,
0760                    // set selection path before popping up!
0761                    if (isPopupMenu()) {
0762                        if (getSubElements().length > 0) {
0763                            MenuElement me[] = new MenuElement[2];
0764                            me[0] = (MenuElement) this ;
0765                            me[1] = getSubElements()[0];
0766                            MenuSelectionManager.defaultManager()
0767                                    .setSelectedPath(me);
0768                        } else {
0769                            MenuElement me[] = new MenuElement[1];
0770                            me[0] = (MenuElement) this ;
0771                            MenuSelectionManager.defaultManager()
0772                                    .setSelectedPath(me);
0773                        }
0774                    }
0775                }
0776
0777                if (b) {
0778                    firePopupMenuWillBecomeVisible();
0779                    popup = getPopup();
0780                    firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE);
0781
0782                } else if (popup != null) {
0783                    firePopupMenuWillBecomeInvisible();
0784                    popup.hide();
0785                    popup = null;
0786                    firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE);
0787                    // 4694797: When popup menu is made invisible, selected path
0788                    // should be cleared
0789                    if (isPopupMenu()) {
0790                        MenuSelectionManager.defaultManager()
0791                                .clearSelectedPath();
0792                    }
0793                }
0794            }
0795
0796            /**
0797             * Returns a <code>Popup</code> instance from the
0798             * <code>PopupMenuUI</code> that has had <code>show</code> invoked on
0799             * it. If the current <code>popup</code> is non-null,
0800             * this will invoke <code>dispose</code> of it, and then
0801             * <code>show</code> the new one.
0802             * <p>
0803             * This does NOT fire any events, it is up the caller to dispatch
0804             * the necessary events.
0805             */
0806            private Popup getPopup() {
0807                Popup oldPopup = popup;
0808
0809                if (oldPopup != null) {
0810                    oldPopup.hide();
0811                }
0812                PopupFactory popupFactory = PopupFactory.getSharedInstance();
0813
0814                if (isLightWeightPopupEnabled()) {
0815                    popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
0816                } else {
0817                    popupFactory.setPopupType(PopupFactory.MEDIUM_WEIGHT_POPUP);
0818                }
0819
0820                // adjust the location of the popup
0821                Point p = adjustPopupLocationToFitScreen(desiredLocationX,
0822                        desiredLocationY);
0823                desiredLocationX = p.x;
0824                desiredLocationY = p.y;
0825
0826                Popup newPopup = getUI().getPopup(this , desiredLocationX,
0827                        desiredLocationY);
0828
0829                popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
0830                newPopup.show();
0831                return newPopup;
0832            }
0833
0834            /**
0835             * Returns true if the popup menu is visible (currently
0836             * being displayed).
0837             */
0838            public boolean isVisible() {
0839                if (popup != null)
0840                    return true;
0841                else
0842                    return false;
0843            }
0844
0845            /**
0846             * Sets the location of the upper left corner of the
0847             * popup menu using x, y coordinates.
0848             *
0849             * @param x the x coordinate of the popup's new position
0850             *          in the screen's coordinate space
0851             * @param y the y coordinate of the popup's new position
0852             *          in the screen's coordinate space
0853             * @beaninfo
0854             * description: The location of the popup menu.
0855             */
0856            public void setLocation(int x, int y) {
0857                int oldX = desiredLocationX;
0858                int oldY = desiredLocationY;
0859
0860                desiredLocationX = x;
0861                desiredLocationY = y;
0862                if (popup != null && (x != oldX || y != oldY)) {
0863                    popup = getPopup();
0864                }
0865            }
0866
0867            /**
0868             * Returns true if the popup menu is a standalone popup menu
0869             * rather than the submenu of a <code>JMenu</code>.
0870             *
0871             * @return true if this menu is a standalone popup menu, otherwise false
0872             */
0873            private boolean isPopupMenu() {
0874                return ((invoker != null) && !(invoker instanceof  JMenu));
0875            }
0876
0877            /**
0878             * Returns the component which is the 'invoker' of this 
0879             * popup menu.
0880             *
0881             * @return the <code>Component</code> in which the popup menu is displayed
0882             */
0883            public Component getInvoker() {
0884                return this .invoker;
0885            }
0886
0887            /**
0888             * Sets the invoker of this popup menu -- the component in which
0889             * the popup menu menu is to be displayed.
0890             *
0891             * @param invoker the <code>Component</code> in which the popup
0892             *		menu is displayed
0893             * @beaninfo
0894             * description: The invoking component for the popup menu
0895             *      expert: true
0896             */
0897            public void setInvoker(Component invoker) {
0898                Component oldInvoker = this .invoker;
0899                this .invoker = invoker;
0900                if ((oldInvoker != this .invoker) && (ui != null)) {
0901                    ui.uninstallUI(this );
0902                    ui.installUI(this );
0903                }
0904                invalidate();
0905            }
0906
0907            /**
0908             * Displays the popup menu at the position x,y in the coordinate
0909             * space of the component invoker.
0910             *
0911             * @param invoker the component in whose space the popup menu is to appear
0912             * @param x the x coordinate in invoker's coordinate space at which 
0913             * the popup menu is to be displayed
0914             * @param y the y coordinate in invoker's coordinate space at which 
0915             * the popup menu is to be displayed
0916             */
0917            public void show(Component invoker, int x, int y) {
0918                if (DEBUG) {
0919                    System.out.println("in JPopupMenu.show ");
0920                }
0921                setInvoker(invoker);
0922                Frame newFrame = getFrame(invoker);
0923                if (newFrame != frame) {
0924                    // Use the invoker's frame so that events 
0925                    // are propagated properly
0926                    if (newFrame != null) {
0927                        this .frame = newFrame;
0928                        if (popup != null) {
0929                            setVisible(false);
0930                        }
0931                    }
0932                }
0933                Point invokerOrigin;
0934                if (invoker != null) {
0935                    invokerOrigin = invoker.getLocationOnScreen();
0936
0937                    // To avoid integer overflow
0938                    long lx, ly;
0939                    lx = ((long) invokerOrigin.x) + ((long) x);
0940                    ly = ((long) invokerOrigin.y) + ((long) y);
0941                    if (lx > Integer.MAX_VALUE)
0942                        lx = Integer.MAX_VALUE;
0943                    if (lx < Integer.MIN_VALUE)
0944                        lx = Integer.MIN_VALUE;
0945                    if (ly > Integer.MAX_VALUE)
0946                        ly = Integer.MAX_VALUE;
0947                    if (ly < Integer.MIN_VALUE)
0948                        ly = Integer.MIN_VALUE;
0949
0950                    setLocation((int) lx, (int) ly);
0951                } else {
0952                    setLocation(x, y);
0953                }
0954                setVisible(true);
0955            }
0956
0957            /**
0958             * Returns the popup menu which is at the root of the menu system
0959             * for this popup menu.
0960             *
0961             * @return the topmost grandparent <code>JPopupMenu</code>
0962             */
0963            JPopupMenu getRootPopupMenu() {
0964                JPopupMenu mp = this ;
0965                while ((mp != null) && (mp.isPopupMenu() != true)
0966                        && (mp.getInvoker() != null)
0967                        && (mp.getInvoker().getParent() != null)
0968                        && (mp.getInvoker().getParent() instanceof  JPopupMenu)) {
0969                    mp = (JPopupMenu) mp.getInvoker().getParent();
0970                }
0971                return mp;
0972            }
0973
0974            /**
0975             * Returns the component at the specified index.
0976             * 
0977             * @param i  the index of the component, where 0 is the first 
0978             * @return the <code>Component</code> at that index 
0979             * @deprecated replaced by {@link java.awt.Container#getComponent(int)} 
0980             */
0981            @Deprecated
0982            public Component getComponentAtIndex(int i) {
0983                return getComponent(i);
0984            }
0985
0986            /**
0987             * Returns the index of the specified component.
0988             * 
0989             * @param  c the <code>Component</code> to find
0990             * @return the index of the component, where 0 is the first;
0991             *         or -1 if the component is not found
0992             */
0993            public int getComponentIndex(Component c) {
0994                int ncomponents = this .getComponentCount();
0995                Component[] component = this .getComponents();
0996                for (int i = 0; i < ncomponents; i++) {
0997                    Component comp = component[i];
0998                    if (comp == c)
0999                        return i;
1000                }
1001                return -1;
1002            }
1003
1004            /**
1005             * Sets the size of the Popup window using a <code>Dimension</code> object.
1006             * This is equivalent to <code>setPreferredSize(d)</code>.
1007             *
1008             * @param d   the <code>Dimension</code> specifying the new size 
1009             * of this component.
1010             * @beaninfo
1011             * description: The size of the popup menu
1012             */
1013            public void setPopupSize(Dimension d) {
1014                Dimension oldSize = getPreferredSize();
1015
1016                setPreferredSize(d);
1017                if (popup != null) {
1018                    Dimension newSize = getPreferredSize();
1019
1020                    if (!oldSize.equals(newSize)) {
1021                        popup = getPopup();
1022                    }
1023                }
1024            }
1025
1026            /**
1027             * Sets the size of the Popup window to the specified width and
1028             * height. This is equivalent to
1029             *  <code>setPreferredSize(new Dimension(width, height))</code>.
1030             *
1031             * @param width the new width of the Popup in pixels
1032             * @param height the new height of the Popup in pixels
1033             * @beaninfo
1034             * description: The size of the popup menu
1035             */
1036            public void setPopupSize(int width, int height) {
1037                setPopupSize(new Dimension(width, height));
1038            }
1039
1040            /**
1041             * Sets the currently selected component,  This will result
1042             * in a change to the selection model.
1043             *
1044             * @param sel the <code>Component</code> to select
1045             * @beaninfo
1046             * description: The selected component on the popup menu
1047             *      expert: true
1048             *      hidden: true
1049             */
1050            public void setSelected(Component sel) {
1051                SingleSelectionModel model = getSelectionModel();
1052                int index = getComponentIndex(sel);
1053                model.setSelectedIndex(index);
1054            }
1055
1056            /**
1057             * Checks whether the border should be painted.
1058             *
1059             * @return true if the border is painted, false otherwise
1060             * @see #setBorderPainted
1061             */
1062            public boolean isBorderPainted() {
1063                return paintBorder;
1064            }
1065
1066            /**
1067             * Sets whether the border should be painted.
1068             *
1069             * @param b if true, the border is painted.
1070             * @see #isBorderPainted
1071             * @beaninfo
1072             * description: Is the border of the popup menu painted
1073             */
1074            public void setBorderPainted(boolean b) {
1075                paintBorder = b;
1076                repaint();
1077            }
1078
1079            /**
1080             * Paints the popup menu's border if the <code>borderPainted</code>
1081             * property is <code>true</code>.
1082             * @param g  the <code>Graphics</code> object
1083             * 
1084             * @see JComponent#paint
1085             * @see JComponent#setBorder
1086             */
1087            protected void paintBorder(Graphics g) {
1088                if (isBorderPainted()) {
1089                    super .paintBorder(g);
1090                }
1091            }
1092
1093            /**
1094             * Returns the margin, in pixels, between the popup menu's border and
1095             * its containees.
1096             *
1097             * @return an <code>Insets</code> object containing the margin values.
1098             */
1099            public Insets getMargin() {
1100                if (margin == null) {
1101                    return new Insets(0, 0, 0, 0);
1102                } else {
1103                    return margin;
1104                }
1105            }
1106
1107            /**
1108             * Examines the list of menu items to determine whether
1109             * <code>popup</code> is a popup menu.
1110             * 
1111             * @param popup  a <code>JPopupMenu</code>
1112             * @return true if <code>popup</code>
1113             */
1114            boolean isSubPopupMenu(JPopupMenu popup) {
1115                int ncomponents = this .getComponentCount();
1116                Component[] component = this .getComponents();
1117                for (int i = 0; i < ncomponents; i++) {
1118                    Component comp = component[i];
1119                    if (comp instanceof  JMenu) {
1120                        JMenu menu = (JMenu) comp;
1121                        JPopupMenu subPopup = menu.getPopupMenu();
1122                        if (subPopup == popup)
1123                            return true;
1124                        if (subPopup.isSubPopupMenu(popup))
1125                            return true;
1126                    }
1127                }
1128                return false;
1129            }
1130
1131            private static Frame getFrame(Component c) {
1132                Component w = c;
1133
1134                while (!(w instanceof  Frame) && (w != null)) {
1135                    w = w.getParent();
1136                }
1137                return (Frame) w;
1138            }
1139
1140            /**
1141             * Returns a string representation of this <code>JPopupMenu</code>.
1142             * This method 
1143             * is intended to be used only for debugging purposes, and the 
1144             * content and format of the returned string may vary between      
1145             * implementations. The returned string may be empty but may not 
1146             * be <code>null</code>.
1147             * 
1148             * @return  a string representation of this <code>JPopupMenu</code>.
1149             */
1150            protected String paramString() {
1151                String labelString = (label != null ? label : "");
1152                String paintBorderString = (paintBorder ? "true" : "false");
1153                String marginString = (margin != null ? margin.toString() : "");
1154                String lightWeightPopupEnabledString = (isLightWeightPopupEnabled() ? "true"
1155                        : "false");
1156                return super .paramString() + ",desiredLocationX="
1157                        + desiredLocationX + ",desiredLocationY="
1158                        + desiredLocationY + ",label=" + labelString
1159                        + ",lightWeightPopupEnabled="
1160                        + lightWeightPopupEnabledString + ",margin="
1161                        + marginString + ",paintBorder=" + paintBorderString;
1162            }
1163
1164            /////////////////
1165            // Accessibility support
1166            ////////////////
1167
1168            /**
1169             * Gets the AccessibleContext associated with this JPopupMenu. 
1170             * For JPopupMenus, the AccessibleContext takes the form of an 
1171             * AccessibleJPopupMenu. 
1172             * A new AccessibleJPopupMenu instance is created if necessary.
1173             *
1174             * @return an AccessibleJPopupMenu that serves as the 
1175             *         AccessibleContext of this JPopupMenu
1176             */
1177            public AccessibleContext getAccessibleContext() {
1178                if (accessibleContext == null) {
1179                    accessibleContext = new AccessibleJPopupMenu();
1180                }
1181                return accessibleContext;
1182            }
1183
1184            /**
1185             * This class implements accessibility support for the 
1186             * <code>JPopupMenu</code> class.  It provides an implementation of the 
1187             * Java Accessibility API appropriate to popup menu user-interface 
1188             * elements.
1189             */
1190            protected class AccessibleJPopupMenu extends AccessibleJComponent
1191                    implements  PropertyChangeListener {
1192
1193                /**
1194                 * AccessibleJPopupMenu constructor
1195                 *
1196                 * @since 1.5
1197                 */
1198                protected AccessibleJPopupMenu() {
1199                    JPopupMenu.this .addPropertyChangeListener(this );
1200                }
1201
1202                /**
1203                 * Get the role of this object.
1204                 *
1205                 * @return an instance of AccessibleRole describing the role of 
1206                 * the object
1207                 */
1208                public AccessibleRole getAccessibleRole() {
1209                    return AccessibleRole.POPUP_MENU;
1210                }
1211
1212                /**
1213                 * This method gets called when a bound property is changed.
1214                 * @param e A <code>PropertyChangeEvent</code> object describing
1215                 * the event source and the property that has changed. Must not be null.
1216                 *
1217                 * @throws NullPointerException if the parameter is null.
1218                 * @since 1.5
1219                 */
1220                public void propertyChange(PropertyChangeEvent e) {
1221                    String propertyName = e.getPropertyName();
1222                    if (propertyName == "visible") {
1223                        if (e.getOldValue() == Boolean.FALSE
1224                                && e.getNewValue() == Boolean.TRUE) {
1225                            handlePopupIsVisibleEvent(true);
1226
1227                        } else if (e.getOldValue() == Boolean.TRUE
1228                                && e.getNewValue() == Boolean.FALSE) {
1229                            handlePopupIsVisibleEvent(false);
1230                        }
1231                    }
1232                }
1233
1234                /*
1235                 * Handles popup "visible" PropertyChangeEvent
1236                 */
1237                private void handlePopupIsVisibleEvent(boolean visible) {
1238                    if (visible) {
1239                        // notify listeners that the popup became visible
1240                        firePropertyChange(ACCESSIBLE_STATE_PROPERTY, null,
1241                                AccessibleState.VISIBLE);
1242                        // notify listeners that a popup list item is selected
1243                        fireActiveDescendant();
1244                    } else {
1245                        // notify listeners that the popup became hidden
1246                        firePropertyChange(ACCESSIBLE_STATE_PROPERTY,
1247                                AccessibleState.VISIBLE, null);
1248                    }
1249                }
1250
1251                /*
1252                 * Fires AccessibleActiveDescendant PropertyChangeEvent to notify listeners
1253                 * on the popup menu invoker that a popup list item has been selected
1254                 */
1255                private void fireActiveDescendant() {
1256                    if (JPopupMenu.this  instanceof  BasicComboPopup) {
1257                        // get the popup list
1258                        JList popupList = ((BasicComboPopup) JPopupMenu.this )
1259                                .getList();
1260                        if (popupList == null) {
1261                            return;
1262                        }
1263
1264                        // get the first selected item
1265                        AccessibleContext ac = popupList.getAccessibleContext();
1266                        AccessibleSelection selection = ac
1267                                .getAccessibleSelection();
1268                        if (selection == null) {
1269                            return;
1270                        }
1271                        Accessible a = selection.getAccessibleSelection(0);
1272                        if (a == null) {
1273                            return;
1274                        }
1275                        AccessibleContext selectedItem = a
1276                                .getAccessibleContext();
1277
1278                        // fire the event with the popup invoker as the source.  
1279                        if (selectedItem != null && invoker != null) {
1280                            AccessibleContext invokerContext = invoker
1281                                    .getAccessibleContext();
1282                            if (invokerContext != null) {
1283                                // Check invokerContext because Component.getAccessibleContext 
1284                                // returns null. Classes that extend Component are responsible
1285                                // for returning a non-null AccessibleContext.
1286                                invokerContext.firePropertyChange(
1287                                        ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
1288                                        null, selectedItem);
1289                            }
1290                        }
1291                    }
1292                }
1293            } // inner class AccessibleJPopupMenu
1294
1295            ////////////
1296            // Serialization support.  
1297            ////////////
1298            private void writeObject(ObjectOutputStream s) throws IOException {
1299                Vector values = new Vector();
1300
1301                s.defaultWriteObject();
1302                // Save the invoker, if its Serializable.
1303                if (invoker != null && invoker instanceof  Serializable) {
1304                    values.addElement("invoker");
1305                    values.addElement(invoker);
1306                }
1307                // Save the popup, if its Serializable.
1308                if (popup != null && popup instanceof  Serializable) {
1309                    values.addElement("popup");
1310                    values.addElement(popup);
1311                }
1312                s.writeObject(values);
1313
1314                if (getUIClassID().equals(uiClassID)) {
1315                    byte count = JComponent.getWriteObjCounter(this );
1316                    JComponent.setWriteObjCounter(this , --count);
1317                    if (count == 0 && ui != null) {
1318                        ui.installUI(this );
1319                    }
1320                }
1321            }
1322
1323            // implements javax.swing.MenuElement
1324            private void readObject(ObjectInputStream s) throws IOException,
1325                    ClassNotFoundException {
1326                s.defaultReadObject();
1327
1328                Vector values = (Vector) s.readObject();
1329                int indexCounter = 0;
1330                int maxCounter = values.size();
1331
1332                if (indexCounter < maxCounter
1333                        && values.elementAt(indexCounter).equals("invoker")) {
1334                    invoker = (Component) values.elementAt(++indexCounter);
1335                    indexCounter++;
1336                }
1337                if (indexCounter < maxCounter
1338                        && values.elementAt(indexCounter).equals("popup")) {
1339                    popup = (Popup) values.elementAt(++indexCounter);
1340                    indexCounter++;
1341                }
1342            }
1343
1344            /**
1345             * This method is required to conform to the
1346             * <code>MenuElement</code> interface, but it not implemented.
1347             * @see MenuElement#processMouseEvent(MouseEvent, MenuElement[], MenuSelectionManager)
1348             */
1349            public void processMouseEvent(MouseEvent event, MenuElement path[],
1350                    MenuSelectionManager manager) {
1351            }
1352
1353            /**
1354             * Processes a key event forwarded from the
1355             * <code>MenuSelectionManager</code> and changes the menu selection,
1356             * if necessary, by using <code>MenuSelectionManager</code>'s API.
1357             * <p>
1358             * Note: you do not have to forward the event to sub-components.
1359             * This is done automatically by the <code>MenuSelectionManager</code>.
1360             *
1361             * @param e  a <code>KeyEvent</code>
1362             * @param path the <code>MenuElement</code> path array
1363             * @param manager   the <code>MenuSelectionManager</code>
1364             */
1365            public void processKeyEvent(KeyEvent e, MenuElement path[],
1366                    MenuSelectionManager manager) {
1367                MenuKeyEvent mke = new MenuKeyEvent(e.getComponent(),
1368                        e.getID(), e.getWhen(), e.getModifiers(), e
1369                                .getKeyCode(), e.getKeyChar(), path, manager);
1370                processMenuKeyEvent(mke);
1371
1372                if (mke.isConsumed()) {
1373                    e.consume();
1374                }
1375            }
1376
1377            /**
1378             * Handles a keystroke in a menu.
1379             *
1380             * @param e  a <code>MenuKeyEvent</code> object
1381             * @since 1.5
1382             */
1383            private void processMenuKeyEvent(MenuKeyEvent e) {
1384                switch (e.getID()) {
1385                case KeyEvent.KEY_PRESSED:
1386                    fireMenuKeyPressed(e);
1387                    break;
1388                case KeyEvent.KEY_RELEASED:
1389                    fireMenuKeyReleased(e);
1390                    break;
1391                case KeyEvent.KEY_TYPED:
1392                    fireMenuKeyTyped(e);
1393                    break;
1394                default:
1395                    break;
1396                }
1397            }
1398
1399            /**
1400             * Notifies all listeners that have registered interest for
1401             * notification on this event type.
1402             *
1403             * @param event a <code>MenuKeyEvent</code>
1404             * @see EventListenerList
1405             */
1406            private void fireMenuKeyPressed(MenuKeyEvent event) {
1407                Object[] listeners = listenerList.getListenerList();
1408                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1409                    if (listeners[i] == MenuKeyListener.class) {
1410                        ((MenuKeyListener) listeners[i + 1])
1411                                .menuKeyPressed(event);
1412                    }
1413                }
1414            }
1415
1416            /**
1417             * Notifies all listeners that have registered interest for
1418             * notification on this event type.
1419             *
1420             * @param event a <code>MenuKeyEvent</code>
1421             * @see EventListenerList
1422             */
1423            private void fireMenuKeyReleased(MenuKeyEvent event) {
1424                Object[] listeners = listenerList.getListenerList();
1425                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1426                    if (listeners[i] == MenuKeyListener.class) {
1427                        ((MenuKeyListener) listeners[i + 1])
1428                                .menuKeyReleased(event);
1429                    }
1430                }
1431            }
1432
1433            /**
1434             * Notifies all listeners that have registered interest for
1435             * notification on this event type.
1436             *
1437             * @param event a <code>MenuKeyEvent</code>
1438             * @see EventListenerList
1439             */
1440            private void fireMenuKeyTyped(MenuKeyEvent event) {
1441                Object[] listeners = listenerList.getListenerList();
1442                for (int i = listeners.length - 2; i >= 0; i -= 2) {
1443                    if (listeners[i] == MenuKeyListener.class) {
1444                        ((MenuKeyListener) listeners[i + 1])
1445                                .menuKeyTyped(event);
1446                    }
1447                }
1448            }
1449
1450            /**
1451             * Messaged when the menubar selection changes to activate or
1452             * deactivate this menu. This implements the
1453             * <code>javax.swing.MenuElement</code> interface.
1454             * Overrides <code>MenuElement.menuSelectionChanged</code>.
1455             *
1456             * @param isIncluded  true if this menu is active, false if
1457             *        it is not
1458             * @see MenuElement#menuSelectionChanged(boolean)
1459             */
1460            public void menuSelectionChanged(boolean isIncluded) {
1461                if (DEBUG) {
1462                    System.out.println("In JPopupMenu.menuSelectionChanged "
1463                            + isIncluded);
1464                }
1465                if (invoker instanceof  JMenu) {
1466                    JMenu m = (JMenu) invoker;
1467                    if (isIncluded)
1468                        m.setPopupMenuVisible(true);
1469                    else
1470                        m.setPopupMenuVisible(false);
1471                }
1472                if (isPopupMenu() && !isIncluded)
1473                    setVisible(false);
1474            }
1475
1476            /**
1477             * Returns an array of <code>MenuElement</code>s containing the submenu
1478             * for this menu component.  It will only return items conforming to
1479             * the <code>JMenuElement</code> interface.
1480             * If popup menu is <code>null</code> returns
1481             * an empty array.  This method is required to conform to the
1482             * <code>MenuElement</code> interface.  
1483             *
1484             * @return an array of <code>MenuElement</code> objects
1485             * @see MenuElement#getSubElements
1486             */
1487            public MenuElement[] getSubElements() {
1488                MenuElement result[];
1489                Vector tmp = new Vector();
1490                int c = getComponentCount();
1491                int i;
1492                Component m;
1493
1494                for (i = 0; i < c; i++) {
1495                    m = getComponent(i);
1496                    if (m instanceof  MenuElement)
1497                        tmp.addElement(m);
1498                }
1499
1500                result = new MenuElement[tmp.size()];
1501                for (i = 0, c = tmp.size(); i < c; i++)
1502                    result[i] = (MenuElement) tmp.elementAt(i);
1503                return result;
1504            }
1505
1506            /**
1507             * Returns this <code>JPopupMenu</code> component.
1508             * @return this <code>JPopupMenu</code> object
1509             * @see MenuElement#getComponent
1510             */
1511            public Component getComponent() {
1512                return this ;
1513            }
1514
1515            /**
1516             * A popup menu-specific separator.
1517             */
1518            static public class Separator extends JSeparator {
1519                public Separator() {
1520                    super (JSeparator.HORIZONTAL);
1521                }
1522
1523                /**
1524                 * Returns the name of the L&F class that renders this component.
1525                 *
1526                 * @return the string "PopupMenuSeparatorUI"
1527                 * @see JComponent#getUIClassID
1528                 * @see UIDefaults#getUI
1529                 */
1530                public String getUIClassID() {
1531                    return "PopupMenuSeparatorUI";
1532
1533                }
1534            }
1535
1536            /**
1537             * Returns true if the <code>MouseEvent</code> is considered a popup trigger
1538             * by the <code>JPopupMenu</code>'s currently installed UI.
1539             *
1540             * @return true if the mouse event is a popup trigger
1541             * @since 1.3
1542             */
1543            public boolean isPopupTrigger(MouseEvent e) {
1544                return getUI().isPopupTrigger(e);
1545            }
1546        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.