[gui][PATCH] More fixes and implementation for menu components

Olga Rodimina rodimina@redhat.com
Wed Jun 30 19:32:00 GMT 2004


Hi, 

Here is the patch that implements - 
	
	BasicPopupMenuUI.PopupMenuHandler
	BasicPopupMenuUI.TopWindowListener
	BasicPopupMenuUI.ActionChangeListener
	BasicMenuBarUI.ContainerHandler

It also adds javadocs to BasicPopupMenuUI and makes other
various fixes to AbstractButton and other menu related widgets.

I'll be committing it to java-gui-branch.

Olga
-------------- next part --------------
? .snprj
? libjava.proj
? package-list
? patch
? resources
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libjava/ChangeLog,v
retrieving revision 1.2660.2.235
diff -c -p -u -r1.2660.2.235 ChangeLog
--- ChangeLog	29 Jun 2004 11:30:44 -0000	1.2660.2.235
+++ ChangeLog	30 Jun 2004 16:26:24 -0000
@@ -1,3 +1,46 @@
+2004-06-30  Olga Rodimina  <rodimina@redhat.com>
+
+	*  javax/swing/AbstractButton.java: 
+	(configurePropertiesFromAction): Set action command
+	to button's text by default if action command is not 
+	explicitely specified.
+	* javax/swing/JMenu.java: Remove unnecessary listener
+	and methods relevant to it.
+	(setSelected): Reimplemented.
+	(menuSelectionChanged): Moved most part of implementation to
+	setSelected() and call it instead.
+	* javax/swing/JMenuItem.java: 
+	(init): Comment out statement that sets paint_border to false.
+	(configurePropertiesFromAction): Do not set accelerator
+	for JMenu.
+	(menuSelectionChanged): Change selected index in the selection
+	model of menu item's parent.
+	* javax/swing/JPopupMenu.java:
+	(remove): Set constraints.fill field to GridBagConstraints.BOTH
+	instead of GridBagConstraints.HORIZONTAL.
+	(insert): Likewise.
+	(createActionChangeListener): Implemented.
+	(setVisible): Correct location of HeavyWeightMenu and 
+	don't firePopupMenuCanceled().
+	(menuSelectionChanged): Implemented.
+	(ActionChangeListener): New Listener. Implemented.
+	* javax/swing/plaf/basic/BasicMenuBarUI.java:
+	(BasicMenuBarUI.ContainerHandler): Implemented.
+	* javax/swing/plaf/basic/BasicMenuItemUI.java:
+	(paintMenuItem): Uncommented out code that paints 
+	icon, now that icons are working properly.
+	(PropertyChangeListener): Implemented.
+	* javax/swing/plaf/basic/BasicPopupMenuUI.java:
+	Added javadocs.
+	(topWindowListener): New field.
+	(Constructor): initialize topWindowListener.
+	(BasicPopupMenuUI.TopWindowListener): Implemented.	
+	(BasicPopupMenuUI.PopupMenuHandler): Implemented.
+	(BasicPopupMenuUI.TopWindowListener): New ComponentListener.
+	Implemented.
+	
+	
+
 2004-06-29  Michael Koch  <konqueror@gmx.de>
 
 	* javax/swing/JFormattedTextField.java
Index: javax/swing/AbstractButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractButton.java,v
retrieving revision 1.5.2.10
diff -c -p -u -r1.5.2.10 AbstractButton.java
--- javax/swing/AbstractButton.java	22 Jun 2004 17:03:44 -0000	1.5.2.10
+++ javax/swing/AbstractButton.java	30 Jun 2004 16:26:25 -0000
@@ -1403,7 +1403,13 @@ public abstract class AbstractButton ext
         setToolTipText((String)(a.getValue(Action.SHORT_DESCRIPTION)));
 	if (a.getValue(Action.MNEMONIC_KEY) != null)
           setMnemonic(((Integer)(a.getValue(Action.MNEMONIC_KEY))).intValue());
-        setActionCommand((String)(a.getValue(Action.ACTION_COMMAND_KEY)));
+        String actionCommand = (String)(a.getValue(Action.ACTION_COMMAND_KEY));
+
+        // Set actionCommand to button's text by default if it is not specified
+        if (actionCommand != null)
+	   setActionCommand((String)(a.getValue(Action.ACTION_COMMAND_KEY)));
+	 else
+	   setActionCommand(getText());
       }
   }
 
Index: javax/swing/JMenu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenu.java,v
retrieving revision 1.3.8.8
diff -c -p -u -r1.3.8.8 JMenu.java
--- javax/swing/JMenu.java	17 Jun 2004 18:18:38 -0000	1.3.8.8
+++ javax/swing/JMenu.java	30 Jun 2004 16:26:25 -0000
@@ -76,9 +76,6 @@ public class JMenu extends JMenuItem imp
   /** A Popup menu associated with this menu, which pops up when menu is selected */
   private JPopupMenu popupMenu = new JPopupMenu();
 
-  /** MenuChangeListener that listens to change events occuring in menu's model */
-  private ChangeListener menuChangeListener;
-
   /** MenuEvent */
   private MenuEvent menuEvent = new MenuEvent(this);
 
@@ -98,8 +95,6 @@ public class JMenu extends JMenuItem imp
   public JMenu()
   {
     super();
-    menuChangeListener = createMenuChangeListener();
-    getModel().addChangeListener(menuChangeListener);
   }
 
   /**
@@ -110,8 +105,6 @@ public class JMenu extends JMenuItem imp
   public JMenu(String text)
   {
     super(text);
-    menuChangeListener = createMenuChangeListener();
-    getModel().addChangeListener(menuChangeListener);
   }
 
   /**
@@ -123,8 +116,7 @@ public class JMenu extends JMenuItem imp
   public JMenu(Action action)
   {
     super(action);
-    menuChangeListener = createMenuChangeListener();
-    getModel().addChangeListener(menuChangeListener);
+    createActionChangeListener(this);
   }
 
   /**
@@ -341,8 +333,38 @@ public class JMenu extends JMenuItem imp
    */
   public void setSelected(boolean selected)
   {
-    super.setArmed(true);
-    fireMenuSelected();
+    // if this menu selection is true, then activate this menu and 
+    // display popup associated with this menu	
+    if (selected)
+      {
+	super.setArmed(true);
+	super.setSelected(true);
+	fireMenuSelected();
+
+	int x = 0;
+	int y = 0;
+	if (menuLocation == null)
+	  {
+	    // Calculate correct position of the popup. Note that location of the popup 
+	    // passed to show() should be relative to the popup's invoker
+	    if (isTopLevelMenu())
+	      y = this.getHeight();
+	    else
+	      x = this.getWidth();
+
+	    getPopupMenu().show(this, x, y);
+	  }
+	else
+	  getPopupMenu().show(this, menuLocation.x, menuLocation.y);
+      }
+
+    else
+      {
+	super.setSelected(false);
+	super.setArmed(false);
+	fireMenuDeselected();
+	popupMenu.setVisible(false);
+      }
   }
 
   /**
@@ -641,17 +663,6 @@ public class JMenu extends JMenuItem imp
   }
 
   /**
-   * Creates MenuChangeListener to listen to change events occuring
-   * in the model
-   *
-   * @return ChangeListener
-   */
-  private ChangeListener createMenuChangeListener()
-  {
-    return new MenuChangeListener();
-  }
-
-  /**
    * Creates WinListener that listens to the menu;s popup menu.
    *
    * @param popup JPopupMenu to listen to
@@ -675,34 +686,7 @@ public class JMenu extends JMenuItem imp
   {
     // if this menu selection is true, then activate this menu and 
     // display popup associated with this menu
-    if (changed)
-      {
-	setArmed(true);
-	fireMenuSelected();
-
-	int x = 0;
-	int y = 0;
-	if (menuLocation == null)
-	  {
-	    // Calculate correct position of the popup. Note that location of the popup 
-	    // passed to show() should be relative to the popup's invoker
-	    if (isTopLevelMenu())
-	      y = this.getHeight();
-	    else
-	      x = this.getWidth();
-
-	    getPopupMenu().show(this, x, y);
-	  }
-	else
-	  getPopupMenu().show(this, menuLocation.x, menuLocation.y);
-      }
-
-    else
-      {
-	fireMenuDeselected();
-	popupMenu.setVisible(false);
-	setArmed(false);
-      }
+    setSelected(changed);
   }
 
   /**
@@ -860,17 +844,6 @@ public class JMenu extends JMenuItem imp
     }
   }
 
-  /** This class listens to ChangeEvent fired by menu's model*/
-  protected class MenuChangeListener implements ChangeListener
-  {
-    /** This method is invoked when there is change in menu's model property */
-    public void stateChanged(ChangeEvent e)
-    {
-      revalidate();
-      repaint();
-    }
-  }
-
   /**
    * This class listens to PropertyChangeEvents occuring in menu's action
    */
Index: javax/swing/JMenuItem.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenuItem.java,v
retrieving revision 1.2.18.9
diff -c -p -u -r1.2.18.9 JMenuItem.java
--- javax/swing/JMenuItem.java	22 Jun 2004 17:03:44 -0000	1.2.18.9
+++ javax/swing/JMenuItem.java	30 Jun 2004 16:26:25 -0000
@@ -150,26 +150,11 @@ public class JMenuItem extends AbstractB
     setMnemonic(mnemonic);
   }
 
-  /**
-   * DOCUMENT ME!
-   *
-   * @param stream DOCUMENT ME!
-   *
-   * @throws IOException DOCUMENT ME!
-   * @throws ClassNotFoundException DOCUMENT ME!
-   */
   private void readObject(ObjectInputStream stream)
                    throws IOException, ClassNotFoundException
   {
   }
 
-  /**
-   * DOCUMENT ME!
-   *
-   * @param stream DOCUMENT ME!
-   *
-   * @throws IOException DOCUMENT ME!
-   */
   private void writeObject(ObjectOutputStream stream) throws IOException
   {
   }
@@ -186,7 +171,13 @@ public class JMenuItem extends AbstractB
 
     // Initializes properties for this menu item, that are different
     // from Abstract button properties. 
-    paint_border = false;
+    
+    /* NOTE: According to java specifications paint_border should be set to false,
+      since menu item should not have a border. However running few java programs
+      it seems that menu items and menues can have a border. Commenting
+      out statement below for now. */
+      
+    //paint_border = false;
     paint_focus = false;
     hori_align = JButton.LEFT;
     hori_text_pos = JButton.LEFT;
@@ -288,9 +279,7 @@ public class JMenuItem extends AbstractB
   {
     super.configurePropertiesFromAction(action);
 
-    if (action == null)
-      setAccelerator(null);
-    else
+    if (! (this instanceof JMenu) && action != null)
       setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
   }
 
@@ -537,10 +526,19 @@ public class JMenuItem extends AbstractB
    */
   public void menuSelectionChanged(boolean changed)
   {
-    if (changed)
+    if (changed) {
       model.setArmed(true);
-    else
+      
+      if (this.getParent() instanceof JPopupMenu)
+        ((JPopupMenu) this.getParent()).setSelected(this);
+    }  
+    else {
+      
       model.setArmed(false);
+      
+      if (this.getParent() instanceof JPopupMenu)
+        ((JPopupMenu) this.getParent()).getSelectionModel().clearSelection();
+    }
   }
 
   /**
Index: javax/swing/JPopupMenu.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JPopupMenu.java,v
retrieving revision 1.3.8.10
diff -c -p -u -r1.3.8.10 JPopupMenu.java
--- javax/swing/JPopupMenu.java	23 Jun 2004 08:02:30 -0000	1.3.8.10
+++ javax/swing/JPopupMenu.java	30 Jun 2004 16:26:25 -0000
@@ -169,12 +169,12 @@ public class JPopupMenu extends JCompone
   }
 
   /**
-   * 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
-   */
+  * 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);
@@ -223,7 +223,7 @@ public class JPopupMenu extends JCompone
     super.remove(index);
 
     GridBagConstraints constraints = new GridBagConstraints();
-    constraints.fill = GridBagConstraints.HORIZONTAL;
+    constraints.fill = GridBagConstraints.BOTH;
     constraints.weightx = 100.0;
     constraints.weighty = 100.0;
 
@@ -258,7 +258,7 @@ public class JPopupMenu extends JCompone
   public void insert(Component component, int index)
   {
     GridBagConstraints constraints = new GridBagConstraints();
-    constraints.fill = GridBagConstraints.HORIZONTAL;
+    constraints.fill = GridBagConstraints.BOTH;
     constraints.weightx = 100.0;
     constraints.weighty = 100.0;
 
@@ -397,15 +397,16 @@ public class JPopupMenu extends JCompone
   }
 
   /**
-   * DOCUMENT ME!
+   * Creates PropertyChangeListener that listens to PropertyChangeEvents
+   * occuring in the Action associated with given menu item in this popup menu.
    *
-   * @param item DOCUMENT ME!
+   * @param item MenuItem
    *
-   * @return DOCUMENT ME!
+   * @return The PropertyChangeListener
    */
   protected PropertyChangeListener createActionChangeListener(JMenuItem item)
   {
-    return null;
+    return new ActionChangeListener();
   }
 
   /**
@@ -602,27 +603,15 @@ public class JPopupMenu extends JCompone
 	      {
 		// Subtract insets of the top-level container if popup menu's
 		// top-left corner is inside it.
-		if (rootContainer.contains(popupLocation))
-		  {
-		    Insets insets = rootContainer.getInsets();
-		    popup.show(popupLocation.x - insets.left,
-		               popupLocation.y - insets.top, size.width,
-		               size.height);
-		  }
-
-		else
-		  popup.show(popupLocation.x, popupLocation.y, size.width,
-		             size.height);
+		Insets insets = rootContainer.getInsets();
+		popup.show(popupLocation.x - insets.left,
+		           popupLocation.y - insets.top, size.width,
+		           size.height);
 	      }
 	  }
 	else
 	  {
-	    // popup menu was cancelled without selection
-	    if (! getSelectionModel().isSelected())
-	      firePopupMenuCanceled();
-
 	    firePopupMenuWillBecomeInvisible();
-
 	    popup.hide();
 	  }
       }
@@ -822,6 +811,8 @@ public class JPopupMenu extends JCompone
    */
   public void menuSelectionChanged(boolean changed)
   {
+    if (! changed)
+      setVisible(false);
   }
 
   /**
@@ -1053,4 +1044,15 @@ public class JPopupMenu extends JCompone
       return AccessibleRole.POPUP_MENU;
     }
   }
+
+  /* This class resizes popup menu and repaints popup menu appropriately if one
+   of item's action has changed */
+  protected class ActionChangeListener implements PropertyChangeListener
+  {
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      JPopupMenu.this.revalidate();
+      JPopupMenu.this.repaint();
+    }
+  }
 }
Index: javax/swing/plaf/basic/BasicMenuBarUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicMenuBarUI.java,v
retrieving revision 1.1.2.4
diff -c -p -u -r1.1.2.4 BasicMenuBarUI.java
--- javax/swing/plaf/basic/BasicMenuBarUI.java	18 Jun 2004 20:57:09 -0000	1.1.2.4
+++ javax/swing/plaf/basic/BasicMenuBarUI.java	30 Jun 2004 16:26:25 -0000
@@ -284,15 +284,19 @@ public class BasicMenuBarUI extends Menu
      */
     public void componentAdded(ContainerEvent e)
     {
+      menuBar.revalidate();
+      menuBar.repaint();
     }
 
     /**
-     * This method is called whenever menu is removed from the menu bar
+     * This method is called whenever menu is removed from the menu bar.
      *
      * @param e The ContainerEvent.
      */
     public void componentRemoved(ContainerEvent e)
     {
+      menuBar.revalidate();
+      menuBar.repaint();
     }
   }
 
Index: javax/swing/plaf/basic/BasicMenuItemUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java,v
retrieving revision 1.1.2.13
diff -c -p -u -r1.1.2.13 BasicMenuItemUI.java
--- javax/swing/plaf/basic/BasicMenuItemUI.java	21 Jun 2004 20:26:25 -0000	1.1.2.13
+++ javax/swing/plaf/basic/BasicMenuItemUI.java	30 Jun 2004 16:26:25 -0000
@@ -570,15 +570,14 @@ public class BasicMenuItemUI extends Men
     // FIXME: should paint different icon at different button state's.
     // i.e disabled icon when button is disabled.. etc.
 
-    /*
+    
     Icon i = m.getIcon();
     if (i != null)
       {
          int x = ir.x;
          int y = ir.y;
          i.paintIcon(c, g, x, y);
-      }
-    */
+      }    
 
     // paint accelerator    
     String acceleratorText = "";
@@ -990,6 +989,8 @@ public class BasicMenuItemUI extends Men
      */
     public void propertyChange(PropertyChangeEvent evt)
     {
+	menuItem.revalidate();
+	menuItem.repaint();
     }
   }
 }
Index: javax/swing/plaf/basic/BasicPopupMenuUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicPopupMenuUI.java,v
retrieving revision 1.1.2.2
diff -c -p -u -r1.1.2.2 BasicPopupMenuUI.java
--- javax/swing/plaf/basic/BasicPopupMenuUI.java	3 Jun 2004 14:21:53 -0000	1.1.2.2
+++ javax/swing/plaf/basic/BasicPopupMenuUI.java	30 Jun 2004 16:26:25 -0000
@@ -40,6 +40,8 @@ package javax.swing.plaf.basic;
 import java.awt.AWTKeyStroke;
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
@@ -49,6 +51,8 @@ import java.awt.GridBagLayout;
 import java.awt.Insets;
 import java.awt.Rectangle;
 import java.awt.Stroke;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
 import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
@@ -88,14 +92,22 @@ import javax.swing.plaf.PopupMenuUI;
 
 
 /**
- * DOCUMENT ME!
+ * UI Delegate for JPopupMenu
  */
 public class BasicPopupMenuUI extends PopupMenuUI
 {
+  /* popupMenu for which this UI delegate is for*/
   protected JPopupMenu popupMenu;
+
+  /* MouseInputListener listens to mouse events */
   private static transient MouseInputListener mouseInputListener;
+
+  /* PopupMenuListener listens to popup menu events fired by JPopupMenu*/
   private transient PopupMenuListener popupMenuListener;
 
+  /* ComponentListener listening to popupMenu's invoker. */
+  private TopWindowListener topWindowListener;
+
   /**
    * Creates a new BasicPopupMenuUI object.
    */
@@ -103,14 +115,16 @@ public class BasicPopupMenuUI extends Po
   {
     popupMenuListener = new PopupMenuHandler();
     mouseInputListener = new MouseInputHandler();
+    topWindowListener = new TopWindowListener();
   }
 
   /**
-   * DOCUMENT ME!
+   * Factory method to create a BasicPopupMenuUI for the given {@link
+   * JComponent}, which should be a {@link JMenuItem}.
    *
-   * @param x DOCUMENT ME!
+   * @param x The {@link JComponent} a UI is being created for.
    *
-   * @return DOCUMENT ME!
+   * @return A BasicPopupMenuUI for the {@link JComponent}.
    */
   public static ComponentUI createUI(JComponent x)
   {
@@ -118,9 +132,11 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * Installs and initializes all fields for this UI delegate. Any properties
+   * of the UI that need to be initialized and/or set to defaults will be
+   * done now. It will also install any listeners necessary.
    *
-   * @param c DOCUMENT ME!
+   * @param c The {@link JComponent} that is having this UI installed.
    */
   public void installUI(JComponent c)
   {
@@ -135,7 +151,8 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This method installs the defaults that are defined in  the Basic look and
+   * feel for this {@link JPopupMenu}.
    */
   public void installDefaults()
   {
@@ -148,7 +165,7 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This method installs the listeners for the {@link JMenuItem}.
    */
   protected void installListeners()
   {
@@ -158,16 +175,19 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This method installs the keyboard actions for this {@link JPopupMenu}.
    */
   protected void installKeyboardActions()
   {
+    // FIXME: Need to implement
   }
 
   /**
-   * DOCUMENT ME!
+   * Performs the opposite of installUI. Any properties or resources that need
+   * to be cleaned up will be done now. It will also uninstall any listeners
+   * it has. In addition, any properties of this UI will be nulled.
    *
-   * @param c DOCUMENT ME!
+   * @param c The {@link JComponent} that is having this UI uninstalled.
    */
   public void uninstallUI(JComponent c)
   {
@@ -177,7 +197,8 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This method uninstalls the defaults and sets any objects created during
+   * install to null
    */
   protected void uninstallDefaults()
   {
@@ -188,37 +209,38 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * Unregisters all the listeners that this UI delegate was using.
    */
   protected void uninstallListeners()
   {
   }
 
   /**
-   * DOCUMENT ME!
+   * Uninstalls any keyboard actions.
    */
   protected void uninstallKeyboardActions()
   {
+    // FIXME: Need to implement
   }
 
   /**
-   * DOCUMENT ME!
-   *
-   * @param c DOCUMENT ME!
-   *
-   * @return DOCUMENT ME!
-   */
+  * This method returns the minimum size of the JPopupMenu.
+  *
+  * @param c The JComponent to find a size for.
+  *
+  * @return The minimum size.
+  */
   public Dimension getMinimumSize(JComponent c)
   {
     return null;
   }
 
   /**
-   * DOCUMENT ME!
+   * This method returns the preferred size of the JPopupMenu.
    *
-   * @param c DOCUMENT ME!
+   * @param c The JComponent to find a size for.
    *
-   * @return DOCUMENT ME!
+   * @return The preferred size.
    */
   public Dimension getPreferredSize(JComponent c)
   {
@@ -226,11 +248,11 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This method returns the minimum size of the JPopupMenu.
    *
-   * @param c DOCUMENT ME!
+   * @param c The JComponent to find a size for.
    *
-   * @return DOCUMENT ME!
+   * @return The minimum size.
    */
   public Dimension getMaximumSize(JComponent c)
   {
@@ -250,42 +272,113 @@ public class BasicPopupMenuUI extends Po
   }
 
   /**
-   * DOCUMENT ME!
+   * This listener handles PopupMenuEvents fired by JPopupMenu
    */
-  protected class PopupMenuHandler implements PopupMenuListener
+  private class PopupMenuHandler implements PopupMenuListener
   {
     /**
-     * DOCUMENT ME!
+     * This method is invoked when JPopupMenu is cancelled
      *
-     * @param event DOCUMENT ME!
+     * @param event the PopupMenuEvent
      */
     public void popupMenuCanceled(PopupMenuEvent event)
     {
+      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+
+      if (manager.getSelectedPath().length != 0)
+	manager.clearSelectedPath();
+      else
+	popupMenu.setVisible(false);
     }
 
     /**
-     * DOCUMENT ME!
+     * This method is invoked when JPopupMenu becomes invisible
      *
-     * @param event DOCUMENT ME!
+     * @param event the PopupMenuEvent
      */
     public void popupMenuWillBecomeInvisible(PopupMenuEvent event)
     {
+      // remove listener that listens to component events fired 
+      // by the top - level window that this popup belongs to
+      Component invoker = popupMenu.getInvoker();
+      Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
+      rootContainer.removeComponentListener(topWindowListener);
     }
 
     /**
-     * DOCUMENT ME!
+     * This method is invoked when JPopupMenu becomes visible
      *
-     * @param event DOCUMENT ME!
+     * @param event the PopupMenuEvent
      */
     public void popupMenuWillBecomeVisible(PopupMenuEvent event)
     {
+      // Adds topWindowListener to top-level window to listener to 
+      // ComponentEvents fired by it.
+      Component invoker = popupMenu.getInvoker();
+      Container rootContainer = (Container) SwingUtilities.getRoot(invoker);
+      rootContainer.addComponentListener(topWindowListener);
+    }
+  }
+
+  /**
+   * ComponentListener that listens to Component Events fired by the
+   * top - level window to which popup menu belongs. If top-level
+   * window was resized, moved or hidded then popup menu will
+   * be hidded and selected path of current menu hierarchy will be set
+   * to null.
+   *
+   */
+  private class TopWindowListener implements ComponentListener
+  {
+    /**
+     * This method is invoked when top-level window is resized.
+     * This method closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentResized(ComponentEvent e)
+    {
+      popupMenu.firePopupMenuCanceled();
+    }
+
+    /**
+     * This method is invoked when top-level window is moved.
+     * This method closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentMoved(ComponentEvent e)
+    {
+      popupMenu.firePopupMenuCanceled();
+    }
+
+    /**
+     * This method is invoked when top-level window is shown
+     * This method does nothing by default.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentShown(ComponentEvent e)
+    {
+      popupMenu.firePopupMenuCanceled();
+    }
+
+    /**
+     * This method is invoked when top-level window is hidden
+     * This method closes current menu hierarchy.
+     *
+     * @param e The ComponentEvent
+     */
+    public void componentHidden(ComponentEvent e)
+    {
+      popupMenu.firePopupMenuCanceled();
     }
   }
 
   /**
    * DOCUMENT ME!
    */
-  protected class MouseInputHandler implements MouseInputListener
+  private class MouseInputHandler implements MouseInputListener
   {
     /**
      * DOCUMENT ME!


More information about the Java-patches mailing list