October 31, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Understanding Action Objects in Java

  • May 29, 2002
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

Listing 14 invokes the setAction method on the JButton object to register the other Action object on that JButton.  Thus, two different Action objects are registered on the two JButton objects on the toolbar.

Synchronized with menu items

Furthermore, the same two Action objects that are registered on the JButton objects on the tool bar are also registered on the two JMenuItem objects on the menu.  Thus, the menu items and the toolbar buttons are tied together (in pairs) so as to behave in a synchronous fashion.

When one of the Action objects becomes disabled, the corresponding menu item and the corresponding toolbar button also become disabled.  When the other Action object becomes disabled, the other menu item and the other toolbar button become disabled.

When an Action object becomes enabled, the corresponding menu item and the corresponding toolbar button become enabled.

When the value of the keyed property of an Action object identified with the key Action.SMALL_ICON changes, the corresponding menu item and the corresponding toolbar button track the change.  This causes the image displayed on both of those components to change.

Various containers can be used

Probably the most common use of the Action interface is to synchronize the behavior of items on a menu with buttons on a toolbar.  However, the use of the Action interface is not confined to those two types of containers.  Rather, the Action interface can be used to synchronize the behavior of action-aware components in just about any kind of container.  This is illustrated in Listing 15.

(You may want to avoid AWT containers to avoid the problems involved in mixing heavyweight and lightweight components.  For example, it appears that you cannot control icons on a JButton that is placed in an AWT Panel.)
    JButton butC = new JButton();
    butC.setAction(actionObj01);
    panel.add(butC);

    JMenuItem mnuC = new JMenuItem();
    mnuC.setAction(actionObj02);
    panel.add(mnuC);

Listing 15

Populate the JPanel

Listing 15 creates a new JButton object and a new JMenuItem object and places them in a common JPanel container object.  The setAction method is used, along with the same two Action objects discussed earlier, to synchronize the behavior of these two components with the two components on the menu, and the two components on the toolbar.

(Hopefully by now you will have compiled and run this program.  Due to the limitations of my verbal descriptions of behavior, running the program may ultimately be necessary for you to fully understand how this program behaves.)
Construct control panel, set size, etc.

Listing 16 constructs the control panel containing check boxes that will be used to manipulate the properties of the two Action objects.  Listing 16 also sets the size of the GUI and makes it visible.
 

    //Construct the control panel and
    // put it in the Center
    controlPanel.setLayout(
              new GridLayout(2,2,3,3));
    controlPanel.add(ckBox01);
    controlPanel.add(ckBox02);
    controlPanel.add(ckBox03);
    controlPanel.add(ckBox04);
    getContentPane().add(controlPanel,
                  BorderLayout.CENTER);
    
    //Set the size and make the GUI
    // visible
    setSize(350,200);
    setVisible(true);
    setTitle("Copyright 2002, " +
                        "R.G.Baldwin");

Listing 16

The code in Listing 16 is completely straightforward and doesn't deserve further discussion in this article.

Register checkbox event handlers to manipulate Action properties

The anonymous inner listener class in Listing 17 makes it possible for the user to manipulate the enabled property of one of the Action objects and its associated visual components.

The code in Listing 17, (and the code that follows in other listings), registers ActionListener objects on each of the checkboxes.

(Note that these ActionListener objects registered on the checkboxes are completely independent of the Action objects registered on the action-aware components.)
This control structure makes it possible for the user to disable and enable the two Action objects independently of one another simply by checking or clearing the checkboxes.

This control structure also makes it possible to toggle the icons between two different images on each Action object when the Action object is enabled.
 

    ckBox01.addActionListener(
      new ActionListener(){
        public void actionPerformed(
                        ActionEvent e){
          if(e.getActionCommand().
                  equals("Disable01")){
            ckBox01.setText(
                           "Enable01");
            actionObj01.setEnabled(
                                false);
            //Disable ability to toggle
            // the IconImage.
            ckBox03.setEnabled(false);
          }else{
            ckBox01.setText(
                          "Disable01");
            actionObj01.setEnabled(
                                 true);
            //Enable ability to toggle
            // the IconImage.
            ckBox03.setEnabled(true);
          }//end else
        }//end actionPerformed()
      }//end ActionListener
    );//end addActionListener
  
Listing 17

Two important statements

Although the code in Listing 17 appears to be long and complex, it is relatively straightforward.

The actionPerformed method shown in Listing 17 is invoked when the checkbox fires an action event (when the user checks or clears the checkbox).  Let me draw your attention to the two boldface statements in Listing 17.  These two statements use the current state of the checkbox object to make a decision between two alternatives, and then to change the value of the enabled property of the Action object referred to by actionObj01.   (The state of the checkbox object is also changed accordingly.)

When the value of the enabled property of the Action object is changed, the three components registered earlier as change listeners on the Action object are notified of the change.  The code in the classes from which those components were instantiated causes them to become enabled or disabled accordingly.  In other words, the enabled state of all three components tracks the enabled property of the Action object.

The other Action object

The code in Listing 18 uses a different checkbox object to provide essentially the same enabled/disabled control for the other Action object and its associated components.  Since this code replicates the code in Listing 17, I deleted most of it for brevity.  You can view all of the code in Listing 22 near the end of this lesson.
 

    ckBox02.addActionListener(
      //...code deleted for brevity
    );//end addActionListener

Listing 18

Manipulate the icons

Listing 19 is an anonymous inner listener class that makes it possible for the user to manipulate a keyed property value of an Action object, the value of which specifies the icon to be displayed on registered components.

Basically, this code causes the value of the property that specifies the icon displayed on the components to toggle between two different ImageIcon objects based on two different gif files.
 

    ckBox03.addActionListener(
      new ActionListener(){
        public void actionPerformed(
                        ActionEvent e){
          //Get file name for the
          // ImageIcon object.
          String gif = (actionObj01.
                 getValue(
                   Action.SMALL_ICON)).
                            toString();

          if((gif).equals(
                       "redball.gif")){
            actionObj01.putValue(
                     Action.SMALL_ICON,
                      new ImageIcon(
                      "blueball.gif"));
          }else{
            actionObj01.putValue(
               Action.SMALL_ICON,
                         new ImageIcon(
                       "redball.gif"));
          }//end else
           
        }//end actionPerformed()
      }//end ActionListener
    );//end addActionListener    

Listing 19

Change the displayed icon

The logic in Listing 19 is straightforward.  When the checkbox fires an action event, the code in the actionPerformed method uses the getValue method of the Action interface to get the name of the gif file that specifies the icon.  Then it changes the value of that keyed property in the Action object to an ImageIcon object based on the other gif file, thereby toggling the value between two ImageIcon objects based on the two different gif files.

When the value of this keyed property changes, the three components that were earlier registered as change listeners on the Action object are notified of the change.  The code in the classes from which the three components were instantiated causes the icon that is displayed on the component to track the corresponding property value of the Action object.

Do it again for the other Action object

Listing 20 provides the same icon toggling capability for the other Action object.  Once again, since this code replicates the code in Listing 19, I deleted most of it for brevity.  You can view all of the code in Listing 22 near the end of this lesson.
 

    ckBox04.addActionListener(
      //... code deleted for brevity
    );//end addActionListener

Listing 20

Finally, the end of the program

Listing 21 is a simple WindowListener that terminates the program when the user clicks the close button on the JFrame object.  This is relatively standard material, which should not require a discussion in this context.
 

    this.addWindowListener(
      new WindowAdapter(){
        public void windowClosing(
                        WindowEvent e){
          System.exit(0);
        }//end windowClosing()
      }//end WindowAdapter
    );//end addWindowListener
  }//end constructor
}//end GUI class

Listing 21

Listing 21 is also the end of the GUI class definition.
 

Run the Program

If you haven't done so already, I encourage you to copy the code from Listing 22 into your text editor.  Then compile and run it.  Make changes and experiment with it in order to get a feel for the use of the Action interface.
(Note that you will need a couple of gif files containing small images to use as ImageIcon objects.  Any small image will do.  Just be sure to handle the file names properly.)




Page 5 of 6



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel