Frames | No Frames |
1: /* AbstractAction.java -- 2: Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.beans.PropertyChangeEvent; 42: import java.beans.PropertyChangeListener; 43: import java.io.Serializable; 44: import java.util.HashMap; 45: 46: import javax.swing.event.SwingPropertyChangeSupport; 47: 48: /** 49: * A base class for implementing the {@link Action} interface. 50: * 51: * @author Andrew Selkirk 52: */ 53: public abstract class AbstractAction 54: implements Action, Cloneable, Serializable 55: { 56: private static final long serialVersionUID = -6803159439231523484L; 57: 58: /** 59: * A flag that indicates whether or not the action is enabled. 60: */ 61: protected boolean enabled = true; 62: 63: /** 64: * Provides support for property change event notification. 65: */ 66: protected SwingPropertyChangeSupport changeSupport = 67: new SwingPropertyChangeSupport(this); 68: 69: /** 70: * store 71: */ 72: private transient HashMap store = new HashMap(); 73: 74: /** 75: * Creates a new action with no properties set. 76: */ 77: public AbstractAction() 78: { 79: // Nothing to do. 80: } 81: 82: /** 83: * Creates a new action with the specified name. The name is stored as a 84: * property with the key {@link Action#NAME}, and no other properties are 85: * initialised. 86: * 87: * @param name the name (<code>null</code> permitted). 88: */ 89: public AbstractAction(String name) 90: { 91: putValue(NAME, name); 92: } 93: 94: /** 95: * Creates a new action with the specified name and icon. The name is stored 96: * as a property with the key {@link Action#NAME}, the icon is stored as a 97: * property with the key {@link Action#SMALL_ICON}, and no other properties 98: * are initialised. 99: * 100: * @param name the name (<code>null</code> permitted). 101: * @param icon the icon (<code>null</code> permitted). 102: */ 103: public AbstractAction(String name, Icon icon) 104: { 105: putValue(NAME, name); 106: putValue(SMALL_ICON, icon); 107: } 108: 109: /** 110: * Returns a clone of the action. 111: * 112: * @return A clone of the action. 113: * 114: * @exception CloneNotSupportedException if there is a problem cloning the 115: * action. 116: */ 117: protected Object clone() throws CloneNotSupportedException 118: { 119: AbstractAction copy = (AbstractAction) super.clone(); 120: copy.store = (HashMap) store.clone(); 121: return copy; 122: } 123: 124: /** 125: * Returns the value associated with the specified key. 126: * 127: * @param key the key (not <code>null</code>). 128: * 129: * @return The value associated with the specified key, or 130: * <code>null</code> if the key is not found. 131: * 132: * @see #putValue(String, Object) 133: */ 134: public Object getValue(String key) 135: { 136: return store.get(key); 137: } 138: 139: /** 140: * Sets the value associated with the specified key and sends a 141: * {@link java.beans.PropertyChangeEvent} to all registered listeners. 142: * The standard keys are: 143: * <ul> 144: * <li>{@link #NAME}</li> 145: * <li>{@link #SHORT_DESCRIPTION}</li> 146: * <li>{@link #LONG_DESCRIPTION}</li> 147: * <li>{@link #SMALL_ICON}</li> 148: * <li>{@link #ACTION_COMMAND_KEY}</li> 149: * <li>{@link #ACCELERATOR_KEY}</li> 150: * <li>{@link #MNEMONIC_KEY}</li> 151: * </ul> 152: * Any existing value associated with the key will be overwritten. 153: * 154: * @param key the key (not <code>null</code>). 155: * @param value the value (<code>null</code> permitted). 156: */ 157: public void putValue(String key, Object value) 158: { 159: Object old = getValue(key); 160: if ((old == null && value != null) || (old != null && !old.equals(value))) 161: { 162: store.put(key, value); 163: firePropertyChange(key, old, value); 164: } 165: } 166: 167: /** 168: * Returns the flag that indicates whether or not the action is enabled. 169: * 170: * @return The flag. 171: * 172: * @see #setEnabled(boolean) 173: */ 174: public boolean isEnabled() 175: { 176: return enabled; 177: } 178: 179: /** 180: * Sets the flag that indicates whether or not the action is enabled and, if 181: * the value of the flag changed from the previous setting, sends a 182: * {@link java.beans.PropertyChangeEvent} to all registered listeners (using 183: * the property name 'enabled'). 184: * 185: * @param enabled the new flag value. 186: * 187: * @see #isEnabled() 188: */ 189: public void setEnabled(boolean enabled) 190: { 191: if (enabled != this.enabled) 192: { 193: this.enabled = enabled; 194: firePropertyChange("enabled", !this.enabled, this.enabled); 195: } 196: } 197: 198: /** 199: * Returns an array of the keys for the property values that have been 200: * defined via the {@link #putValue(String, Object)} method (or the class 201: * constructor). 202: * 203: * @return An array of keys. 204: */ 205: public Object[] getKeys() 206: { 207: return store.keySet().toArray(); 208: } 209: 210: /** 211: * Sends a {@link PropertyChangeEvent} for the named property to all 212: * registered listeners. 213: * 214: * @param propertyName the property name. 215: * @param oldValue the old value of the property. 216: * @param newValue the new value of the property. 217: */ 218: protected void firePropertyChange(String propertyName, Object oldValue, 219: Object newValue) 220: { 221: changeSupport.firePropertyChange(propertyName, oldValue, newValue); 222: } 223: 224: /** 225: * Sends a {@link PropertyChangeEvent} for the named property to all 226: * registered listeners. This private method is called by the 227: * {@link #setEnabled(boolean)} method. 228: * 229: * @param propertyName the property name. 230: * @param oldValue the old value of the property. 231: * @param newValue the new value of the property. 232: */ 233: private void firePropertyChange(String propertyName, boolean oldValue, 234: boolean newValue) 235: { 236: changeSupport.firePropertyChange(propertyName, oldValue, newValue); 237: } 238: 239: /** 240: * Registers a listener to receive {@link PropertyChangeEvent} notifications 241: * from this action. 242: * 243: * @param listener the listener. 244: * 245: * @see #removePropertyChangeListener(PropertyChangeListener) 246: */ 247: public void addPropertyChangeListener(PropertyChangeListener listener) 248: { 249: changeSupport.addPropertyChangeListener(listener); 250: } 251: 252: /** 253: * Deregisters a listener so that it no longer receives 254: * {@link PropertyChangeEvent} notifications from this action. 255: * 256: * @param listener the listener. 257: * 258: * @see #addPropertyChangeListener(PropertyChangeListener) 259: */ 260: public void removePropertyChangeListener(PropertyChangeListener listener) 261: { 262: changeSupport.removePropertyChangeListener(listener); 263: } 264: 265: /** 266: * Returns all registered listeners. 267: * 268: * @return An array of listeners. 269: * 270: * @since 1.4 271: */ 272: public PropertyChangeListener[] getPropertyChangeListeners() 273: { 274: return changeSupport.getPropertyChangeListeners(); 275: } 276: }