This adds support for firing menu events in JMenu. This makes jircii really usable now. Get away with XChat and use jIRCii with Classpath now! ;-)

2006-08-13  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JMenu.java
        (MenuChangeListener): New inner class, helps firing menu events.
        (changeListener): New field.
        (add(text)): Create new JMenuItem here and call add(JMenuItem).
        (add(Action)): Create Action using createActionComponent()
        and add via add(Component).
        (setModel): Install and uninstall MenuChangeListener here.


/Roman
Index: javax/swing/JMenu.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JMenu.java,v
retrieving revision 1.30
diff -u -1 -2 -r1.30 JMenu.java
--- javax/swing/JMenu.java	2 Aug 2006 23:05:59 -0000	1.30
+++ javax/swing/JMenu.java	13 Aug 2006 00:54:06 -0000
@@ -44,63 +44,102 @@
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.EventListener;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleSelection;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 import javax.swing.plaf.MenuItemUI;
 
 /**
  * This class represents a menu that can be added to a menu bar or
  * can be a submenu in some other menu. When JMenu is selected it
  * displays JPopupMenu containing its menu items.
  *
  * <p>
  * JMenu's fires MenuEvents when this menu's selection changes. If this menu
  * is selected, then fireMenuSelectedEvent() is invoked. In case when menu is
  * deselected or cancelled, then fireMenuDeselectedEvent() or 
  * fireMenuCancelledEvent() is invoked, respectivelly.
  * </p>
  */
 public class JMenu extends JMenuItem implements Accessible, MenuElement
 {
+  /**
+   * Receives notifications when the JMenu's ButtonModel is changed and
+   * fires menuSelected or menuDeselected events when appropriate.
+   */
+  private class MenuChangeListener
+    implements ChangeListener
+  {
+    /**
+     * Indicates the last selected state.
+     */
+    private boolean selected;
+
+    /**
+     * Receives notification when the JMenu's ButtonModel changes.
+     */
+    public void stateChanged(ChangeEvent ev)
+    {
+      ButtonModel m = (ButtonModel) ev.getSource();
+      boolean s = m.isSelected();
+      if (s != selected)
+        {
+          if (s)
+            fireMenuSelected();
+          else
+            fireMenuDeselected();
+          selected = s;
+        }
+    }
+  }
+
   private static final long serialVersionUID = 4227225638931828014L;
 
   /** A Popup menu associated with this menu, which pops up when menu is selected */
   private JPopupMenu popupMenu = null;
 
   /** Whenever menu is selected or deselected the MenuEvent is fired to
      menu's registered listeners. */
   private MenuEvent menuEvent = new MenuEvent(this);
 
   /*Amount of time, in milliseconds, that should pass before popupMenu
     associated with this menu appears or disappers */
   private int delay;
 
   /* PopupListener */
   protected WinListener popupListener;
 
   /** Location at which popup menu associated with this menu will be
      displayed */
   private Point menuLocation;
 
   /**
+   * The ChangeListener for the ButtonModel.
+   *
+   * @see MenuChangeListener
+   */
+  private ChangeListener changeListener;
+
+  /**
    * Creates a new JMenu object.
    */
   public JMenu()
   {
     super();
     setOpaque(false);
   }
 
   /**
    * Creates a new <code>JMenu</code> with the specified label.
    *
    * @param text label for this menu
@@ -179,37 +218,40 @@
     return getPopupMenu().add(component, index);
   }
 
   /**
    * Adds JMenuItem constructed with the specified label to this menu
    *
    * @param text label for the menu item that will be added
    *
    * @return Menu Item that was added to this menu
    */
   public JMenuItem add(String text)
   {
-    return getPopupMenu().add(text);
+    return add(new JMenuItem(text));
   }
 
   /**
    * Adds JMenuItem constructed using properties from specified action.
    *
    * @param action action to construct the menu item with
    *
    * @return Menu Item that was added to this menu
    */
   public JMenuItem add(Action action)
   {
-    return getPopupMenu().add(action);
+    JMenuItem i = createActionComponent(action);
+    i.setAction(action);
+    add(i);
+    return i;
   }
 
   /**
    * Removes given menu item from this menu. Nothing happens if
    * this menu doesn't contain specified menu item.
    *
    * @param item Menu Item which needs to be removed
    */
   public void remove(JMenuItem item)
   {
     getPopupMenu().remove(item);
   }
@@ -314,25 +356,36 @@
   public String getUIClassID()
   {
     return "MenuUI";
   }
 
   /**
    * Sets model for this menu.
    *
    * @param model model to set
    */
   public void setModel(ButtonModel model)
   {
+    ButtonModel oldModel = getModel();
+    if (oldModel != null && changeListener != null)
+      oldModel.removeChangeListener(changeListener);
+
     super.setModel(model);
+
+    if (model != null)
+      {
+        if (changeListener == null)
+          changeListener = new MenuChangeListener();
+        model.addChangeListener(changeListener);
+      }
   }
 
   /**
    * Returns true if the menu is selected and false otherwise
    *
    * @return true if the menu is selected and false otherwise
    */
   public boolean isSelected()
   {
     return super.isSelected();
   }
 

Reply via email to