Source for org.jfree.ui.action.ActionMenuItem

   1: /* ========================================================================
   2:  * JCommon : a free general purpose class library for the Java(tm) platform
   3:  * ========================================================================
   4:  *
   5:  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
   6:  * 
   7:  * Project Info:  http://www.jfree.org/jcommon/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  * 
  27:  * -------------------
  28:  * ActionMenuItem.java
  29:  * -------------------
  30:  * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
  31:  *
  32:  * Original Author:  Thomas Morgner;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * $Id: ActionMenuItem.java,v 1.4 2005/10/18 13:22:12 mungady Exp $
  36:  *
  37:  * ChangeLog
  38:  * ---------
  39:  * 30-Aug-2002 : Initial version
  40:  * 01-Aug-2002 : Documentation
  41:  * 10-Dec-2002 : Minor Javadoc updates (DG);
  42:  *
  43:  */
  44: 
  45: package org.jfree.ui.action;
  46: 
  47: import java.beans.PropertyChangeEvent;
  48: import java.beans.PropertyChangeListener;
  49: import java.awt.event.KeyEvent;
  50: import javax.swing.Action;
  51: import javax.swing.Icon;
  52: import javax.swing.JMenuItem;
  53: import javax.swing.KeyStroke;
  54: 
  55: import org.jfree.util.Log;
  56: 
  57: /**
  58:  * The ActionMenuItem is used to connect an Action and its properties to an
  59:  * MenuItem.
  60:  * <p/>
  61:  * This functionality is already implemented in JDK 1.3 but needed for JDK 1.2.2
  62:  * compatibility.
  63:  *
  64:  * @author Thomas Morgner
  65:  */
  66: public class ActionMenuItem extends JMenuItem
  67: {
  68: 
  69:   /** The action. */
  70:   private Action action;
  71: 
  72:   /** The property change handler. */
  73:   private ActionEnablePropertyChangeHandler propertyChangeHandler;
  74: 
  75:   /**
  76:    * Helperclass to handle the property change event raised by the action.
  77:    * Changed properties in the action will affect the button.
  78:    */
  79:   private class ActionEnablePropertyChangeHandler
  80:           implements PropertyChangeListener
  81:   {
  82:     public ActionEnablePropertyChangeHandler()
  83:     {
  84:     }
  85: 
  86:     /**
  87:      * Receives notification of a property change event.
  88:      *
  89:      * @param event the property change event.
  90:      */
  91:     public void propertyChange(final PropertyChangeEvent event)
  92:     {
  93:       try
  94:       {
  95:         if (event.getPropertyName().equals("enabled"))
  96:         {
  97:           setEnabled(getAction().isEnabled());
  98:         }
  99:         else if (event.getPropertyName().equals(Action.SMALL_ICON))
 100:         {
 101:           setIcon((Icon) getAction().getValue(Action.SMALL_ICON));
 102:         }
 103:         else if (event.getPropertyName().equals(Action.NAME))
 104:         {
 105:           setText((String) getAction().getValue(Action.NAME));
 106:         }
 107:         else if (event.getPropertyName().equals(Action.SHORT_DESCRIPTION))
 108:         {
 109:           ActionMenuItem.this.setToolTipText((String)
 110:                   getAction().getValue(Action.SHORT_DESCRIPTION));
 111:         }
 112: 
 113:         final Action ac = getAction();
 114:         if (event.getPropertyName().equals(ActionDowngrade.ACCELERATOR_KEY))
 115:         {
 116:           setAccelerator((KeyStroke) ac.getValue(ActionDowngrade.ACCELERATOR_KEY));
 117:         }
 118:         else if (event.getPropertyName().equals(ActionDowngrade.MNEMONIC_KEY))
 119:         {
 120:           final Object o = ac.getValue(ActionDowngrade.MNEMONIC_KEY);
 121:           if (o != null)
 122:           {
 123:             if (o instanceof Character)
 124:             {
 125:               final Character c = (Character) o;
 126:               setMnemonic(c.charValue());
 127:             }
 128:             else if (o instanceof Integer)
 129:             {
 130:               final Integer c = (Integer) o;
 131:               setMnemonic(c.intValue());
 132:             }
 133:           }
 134:           else
 135:           {
 136:             setMnemonic(KeyEvent.VK_UNDEFINED);
 137:           }
 138:         }
 139:       }
 140:       catch (Exception e)
 141:       {
 142:         Log.warn("Error on PropertyChange in ActionButton: ", e);
 143:       }
 144:     }
 145:   }
 146: 
 147:   /** Default constructor. */
 148:   public ActionMenuItem()
 149:   {
 150:     // nothing required
 151:   }
 152: 
 153:   /**
 154:    * Creates a menu item with the specified icon.
 155:    *
 156:    * @param icon the icon.
 157:    */
 158:   public ActionMenuItem(final Icon icon)
 159:   {
 160:     super(icon);
 161:   }
 162: 
 163:   /**
 164:    * Creates a menu item with the specified label.
 165:    *
 166:    * @param text the label.
 167:    */
 168:   public ActionMenuItem(final String text)
 169:   {
 170:     super(text);
 171:   }
 172: 
 173:   /**
 174:    * Creates a menu item with the specified label and icon.
 175:    *
 176:    * @param text the label.
 177:    * @param icon the icon.
 178:    */
 179:   public ActionMenuItem(final String text, final Icon icon)
 180:   {
 181:     super(text, icon);
 182:   }
 183: 
 184:   /**
 185:    * Creates a new menu item with the specified label and mnemonic.
 186:    *
 187:    * @param text the label.
 188:    * @param i    the mnemonic.
 189:    */
 190:   public ActionMenuItem(final String text, final int i)
 191:   {
 192:     super(text, i);
 193:   }
 194: 
 195:   /**
 196:    * Creates a new menu item based on the specified action.
 197:    *
 198:    * @param action the action.
 199:    */
 200:   public ActionMenuItem(final Action action)
 201:   {
 202:     setAction(action);
 203:   }
 204: 
 205:   /**
 206:    * Returns the assigned action or null if no action has been assigned.
 207:    *
 208:    * @return the action.
 209:    */
 210:   public Action getAction()
 211:   {
 212:     return this.action;
 213:   }
 214: 
 215:   /**
 216:    * Returns and initializes the PropertyChangehandler for this ActionMenuItem.
 217:    * The PropertyChangeHandler monitors the action and updates the menuitem if
 218:    * necessary.
 219:    *
 220:    * @return the property change handler.
 221:    */
 222:   private ActionEnablePropertyChangeHandler getPropertyChangeHandler()
 223:   {
 224:     if (this.propertyChangeHandler == null)
 225:     {
 226:       this.propertyChangeHandler = new ActionEnablePropertyChangeHandler();
 227:     }
 228:     return this.propertyChangeHandler;
 229:   }
 230: 
 231:   /**
 232:    * Enables and disables this button and if an action is assigned to this
 233:    * menuitem the propertychange is forwarded to the assigned action.
 234:    *
 235:    * @param b the new enable-state of this menuitem
 236:    */
 237:   public void setEnabled(final boolean b)
 238:   {
 239:     super.setEnabled(b);
 240:     if (getAction() != null)
 241:     {
 242:       getAction().setEnabled(b);
 243:     }
 244:   }
 245: 
 246:   /**
 247:    * Assigns the given action to this menuitem. The properties of the action
 248:    * will be assigned to the menuitem. If an previous action was set, the old
 249:    * action is unregistered.
 250:    * <p/>
 251:    * <ul> <li>NAME - specifies the menuitem text <li>SMALL_ICON - specifies the
 252:    * menuitems icon <li>MNEMONIC_KEY - specifies the menuitems mnemonic key
 253:    * <li>ACCELERATOR_KEY - specifies the menuitems accelerator </ul>
 254:    *
 255:    * @param newAction the new action
 256:    */
 257:   public void setAction(final Action newAction)
 258:   {
 259:     final Action oldAction = getAction();
 260:     if (oldAction != null)
 261:     {
 262:       removeActionListener(oldAction);
 263:       oldAction.removePropertyChangeListener(getPropertyChangeHandler());
 264:       setAccelerator(null);
 265:     }
 266:     this.action = newAction;
 267:     if (this.action != null)
 268:     {
 269:       addActionListener(newAction);
 270:       newAction.addPropertyChangeListener(getPropertyChangeHandler());
 271: 
 272:       setText((String) (newAction.getValue(Action.NAME)));
 273:       setToolTipText((String) (newAction.getValue(Action.SHORT_DESCRIPTION)));
 274:       setIcon((Icon) newAction.getValue(Action.SMALL_ICON));
 275:       setEnabled(this.action.isEnabled());
 276: 
 277:       Object o = newAction.getValue(ActionDowngrade.MNEMONIC_KEY);
 278:       if (o != null)
 279:       {
 280:         if (o instanceof Character)
 281:         {
 282:           final Character c = (Character) o;
 283:           setMnemonic(c.charValue());
 284:         }
 285:         else if (o instanceof Integer)
 286:         {
 287:           final Integer c = (Integer) o;
 288:           setMnemonic(c.intValue());
 289:         }
 290:       }
 291:       else
 292:       {
 293:         setMnemonic(KeyEvent.VK_UNDEFINED);
 294:       }
 295: 
 296: 
 297:       o = newAction.getValue(ActionDowngrade.ACCELERATOR_KEY);
 298:       if (o instanceof KeyStroke)
 299:       {
 300:         setAccelerator((KeyStroke) o);
 301:       }
 302:     }
 303:   }
 304: }