Understanding Actions

Actions are a popular addition to Swing. An action allows a programmer to bundle a commonly used procedure and its bound properties (such as its name and an image to represent it) into a single class. This construct comes in handy if an application needs to call upon a particular function from multiple sources. For example, let’s say that a Swing programmer creates an action that saves data to disk. The application could then invoke this action from both the Save menu item on the File menu and the Save button on a toolbar. Both components reference the same action object, which saves the data. If the Save function is disabled for some reason, this property can be set in the action as well. The menu and toolbar objects are automatically notified that they can no longer save any data, and they can relay that information to the user.

Actions and Containers

Swing containers, such as JMenu, JPopupMenu, and JToolBar, can each accept action objects with their add( ) methods. When an action is added, these containers automatically create a GUI component, which the add( ) method then returns to you for customization. For example, a JMenu or a JPopupMenu creates and returns a JMenuItem from an Action while a JToolBar creates and returns a JButton. The action is then paired with the newly created GUI component in two ways: the GUI component registers as a PropertyChangeListener for any property changes that might occur in the action object, while the action object registers as an ActionListener on the GUI component.
 
Essentially, this means that if the menu item or button is selected by the user, the functionality inside the action is invoked. On the other hand, if the action is disabled, it sends a PropertyChangeEvent to both the menu item and the toolbar, causing them to disable and turn gray. Similarly, if the action’s icon or name is changed, the menu and toolbar are automatically updated.
 

The Action Interface

An action is defined by the interface it implements, in this case javax.swing.Action. Action extends the ActionListener interface from AWT; this forces concrete classes that implement Action to provide an actionPerformed( ) method. The programmer uses the actionPerformed( ) method to implement whatever behavior is desired. For example, if you are creating a Save action, you should put the code that saves the data inside of your actionPerformed( ) method.

When the action is added to an accepting container such as JMenu, JPopupMenu, or JToolBar, the container automatically registers the action as an ActionListener of the GUI component it creates. Consequently, if the GUI component is selected by the user, it simply invokes the actionPerformed( ) method of the action to do its job.

Property

The Action interface defines the property shown in following Table:

Action property

Property Data type get is set Default value
enabled boolean · ·  

Methods

public abstract Object getValue(String key) 
public abstract void putValue(String key, Object value) 

Store various keyed properties for the action. A string-based key is used to index the values. When putValue( ) is called with any property, and the value passed in is different than what was there previously, the implementing object must fire a PropertyChangeEvent describing the change to all registered listeners.

public abstract void actionPerformed(ActionEvent e)

This method is required by the ActionListener interface (it does not actually exist in the Action interface). Any concrete class that implements the Action interface must provide an actionPerformed( ) method that performs whatever task the action is supposed to accomplish.

Events

Objects implementing the Action interface must fire a PropertyChangeEvent when any keyed property is changed, or when the action is enabled or disabled. Containers that accept actions typically listen for these PropertyChangeEvent notifications so they can update their own properties or appearances.

public abstract void addPropertyChangeListener(PropertyChangeListener listener) 
public abstract void removePropertyChangeListener(PropertyChangeListener listener) 

Add or remove the specified PropertyChangeListener from the event listener list.