Back Back

The Extended Action Framework

The Extended Action Framework extends the Action framework provided by Swing. It mainly provides convenience methods and fields.

The XAction Interface

The Action interface provided by Swing defines some static final fields, which can be used as keys for its getValue and putValue methods. Unfortunalty this interface has some shortcomings:

The XAction interface overcomes these shortcomings by defining static final fields for all these icons and providing setter and getter methods with the right type for each field it defines.
Note: The getter method might throw a ClassCastException if the putValue method has been called directly with a wrong type. The safest way is to use the convenience methods to set the values.

This extended Action interface builds the base of the rest of the Extended Action Framework and since it extends the Action interface, it can be used everywhere an ordinary Action can be used!
The AbstractXAction class implements the XAction interface by extending the AbstractAction and implementing all new methods of XAction. The actionPerfomed method remains abstract.
            
        

Reflective Actions

ReflectiveXAction is a trampoline class that implements the XAction interface and delegates the actionPerformed method to a reflectivly called action method. That method must be public and take an ActionEvent object as its single parameter.

Normally there are two standard ways to implement the ActionListener interface: The first is to let a class implement the ActionListener interface and then add an object of this class to the addActionListener methods of the components firing ActionEvents. You then have to check the source in the actionPerformed method. You end up with a big ugly, unmaintainable and unstable if-then-else- statement. The second approach is to define a class for every such component. You end up with tons of small classes all increasing the memory footprint (typically 3K per class).

Now this approach using reflection lets you define a method for each such component avoiding the mentioned drawbacks and has the following advantages:

The new drawbacks are however: More to read about reflective actions and trampolines: Chapter 6.2.3, p. 73 of the Java Series Book Java Platform Performance Strategies and Tactics by Steve Wilson and Jeff Kesselman.

Although there are no compile time errors if the specified method doesn't exist, you don't have to wait for the method to be called to get an Exception. The constructor will already throw a NoSuchMethodException in that case.

            
        
Reflective actions are heavily used and supported throughout the whole Extended Action Framework.

The XActions Utility Class

The XActions class is a utility class providing convenience methods, which are described in this section.

The Button Configuration Methods

Let's first have a look at the configureButton method:

        public static void configureButton(AbstractButton button, XAction action, IconType iconType, boolean showText, boolean coolStyle)
        
This method configures an AbstractButton with an XAction. It can be specified, which icon type should be use (small icons, large icons or no icons), if the text should be displayed and if the buttons should have a cool style. If cool style is set to true, then the border of the button will be drawn only if the mouse pointer is over the button. Note: Since Java 1.4 you can create a similar effect by setting the rollover property of the toolbar to true. However look and feels may ignore this property and the Java Look and Feel does so.
            
         

Configure Buttons Sample



Try this:
  1. using Java Web Start.
  2. This sample shows 1 menu and 2 toolbars all configured by the same XAction objects.
Note: This sample uses the GeneralActionFactory class, which will be discussed later in the section The Standard Action Factories.

Source code: ConfigureButtonsSample.java


Like this you can first specify all information in one XAction object and then specify which data should be displayed using this same XAction object.

The configureButton method is twice overloaded:

            public static void configureButton(AbstractButton button, XAction action, ButtonGroup group, IconType iconType, boolean showText, boolean coolStyle)
            
            public static void configureButton(AbstractButton button, XAction action, ItemListener listener, IconType iconType, boolean showText, boolean coolStyle)
        
The first variant additionally adds the button to a ButtonGroup. The second variant registers an ItemListener to the button.

The Button Creation Methods

Instead of first creating a button and then configuring it using one of the methods discussed above, the XAcions class also provides convenience methods to create such configured buttons directly:

            public static JButton createButton(XAction action, IconType iconType, boolean showText, boolean coolStyle)
  
            public static JCheckBox createCheckBox(XAction action, ItemListener listener, IconType iconType, boolean showText)
  
            public static JCheckBoxMenuItem createCheckBoxMenuItem(XAction action, ItemListener listener, IconType iconType, boolean showText)
  
            public static JMenuItem createMenuItem(XAction action, IconType iconType, boolean showText)
  
            public static JRadioButton createRadioButton(XAction action, ButtonGroup group, IconType iconType, boolean showText)
  
            public static JRadioButtonMenuItem createRadioButtonMenuItem(XAction action, ButtonGroup group, IconType iconType, boolean showText)
  
            public static JToggleButton createToggleButton(XAction action, ButtonGroup group, IconType iconType, boolean showText, boolean coolStyle)
  
            public static JToggleButton createToggleButton(XAction action, ItemListener listener, IconType iconType, boolean showText, boolean coolStyle)
        
With these methods the previous sample could be rewritten like this:
            
        
The modified source code: CreateButtonsSample.java
Now that we have looked at how to configure and create buttons using XAction objects, let's see how we can configure and create these XAction objects using a ResourceBundle.

The XAction Configuration Method

The XActions class provides the following utility method to configure a XAction object from a ResourceBundle:

                public static void configureXAction(XAction action, String name, ResourceBundle rb)
            
This method is looking for the following keys:

Key Value
<name>.name The Name to be Displayed
<name>.shortDescription Tool Tip
<name>.acceleratorKey Shortcut
<name>.mnemonicKey Mnemonic
<name>.largeDisabledIcon File Name
<name>.largeDisabledSelectedIcon File Name
<name>.largeIcon File Name
<name>.largePressedIcon File Name
<name>.largeRolloverIcon File Name
<name>.largeRolloverSelectedIcon File Name
<name>.largeSelectedIcon File Name
<name>.smallDisabledIcon File Name
<name>.smallDisabledSelectedIcon File Name
<name>.smallIcon File Name
<name>.smallPressedIcon File Name
<name>.smallRolloverIcon File Name
<name>.smallRolloverSelectedIcon File Name
<name>.smallSelectedIcon File Name

E.g.
            myAction.name = MyAction
            myAction.shortDescription = My Action
            myAction.acceleratorKey = Control M
            myAction.mnemonicKey = A
            myAction.largeIcon = /myGraphics/MyAction24.gif
            myAction.smallIcon = /myGraphics/MyAction16.gif
            
If a key is not specified it in the ResourceBundle it will be ignored!

The XAction Creation Method

Instead of first creating a XAction object and then configuring it using configureXAction method discussed above, the XAcions class also provides a convenience method to create such a configured XAction object directly:

                public static XAction createXAction(String name, Object target, ResourceBundle rb) throws NoSuchMethodException
            
This method will create a ReflectiveXAction. (See the Reflective Actions section to learn more about reflective actions.) The object 'target' is expected to have a method:
                public void <name>(ActionEvent e)
            

The Standard Action Factories

The Standard Action Factories provide utility methods to create and configure XActions for standard actions. However they do not provide any functionality for the actions since that is application specific.

All Standard Action Factory classes are typesafe enums, which provide one action factory instance for each supported standard action. They all derive from the base class StandardActionFactory. The StandardActionFactory provides two methods:

                public XAction createXAction(Object target, Locale locale) throws NoSuchMethodException
                public void configureXAction(XAction action, Locale locale)
            
Note: The createXAction-method expects that the object 'target' has a method:
                public void <name>(ActionEvent e)
            
where <name> is equal to the output of the toString()-method of the action factory.

E.g. to create the standard action "save" you could use:

                
            
or:
                
            

The data in the resource bundles that backup the Standard Action Factories is based on the following sources:

Currently the following locales are supported: Note: The data in the resource bundles is not complete yet!

There is one Standard Action Factory class for each part of the Java Look and Feel Graphics Repository:

Action Factory Button Graphics
DevelopmentActionFactory Development Toolbar Button Graphics
GeneralActionFactory General Toolbar Button Graphics
MediaActionFactory Media Toolbar Button Graphics
NavigationActionFactory Navigation Toolbar Button Graphics
TableActionFactory Table Toolbar Button Graphics
TextActionFactory Text Toolbar Button Graphics

The follwing sample provides an overview over what data is already available.

Standard Action Factories Sample



Try this:
  1. using Java Web Start.
  2. This sample shows 1 menu and 1 toolbar for each Standard Action Factory class.
    (Except the GeneralActionFactory class for which there are 2 toolbars.)

Source code: StandardActionFactoriesSample.java


From the source code:

            
         

Back Back