    001/* ========================================================================
    002 * JCommon : a free general purpose class library for the Java(tm) platform
    003 * ========================================================================
    004 *
    005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006 *
    007 * Project Info:  http://www.jfree.org/jcommon/index.html
    008 *
    009 * This library is free software; you can redistribute it and/or modify it
    010 * under the terms of the GNU Lesser General Public License as published by
    011 * the Free Software Foundation; either version 2.1 of the License, or
    012 * (at your option) any later version.
    013 *
    014 * This library is distributed in the hope that it will be useful, but
    015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017 * License for more details.
    018 *
    019 * You should have received a copy of the GNU Lesser General Public
    020 * License along with this library; if not, write to the Free Software
    021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022 * USA.
    023 *
    024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025 * in the United States and other countries.]
    026 *
    027 * -------------------
    028 * ActionMenuItem.java
    029 * -------------------
    030 * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
    031 *
    032 * Original Author:  Thomas Morgner;
    033 * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034 *
    035 * $Id: ActionMenuItem.java,v 1.5 2007/11/02 17:50:36 taqua Exp $
    036 *
    037 * ChangeLog
    038 * ---------
    039 * 30-Aug-2002 : Initial version
    040 * 01-Aug-2002 : Documentation
    041 * 10-Dec-2002 : Minor Javadoc updates (DG);
    042 *
    043 */
    044
    045package org.jfree.ui.action;
    046
    047import java.awt.event.KeyEvent;
    048import java.beans.PropertyChangeEvent;
    049import java.beans.PropertyChangeListener;
    050import javax.swing.Action;
    051import javax.swing.Icon;
    052import javax.swing.JMenuItem;
    053import javax.swing.KeyStroke;
    054
    055import org.jfree.util.Log;
    056
    057/**
    058 * The ActionMenuItem is used to connect an Action and its properties to an
    059 * MenuItem.
    060 * <p/>
    061 * This functionality is already implemented in JDK 1.3 but needed for JDK 1.2.2
    062 * compatibility.
    063 *
    064 * @author Thomas Morgner
    065 */
    066public class ActionMenuItem extends JMenuItem
    067{
    068
    069  /** The action. */
    070  private Action action;
    071
    072  /** The property change handler. */
    073  private ActionEnablePropertyChangeHandler propertyChangeHandler;
    074
    075  /**
    076   * Helperclass to handle the property change event raised by the action.
    077   * Changed properties in the action will affect the button.
    078   */
    079  private class ActionEnablePropertyChangeHandler
    080          implements PropertyChangeListener
    081  {
    082    public ActionEnablePropertyChangeHandler()
    083    {
    084    }
    085
    086    /**
    087     * Receives notification of a property change event.
    088     *
    089     * @param event the property change event.
    090     */
    091    public void propertyChange(final PropertyChangeEvent event)
    092    {
    093      try
    094      {
    095        if (event.getPropertyName().equals("enabled"))
    096        {
    097          setEnabled(getAction().isEnabled());
    098        }
    099        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}