Table of Contents Markup Tutorial Interfacing with Java™ Web Services

Action events, like item events, can be handled by attaching one or more action listeners to components that receive such events. Typically, a component is associated with a single action listener, but it is possible to attach more than one listener to a single component. When multiple action listeners are attached to a component, a specific action is performed by each of them in response to an action event.

An action listener can be an instance of any user-defined class that implements the java.awt.event.ActionListener interface. An action listener is usually represented by the actionListener element type, or by the action element type. The action element type supports additional attributes that are not supported by the actionListener element type. These include title, icon, enabled, and description attributes.

The only way to attach multiple actions to a component is through the actionListener element type. However, we focus almost exclusively on the action element type in this tutorial.

Groundwork for Action

In preparation for a demonstration of the action element type, we create a skeleton user interface for a hypothetical “Media Controller” in the example below. The markup is straightforward as it does not introduce any new concepts or element types that have not already been covered.

Make this object in eNode Sandbox. The result should be similar to the following:

Shared Actions

Actions, like borders and fonts, can be shared by multiple components. For example, a given action may be associated with a button and a menu item. For this reason, an action element, like a font element, is commonly defined in advance inside a reserve element, although it doesn’t have to be that way. Also, exactly like fonts, an action is attached to a component by associating:

  • the action attribute of the element representing the component, with
  • the action element representing the action.
As usual, the association is made using a URI that must, at a minimum, include the fragment identifier identifying the action element.

Wiring of Shared Actions

We now show how the “Skip Backward” and “Skip Forward” menu items and the corresponding toolbar buttons are wired with shared actions, by augmenting the markup for the Media Controller example shown above.

When using action elements, it is customary to specify a button’s or menu item’s title and icon through the title and icon attributes, respectively, of the corresponding action elements, as shown below:

<action id="showInfo" title="Show Info"/>
<action id="backward" title="Skip Backward" icon="images/backward.gif"/>
<action id="pause" title="Pause" icon="images/pause.gif"/>
<action id="forward" title="Skip Forward" icon="images/forward.gif"/>
<action id="stop" title="Stop"/>

Overriding Action Attributes

If an action element is subsequently associated with a button element or a menuItem element, the realized button or menu item gets its title and icon from the corresponding attribute of the action element. That can be problematic if an action element has both a title attribute and an icon attribute, but the menu item shows only the title and the button shows only the icon, as in this example. Fortunately, you can override the title, or icon, or both, by explicitly specifying the relevant attribute for the button or menuItem elements, as shown below:

<menuItem icon="" accelerator="meta B" action="#backward"/>
<menuItem icon="" accelerator="meta P" action="#pause"/>
<menuItem icon="" accelerator="meta F" action="#forward"/>

and, likewise,

<button title="" action="#backward"/>
<button title="" action="#pause"/>
<button title="" action="#forward"/>

The entire listing for the example is shown below.

Make this object in eNode Sandbox. The result should be similar to the following:

Now, click on the backward or forward button on the toolbar, or select the corresponding item from the “Control” menu, and observe the output on the console — You should see the name of the action that was “performed”.

User-Defined Actions

In order to plug in your own actions, you have two options to choose from, at this point.

  • Using the class attribute of an action element, you can realize an instance of any custom class that implements javax.swing.Action or extends javax.swing.AbstractAction, or
  • Using the target attribute of an action element, you can delegate the action to another action listener object. The value of the target attribute is the URI of an element representing the other action listener object.

Trampolines

When the handling of an action event is delegated to another action listener, the action listener represented by the original action element functions like a trampoline — An action event initially arrives at the trampoline, but immediately bounces off to the target object, where it is eventually handled.

The target attribute is required in order for the realized form of an action element to be recognized as a trampoline. The target object itself can be an instance of any class, as long as it implements java.awt.event.ActionListener (possibly along with other event listener interfaces).

Invoking Actions by Name

By default, an action listener handles an action event in the actionPerformed() method declared by the java.awt.event.ActionListener interface. The listener invokes the same method for every action event, regardless of the source of the event. This is fine when a separate action listener is used for each distinct event source, but may pose administrative problems when a single listener is shared by more than one event source (such as the “Skip Backward” and “Skip Forward” buttons in this example).

In such cases, it is often desirable to associate an action source with a distinctly named action method in the event listener class. Then, all events from the same action source could be directly routed to the appropriate action method, instead of the generic actionPerformed() method.

This facility is available only when a trampoline is used to delegate action handling to a separate target object. The name of the action method must be specified in the method attribute of the action element representing the trampoline.The action method in the target must be a public method with the same return type and argument list as the actionPerformed() method.

If all of this sounds complicated, it isn’t. See an example of a trampoline in action here


Copyright © 2002 eNode, Inc. All Rights Reserved.