[ Team LiB ] Previous Section Next Section

11.6 Actions and Reflection

Example 11-15 demonstrated the use of Action objects, which allow an application's command set to be easily presented to the user in menubars, toolbars, and so on. The awkward part about working with Action objects, however, is that each one must usually be defined as a class of its own. If you are willing to use the Java Reflection API, however, there is an easier alternative. In Example 9-2 we saw the Command class—a class that encapsulates a java.lang.reflect.Method object, an array of arguments for the method, and the object upon which the method is to be invoked. Calling the invoke( ) method of a Command object invokes the method. The most powerful feature of the Command class, however, is its static parse( ) method, which can create a Command by parsing a textual representation of the method name and argument list.

The Command class implements the ActionListener interface, so Command objects can be used as simple action listeners. But a Command is not an Action. Example 11-16 addresses this; it is a listing of CommandAction.java, a subclass of AbstractAction that uses a Command object to perform the action. Since the Command class does the hard work, the code for CommandAction is relatively simple.

Example 11-16. CommandAction.java
package je3.gui;
import je3.reflect.*;
import javax.swing.*;
import java.awt.event.*;

public class CommandAction extends AbstractAction {
    Command command;  // The command to execute in response to an ActionEvent
    
    /**
     * Create an Action object that has the various specified attributes, 
     * and invokes the specified Command object in response to ActionEvents
     **/
    public CommandAction(Command command, String label,
                         Icon icon, String tooltip, 
                         KeyStroke accelerator, int mnemonic,
                         boolean enabled) 
    {
        this.command = command;  // Remember the command to invoke
        
        // Set the various action attributes with putValue( )
        if (label != null) putValue(NAME, label);
        if (icon != null) putValue(SMALL_ICON, icon);
        if (tooltip != null) putValue(SHORT_DESCRIPTION, tooltip);
        if (accelerator != null) putValue(ACCELERATOR_KEY, accelerator);
        if (mnemonic != KeyEvent.VK_UNDEFINED) 
            putValue(MNEMONIC_KEY, new Integer(mnemonic));

        // Tell the action whether it is currently enabled or not
        setEnabled(enabled);
    }
    
    /**
     * This method implements ActionListener, which is a superinterface of
     * Action.  When a component generates an ActionEvent, it is passed to
     * this method.  This method simply passes it on to the Command object,
     * which is also an ActionListener object
     **/
    public void actionPerformed(ActionEvent e) { command.actionPerformed(e); }

    // These constants are defined by Action in Java 1.3.
    // For compatibility with Java 1.2, we redefine them here.
    public static final String ACCELERATOR_KEY = "AcceleratorKey";
    public static final String MNEMONIC_KEY = "MnemonicKey";
}
    [ Team LiB ] Previous Section Next Section