summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/JPopupMenu.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/JPopupMenu.java')
-rw-r--r--libjava/classpath/javax/swing/JPopupMenu.java947
1 files changed, 947 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JPopupMenu.java b/libjava/classpath/javax/swing/JPopupMenu.java
new file mode 100644
index 000000000..8f16aa2a7
--- /dev/null
+++ b/libjava/classpath/javax/swing/JPopupMenu.java
@@ -0,0 +1,947 @@
+/* JPopupMenu.java --
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.PopupMenuUI;
+
+/**
+ * JPopupMenu is a container that is used to display popup menu's menu
+ * items. By default JPopupMenu is a lightweight container, however if it
+ * is the case that JPopupMenu's bounds are outside of main window, then
+ * heawyweight container will be used to display menu items. It is also
+ * possible to change JPopupMenu's default behavior and set JPopupMenu
+ * to always use heavyweight container.
+ *
+ * JPopupMenu can be displayed anywhere; it is a floating free popup menu.
+ * However before JPopupMenu is diplayed, its invoker property should be set.
+ * JPopupMenu's invoker is a component relative to which popup menu is
+ * displayed.
+ *
+ * JPopupMenu fires PopupMenuEvents to its registered listeners. Whenever
+ * JPopupMenu becomes visible on the screen then PopupMenuEvent indicating
+ * that popup menu became visible will be fired. In the case when
+ * JPopupMenu becomes invisible or cancelled without selection, then
+ * popupMenuBecomeInvisible() or popupMenuCancelled() methods of
+ * PopupMenuListeners will be invoked.
+ *
+ * JPopupMenu also fires PropertyChangeEvents when its bound properties
+ * change.In addittion to inheritted bound properties, JPopupMenu has
+ * 'visible' bound property. When JPopupMenu becomes visible/invisible on
+ * the screen it fires PropertyChangeEvents to its registered
+ * PropertyChangeListeners.
+ */
+public class JPopupMenu extends JComponent implements Accessible, MenuElement
+{
+ private static final long serialVersionUID = -8336996630009646009L;
+
+ /* indicates if popup's menu border should be painted*/
+ private boolean borderPainted = true;
+
+ /** Flag indicating whether lightweight, mediumweight or heavyweight popup
+ is used to display menu items.
+
+ These are the possible cases:
+
+ 1. if DefaultLightWeightPopupEnabled true
+ (i) use lightweight container if popup feets inside top-level window
+ (ii) only use heavyweight container (JDialog) if popup doesn't fit.
+
+ 2. if DefaultLightWeightPopupEnabled false
+ (i) if popup fits, use awt.Panel (mediumWeight)
+ (ii) if popup doesn't fit, use JDialog (heavyWeight)
+ */
+ private static boolean DefaultLightWeightPopupEnabled = true;
+
+ /* Component that invokes popup menu. */
+ transient Component invoker;
+
+ /* Label for this popup menu. It is not used in most of the look and feel themes. */
+ private String label;
+
+ /*Amount of space between menuItem's in JPopupMenu and JPopupMenu's border */
+ private Insets margin;
+
+ /** Indicates whether ligthWeight container can be used to display popup
+ menu. This flag is the same as DefaultLightWeightPopupEnabled, but setting
+ this flag can change popup menu after creation of the object */
+ private boolean lightWeightPopupEnabled;
+
+ /** SelectionModel that keeps track of menu selection. */
+ protected SingleSelectionModel selectionModel;
+
+ /* Popup that is used to display JPopupMenu */
+ private transient Popup popup;
+
+ /**
+ * Location of the popup, X coordinate.
+ */
+ private int popupLocationX;
+
+ /**
+ * Location of the popup, Y coordinate.
+ */
+ private int popupLocationY;
+
+ /* Field indicating if popup menu is visible or not */
+ private boolean visible = false;
+
+ /**
+ * Creates a new JPopupMenu object.
+ */
+ public JPopupMenu()
+ {
+ this(null);
+ }
+
+ /**
+ * Creates a new JPopupMenu with specified label
+ *
+ * @param label Label for popup menu.
+ */
+ public JPopupMenu(String label)
+ {
+ lightWeightPopupEnabled = getDefaultLightWeightPopupEnabled();
+ setLabel(label);
+ setSelectionModel(new DefaultSingleSelectionModel());
+ super.setVisible(false);
+ updateUI();
+ }
+
+ /**
+ * Adds given menu item to the popup menu
+ *
+ * @param item menu item to add to the popup menu
+ *
+ * @return menu item that was added to the popup menu
+ */
+ public JMenuItem add(JMenuItem item)
+ {
+ this.insert(item, -1);
+ return item;
+ }
+
+ /**
+ * Constructs menu item with a specified label and adds it to
+ * popup menu
+ *
+ * @param text label for the menu item to be added
+ *
+ * @return constructed menu item that was added to the popup menu
+ */
+ public JMenuItem add(String text)
+ {
+ JMenuItem item = new JMenuItem(text);
+ return add(item);
+ }
+
+ /**
+ * Constructs menu item associated with the specified action
+ * and adds it to the popup menu
+ *
+ * @param action Action for the new menu item
+ *
+ * @return menu item that was added to the menu
+ */
+ public JMenuItem add(Action action)
+ {
+ JMenuItem item = createActionComponent(action);
+
+ if (action != null)
+ action.addPropertyChangeListener(createActionChangeListener(item));
+
+ return add(item);
+ }
+
+ /**
+ * Revomes component at the given index from the menu.
+ *
+ * @param index index of the component that will be removed in the menu
+ */
+ public void remove(int index)
+ {
+ super.remove(index);
+ revalidate();
+ }
+
+ /**
+ * Create menu item associated with the given action
+ * and inserts it into the popup menu at the specified index
+ *
+ * @param action Action for the new menu item
+ * @param index index in the popup menu at which to insert new menu item.
+ */
+ public void insert(Action action, int index)
+ {
+ JMenuItem item = new JMenuItem(action);
+ this.insert(item, index);
+ }
+
+ /**
+ * Insert given component to the popup menu at the
+ * specified index
+ *
+ * @param component Component to insert
+ * @param index Index at which to insert given component
+ */
+ public void insert(Component component, int index)
+ {
+ super.add(component, index);
+ }
+
+ /**
+ * Returns flag indicating if newly created JPopupMenu will use
+ * heavyweight or lightweight container to display its menu items
+ *
+ * @return true if JPopupMenu will use lightweight container to display
+ * menu items by default, and false otherwise.
+ */
+ public static boolean getDefaultLightWeightPopupEnabled()
+ {
+ return DefaultLightWeightPopupEnabled;
+ }
+
+ /**
+ * Sets whether JPopupMenu should use ligthWeight container to
+ * display it menu items by default
+ *
+ * @param enabled true if JPopupMenu should use lightweight container
+ * for displaying its menu items, and false otherwise.
+ */
+ public static void setDefaultLightWeightPopupEnabled(boolean enabled)
+ {
+ DefaultLightWeightPopupEnabled = enabled;
+ }
+
+ /**
+ * This method returns the UI used to display the JPopupMenu.
+ *
+ * @return The UI used to display the JPopupMenu.
+ */
+ public PopupMenuUI getUI()
+ {
+ return (PopupMenuUI) ui;
+ }
+
+ /**
+ * Set the "UI" property of the menu item, which is a look and feel class
+ * responsible for handling popupMenu's input events and painting it.
+ *
+ * @param ui The new "UI" property
+ */
+ public void setUI(PopupMenuUI ui)
+ {
+ super.setUI(ui);
+ }
+
+ /**
+ * This method sets this menuItem's UI to the UIManager's default for the
+ * current look and feel.
+ */
+ public void updateUI()
+ {
+ setUI((PopupMenuUI) UIManager.getUI(this));
+ }
+
+ /**
+ * This method returns a name to identify which look and feel class will be
+ * the UI delegate for the menuItem.
+ *
+ * @return The Look and Feel classID. "PopupMenuUI"
+ */
+ public String getUIClassID()
+ {
+ return "PopupMenuUI";
+ }
+
+ /**
+ * Returns selectionModel used by this popup menu to keep
+ * track of the selection.
+ *
+ * @return popup menu's selection model
+ */
+ public SingleSelectionModel getSelectionModel()
+ {
+ return selectionModel;
+ }
+
+ /**
+ * Sets selection model for this popup menu
+ *
+ * @param model new selection model of this popup menu
+ */
+ public void setSelectionModel(SingleSelectionModel model)
+ {
+ selectionModel = model;
+ }
+
+ /**
+ * Creates new menu item associated with a given action.
+ *
+ * @param action Action used to create new menu item
+ *
+ * @return new created menu item associated with a given action.
+ */
+ protected JMenuItem createActionComponent(Action action)
+ {
+ return new JMenuItem(action);
+ }
+
+ /**
+ * Creates PropertyChangeListener that listens to PropertyChangeEvents
+ * occuring in the Action associated with given menu item in this popup menu.
+ *
+ * @param item MenuItem
+ *
+ * @return The PropertyChangeListener
+ */
+ protected PropertyChangeListener createActionChangeListener(JMenuItem item)
+ {
+ return new ActionChangeListener();
+ }
+
+ /**
+ * Returns true if this popup menu will display its menu item in
+ * a lightweight container and false otherwise.
+ *
+ * @return true if this popup menu will display its menu items
+ * in a lightweight container and false otherwise.
+ */
+ public boolean isLightWeightPopupEnabled()
+ {
+ return lightWeightPopupEnabled;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param enabled DOCUMENT ME!
+ */
+ public void setLightWeightPopupEnabled(boolean enabled)
+ {
+ lightWeightPopupEnabled = enabled;
+ }
+
+ /**
+ * Returns label for this popup menu
+ *
+ * @return label for this popup menu
+ */
+ public String getLabel()
+ {
+ return label;
+ }
+
+ /**
+ * Sets label for this popup menu. This method fires PropertyChangeEvent
+ * when the label property is changed. Please note that most
+ * of the Look & Feel will ignore this property.
+ *
+ * @param label label for this popup menu
+ */
+ public void setLabel(String label)
+ {
+ if (label != this.label)
+ {
+ String oldLabel = this.label;
+ this.label = label;
+ firePropertyChange("label", oldLabel, label);
+ }
+ }
+
+ /**
+ * Adds separator to this popup menu
+ */
+ public void addSeparator()
+ {
+ // insert separator at the end of the list of menu items
+ this.insert(new Separator(), -1);
+ }
+
+ /**
+ * Adds a MenuKeyListener to the popup.
+ *
+ * @param l - the listener to add.
+ */
+ public void addMenuKeyListener(MenuKeyListener l)
+ {
+ listenerList.add(MenuKeyListener.class, l);
+ }
+
+ /**
+ * Removes a MenuKeyListener from the popup.
+ *
+ * @param l - the listener to remove.
+ */
+ public void removeMenuKeyListener(MenuKeyListener l)
+ {
+ listenerList.remove(MenuKeyListener.class, l);
+ }
+
+ /**
+ * Returns array of getMenuKeyListeners that are listening to JPopupMenu.
+ *
+ * @return array of getMenuKeyListeners that are listening to JPopupMenu
+ */
+ public MenuKeyListener[] getMenuKeyListeners()
+ {
+ return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class));
+ }
+
+ /**
+ * Adds popupMenuListener to listen for PopupMenuEvents fired
+ * by the JPopupMenu
+ *
+ * @param listener PopupMenuListener to add to JPopupMenu
+ */
+ public void addPopupMenuListener(PopupMenuListener listener)
+ {
+ listenerList.add(PopupMenuListener.class, listener);
+ }
+
+ /**
+ * Removes PopupMenuListener from JPopupMenu's list of listeners
+ *
+ * @param listener PopupMenuListener which needs to be removed
+ */
+ public void removePopupMenuListener(PopupMenuListener listener)
+ {
+ listenerList.remove(PopupMenuListener.class, listener);
+ }
+
+ /**
+ * Returns array of PopupMenuListeners that are listening to JPopupMenu
+ *
+ * @return Array of PopupMenuListeners that are listening to JPopupMenu
+ */
+ public PopupMenuListener[] getPopupMenuListeners()
+ {
+ return ((PopupMenuListener[]) listenerList.getListeners(PopupMenuListener.class));
+ }
+
+ /**
+ * This method calls popupMenuWillBecomeVisible() of popup menu's
+ * PopupMenuListeners. This method is invoked just before popup menu
+ * will appear on the screen.
+ */
+ protected void firePopupMenuWillBecomeVisible()
+ {
+ EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+ for (int i = 0; i < ll.length; i++)
+ ((PopupMenuListener) ll[i]).popupMenuWillBecomeVisible(new PopupMenuEvent(this));
+ }
+
+ /**
+ * This method calls popupMenuWillBecomeInvisible() of popup
+ * menu's PopupMenuListeners. This method is invoked just before popup
+ * menu will disappear from the screen
+ */
+ protected void firePopupMenuWillBecomeInvisible()
+ {
+ EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+ for (int i = 0; i < ll.length; i++)
+ ((PopupMenuListener) ll[i]).popupMenuWillBecomeInvisible(new PopupMenuEvent(this));
+ }
+
+ /**
+ * This method calls popupMenuCanceled() of popup menu's PopupMenuListeners.
+ * This method is invoked just before popup menu is cancelled. This happens
+ * when popup menu is closed without selecting any of its menu items. This
+ * usually happens when the top-level window is resized or moved.
+ */
+ protected void firePopupMenuCanceled()
+ {
+ EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+ for (int i = 0; i < ll.length; i++)
+ ((PopupMenuListener) ll[i]).popupMenuCanceled(new PopupMenuEvent(this));
+ }
+
+ /**
+ * This methods sets popup menu's size to its' preferred size. If the
+ * popup menu's size is previously set it will be ignored.
+ */
+ public void pack()
+ {
+ // Hook up this call so that it gets executed on the event thread in order
+ // to avoid synchronization problems when calling the layout manager.
+ if (! SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ show();
+ }
+ });
+ }
+
+ setSize(getPreferredSize());
+ }
+
+ /**
+ * Return visibility of the popup menu
+ *
+ * @return true if popup menu is visible on the screen and false otherwise.
+ */
+ public boolean isVisible()
+ {
+ return visible;
+ }
+
+ /**
+ * Sets visibility property of this popup menu. If the property is
+ * set to true then popup menu will be dispayed and popup menu will
+ * hide itself if visible property is set to false.
+ *
+ * @param visible true if popup menu will become visible and false otherwise.
+ */
+ public void setVisible(final boolean visible)
+ {
+ // Hook up this call so that it gets executed on the event thread in order
+ // to avoid synchronization problems when calling the layout manager.
+ if (! SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ setVisible(visible);
+ }
+ });
+ }
+
+ if (visible == isVisible())
+ return;
+
+ boolean old = isVisible();
+ this.visible = visible;
+ if (old != isVisible())
+ {
+ if (visible)
+ {
+ if (invoker != null && !(invoker instanceof JMenu))
+ {
+ MenuElement[] menuEls;
+ if (getSubElements().length > 0)
+ {
+ menuEls = new MenuElement[2];
+ menuEls[0] = this;
+ menuEls[1] = getSubElements()[0];
+ }
+ else
+ {
+ menuEls = new MenuElement[1];
+ menuEls[0] = this;
+ }
+ MenuSelectionManager.defaultManager().setSelectedPath(menuEls);
+ }
+ firePopupMenuWillBecomeVisible();
+ PopupFactory pf = PopupFactory.getSharedInstance();
+ pack();
+ popup = pf.getPopup(invoker, this, popupLocationX, popupLocationY);
+ popup.show();
+ }
+ else
+ {
+ getSelectionModel().clearSelection();
+ firePopupMenuWillBecomeInvisible();
+ popup.hide();
+ }
+ firePropertyChange("visible", old, isVisible());
+ }
+ }
+
+ /**
+ * Sets location of the popup menu.
+ *
+ * @param x X coordinate of the popup menu's location
+ * @param y Y coordinate of the popup menu's location
+ */
+ public void setLocation(int x, int y)
+ {
+ popupLocationX = x;
+ popupLocationY = y;
+ // Handle the case when the popup is already showing. In this case we need
+ // to fetch a new popup from PopupFactory and use this. See the general
+ // contract of the PopupFactory.
+ }
+
+ /**
+ * Returns popup menu's invoker.
+ *
+ * @return popup menu's invoker
+ */
+ public Component getInvoker()
+ {
+ return invoker;
+ }
+
+ /**
+ * Sets popup menu's invoker.
+ *
+ * @param component The new invoker of this popup menu
+ */
+ public void setInvoker(Component component)
+ {
+ invoker = component;
+ }
+
+ /**
+ * This method displays JPopupMenu on the screen at the specified
+ * location. Note that x and y coordinates given to this method
+ * should be expressed in terms of the popup menus' invoker.
+ *
+ * @param component Invoker for this popup menu
+ * @param x x-coordinate of the popup menu relative to the specified invoker
+ * @param y y-coordiate of the popup menu relative to the specified invoker
+ */
+ public void show(Component component, int x, int y)
+ {
+ if (component.isShowing())
+ {
+ setInvoker(component);
+ Point p = new Point(x, y);
+ SwingUtilities.convertPointToScreen(p, component);
+ setLocation(p.x, p.y);
+ setVisible(true);
+ }
+ }
+
+ /**
+ * Returns component located at the specified index in the popup menu
+ *
+ * @param index index of the component to return
+ *
+ * @return component located at the specified index in the popup menu
+ *
+ * @deprecated Replaced by getComponent(int)
+ */
+ public Component getComponentAtIndex(int index)
+ {
+ return getComponent(index);
+ }
+
+ /**
+ * Returns index of the specified component in the popup menu
+ *
+ * @param component Component to look for
+ *
+ * @return index of the specified component in the popup menu
+ */
+ public int getComponentIndex(Component component)
+ {
+ Component[] items = getComponents();
+
+ for (int i = 0; i < items.length; i++)
+ {
+ if (items[i].equals(component))
+ return i;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Sets size of the popup
+ *
+ * @param size Dimensions representing new size of the popup menu
+ */
+ public void setPopupSize(Dimension size)
+ {
+ super.setSize(size);
+ }
+
+ /**
+ * Sets size of the popup menu
+ *
+ * @param width width for the new size
+ * @param height height for the new size
+ */
+ public void setPopupSize(int width, int height)
+ {
+ super.setSize(width, height);
+ }
+
+ /**
+ * Selects specified component in this popup menu.
+ *
+ * @param selected component to select
+ */
+ public void setSelected(Component selected)
+ {
+ int index = getComponentIndex(selected);
+ selectionModel.setSelectedIndex(index);
+ }
+
+ /**
+ * Checks if this popup menu paints its border.
+ *
+ * @return true if this popup menu paints its border and false otherwise.
+ */
+ public boolean isBorderPainted()
+ {
+ return borderPainted;
+ }
+
+ /**
+ * Sets if the border of the popup menu should be
+ * painter or not.
+ *
+ * @param painted true if the border should be painted and false otherwise
+ */
+ public void setBorderPainted(boolean painted)
+ {
+ borderPainted = painted;
+ }
+
+ /**
+ * Returns margin for this popup menu.
+ *
+ * @return margin for this popup menu.
+ */
+ public Insets getMargin()
+ {
+ return margin;
+ }
+
+ /**
+ * A string that describes this JPopupMenu. Normally only used
+ * for debugging.
+ *
+ * @return A string describing this JMenuItem
+ */
+ protected String paramString()
+ {
+ CPStringBuilder sb = new CPStringBuilder();
+ sb.append(super.paramString());
+ sb.append(",label=");
+ if (getLabel() != null)
+ sb.append(getLabel());
+ sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
+ sb.append(",margin=");
+ if (getMargin() != null)
+ sb.append(margin);
+ sb.append(",paintBorder=").append(isBorderPainted());
+ return sb.toString();
+ }
+
+ /**
+ * Process mouse events forwarded from MenuSelectionManager. This method
+ * doesn't do anything. It is here to conform to the MenuElement interface.
+ *
+ * @param event event forwarded from MenuSelectionManager
+ * @param path path to the menu element from which event was generated
+ * @param manager MenuSelectionManager for the current menu hierarchy
+ */
+ public void processMouseEvent(MouseEvent event, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ // Empty Implementation. This method is needed for the implementation
+ // of MenuElement interface
+ }
+
+ /**
+ * Process key events forwarded from MenuSelectionManager. This method
+ * doesn't do anything. It is here to conform to the MenuElement interface.
+ *
+ * @param event event forwarded from MenuSelectionManager
+ * @param path path to the menu element from which event was generated
+ * @param manager MenuSelectionManager for the current menu hierarchy
+ *
+ */
+ public void processKeyEvent(KeyEvent event, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ // Empty Implementation. This method is needed for the implementation
+ // of MenuElement interface
+ }
+
+ /**
+ * Method of MenuElement Interface. It is invoked when
+ * popupMenu's selection has changed
+ *
+ * @param changed true if this popupMenu is part of current menu
+ * hierarchy and false otherwise.
+ */
+ public void menuSelectionChanged(boolean changed)
+ {
+ if (invoker instanceof JMenu)
+ {
+ // We need to special case this since the JMenu calculates the
+ // position etc of the popup.
+ JMenu menu = (JMenu) invoker;
+ menu.setPopupMenuVisible(changed);
+ }
+ else if (! changed)
+ setVisible(false);
+ }
+
+ /**
+ * Return subcomonents of this popup menu. This method returns only
+ * components that implement the <code>MenuElement</code> interface.
+ *
+ * @return array of menu items belonging to this popup menu
+ */
+ public MenuElement[] getSubElements()
+ {
+ Component[] items = getComponents();
+ ArrayList subElements = new ArrayList();
+
+ for (int i = 0; i < items.length; i++)
+ if (items[i] instanceof MenuElement)
+ subElements.add(items[i]);
+
+ return (MenuElement[])
+ subElements.toArray(new MenuElement[subElements.size()]);
+ }
+
+ /**
+ * Method of the MenuElement interface. Returns reference to itself.
+ *
+ * @return Returns reference to itself
+ */
+ public Component getComponent()
+ {
+ return this;
+ }
+
+ /**
+ * Checks if observing mouse event should trigger popup
+ * menu to show on the screen.
+ *
+ * @param event MouseEvent to check
+ *
+ * @return true if the observing mouse event is popup trigger and false otherwise
+ */
+ public boolean isPopupTrigger(MouseEvent event)
+ {
+ return ((PopupMenuUI) getUI()).isPopupTrigger(event);
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJPopupMenu();
+
+ return accessibleContext;
+ }
+
+ /**
+ * This is the separator that can be used in popup menu.
+ */
+ public static class Separator extends JSeparator
+ {
+ public Separator()
+ {
+ super();
+ }
+
+ public String getUIClassID()
+ {
+ return "PopupMenuSeparatorUI";
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the component is guaranteed to be painted
+ * on top of others. This returns false by default and is overridden by
+ * components like JMenuItem, JPopupMenu and JToolTip to return true for
+ * added efficiency.
+ *
+ * @return <code>true</code> if the component is guaranteed to be painted
+ * on top of others
+ */
+ boolean onTop()
+ {
+ return true;
+ }
+
+ protected class AccessibleJPopupMenu extends AccessibleJComponent
+ {
+ private static final long serialVersionUID = 7423261328879849768L;
+
+ protected AccessibleJPopupMenu()
+ {
+ // Nothing to do here.
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.POPUP_MENU;
+ }
+ }
+
+ /* This class resizes popup menu and repaints popup menu appropriately if one
+ of item's action has changed */
+ private class ActionChangeListener implements PropertyChangeListener
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // We used to have a revalidate() and repaint() call here. However I think
+ // this is not needed. Instead, a new Popup has to be fetched from the
+ // PopupFactory and used here.
+ }
+ }
+}