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}