Aqua Phoenix
     >>  Research >>  OOP  
 

Navigator
   
 
       
   

12. Events

12.1 Summary

  • What are Action Listeners?
  • Events are objects
  • How to implement Action Listeners

12.2 Contents

12.2.1 What are Action Listeners?

What are buttons, checkboxes, and the like used for, if we couldn't capture a click or some type of action related to the object. A button without an action association is really just two images; we see one image, and when clicking on the image, we see a slightly displaced version of the image. In order to make some use of it, we need to associate an action to the button. For that reason, we apply what is called an "ActionListener".

ActionListeners are added to objects, so that when we make use of an object, the ActionListener notifies us of the action. If you look at our first applet framework, you may notice in the class declaration the use of this ActionListener as "implements ActionListener". We would not need these two keywords, if we had no interaction in the applet. That is, ActionListeners are only then added when there is some type of interactive component in the applet. You may wonder why this functionality is not inherent to applets. The reason for that is that there are numerous Listeners that can be added to applets. Drop-down boxes, for example, use an ItemListener instead. If we added all of the possible Listeners, we would greatly impede the efficiency of applets, while not using 99% of the possible Listeners. More importantly though, we also want to make room for non-default Listeners. That is, what happens, if we write our own Listener for some object. These Listeners are not added to applets by default either.

However, simply adding ActionListeners to the declaration does not suffice. Additionally, we need to add instances of the ActionListener to each component that we want to listen to. A button is a good example. After adding an ActionListener to a button, we may capture the button's actions in a separate, pre-defined method, which we include in the applet. If you look back at the simplistic framework, you may notice a method by the name of "actionPerformed(..)". This is a predefined method for all those components that use the ActionListener. For components that use the ItemListener, this method is called "itemStateChanged(..)". We will learn later why these methods have predefined names.

12.2.2 Events are objects

Much like everything else in Java, events themselves behave like objects. Once an action has been performed, an event object is passed to the function, e.g. in "actionPerformed(ActionEvent e)", ActionEvent is the type of event object passed, and e is the variable reference to that object. We can now find out what kind of action has been performed, by calling methods on the object. You may wonder why we need to find out specifics about the action. Since an applet may have multiple buttons, each button action arrives at the very same actionPerformed(..) method, and each time a new and different ActionEvent object is passed along as an argument. There is no way of distinguishing what button has been pressed, other than finding out with methods in the ActionEvent. A very useful method in ActionEvent is called "getSource()". This method returns the object on which an action has been performed. It does not just return the name or any other part of the component, it simply returns a reference to the very component that has received an action. If we declare our buttons globally, so that it may be accessed over the entire applet, we can now compare it to "getSource()" and see whether or not this particular button has been pressed.

12.2.3 How to implement Listeners

We shall now look at a specific example that implements an ActionListener:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;


public class myApplet extends Applet implements ActionListener {

  Button b1;

  public init() {

    BorderLayout bl = new BorderLayout();
    setLayout(bl);

    b1 = new Button("Click Me!");
    b1.addActionListener(this);
    add(b1, BorderLayout.CENTER);
  }


  public void actionPerformed(ActionEvent e) {

    if (e.getSource() == b1) {
      // do something
    }
  }
}
Firstly, because we are dealing with buttons, we need to include the ActionListener in our implements statement. After declaring the button globally, we can now instantiate it and add the ActionListener to the button by stating b1.addActionListener(this). The keyword "this" again refers to the current object, namely our applet. We need to specify "this", because it is this very object that will be handling the actions in the method "actionPerformed(..)". If the actions were handled by another object, we would not need to include the "implements ActionListener" part, or the method "actionPerformed(..)". Moreover, in that case, we would include a variable that references the other object, instead of "this". For our purposes, we will be handling all actions in the very object, where they were created. In our actionPerformed(..) method, we may then use the ActionEvent e to find out what object has been used, as outlined above. We merely need to compare the source of action [getSource()] to the objects in question. Even though we only have one object, where the action could possibly come from, the above code only serves as an example.

If you look back at the code example "Components.java", you will find yet another event handler by the name of ItemListener. This type of listener is used for checkboxes and drop down selection boxes. The reason for creating a separate listener is that while buttons only have one state, i.e. the state of being clicked on, checkboxes and drop down selection boxes have two and multiple states, respectively.