Sun Java Solaris Communities My SDN Account Join SDN
 
Java Technology Fundamentals Newsletter Index

Java Technology Fundamentals Newsletter

 
Technology Fundamentals

Java Platform Overview | Getting Started | Step-by-Step Programming
Learning Paths | References & Resources | Certification


New to Java Programming Center Welcome to the Java Developer Connection Java Technology Fundamentals Newsletter.

This monthly newsletter provides a way for you to learn the basics of the Java programming language, discover new resources, and keep up-to-date on the latest additions to the JDC's New to Java Programming Center.

CONTENTS

1. Java Programming Language Basics

Event Handling Basics

2. Java Bits

Adapter Classes

3. Making Sense of the Java Class Libraries

KeyListener Interface and KeyAdapter Class

4. Program Challenge

Create the JustWindows Application

5. For More Information

Read articles, Tech Tips, trails, and tutorials that provide more information on the topics discussed here.

Java Programming Language Basics

Event Handling Basics

Click, click, click. Why isn't this button doing anything? When creating graphical programs with the Swing component set, you need to understand the associated event-handling model. Just placing those components onto the screen with a layout manager isn't the only necessary task to make a responsive user interface.

The event-handling model of the Swing component set works by associating observers to a component so that when an event occurs, any objects observing that event are notified. What's an observer? Generally speaking, it's any object that is interested in when an event happens. The trick with Swing is learning about the observers that are available for specific events of a component.

In the case of the Swing components, observers are called event listeners. They must implement the empty java.util.EventListener interface, and almost always implement a subclass listener interface with at least one method. The events are still called events, but they must subclass the java.util.EventObject class. Learning which event listeners are associated with the events of a component is half the battle.

Before learning how to find the events associated with a component, look at a specific one, button selection. Selection of a JButton is the ActionEvent. When a user selects a JButton, an ActionEvent is generated. If an object is interested in when that ActionEvent is generated, it needs to be registered with the JButton.

eventsource

For an ActionEvent, the registration comes in the form of an ActionListener. The names are purposely related. For any event of the form ABCEvent, the associated listener is ABCListener, where the specific event type replaces ABC.

Registration happens when the addActionListener method is called. By passing in an implementation of the listener interface to the addActionListener method, when the ActionEvent is generated, each and every registered implementer is notified. There can be multiple observers of an event.

The whole process goes as follows, though actual order can vary slightly.

  • For a given event, define a class that implements the related interface. You can add the "implements ABCListener" to an existing class definition, or create a new class that implements the interface.

  • Just adding "implements ABCListener" to the class isn't sufficient though. That class also needs to implement every method of the interface. Some listeners, like ActionListener, have one method. Other listeners, like WindowListener (for dealing with when a window moves or is closed) have more. Once the listener methods are defined, your code is compilable. However, "compilable" doesn't mean "responsive." That leads to the third step.

  • After defining the interface implementation, you need to create an instance of the implementation and associate that instance with the component. Only then is the observer--the listener--notified when the actual event occurs.

eventobject

This program demonstrates the case of responding to a button selection:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class MyActionListener implements ActionListener {
   public void actionPerformed(ActionEvent e) {
     System.out.println("Thank you.");
   }
}

public class SelectMe extends JFrame {


   public SelectMe() {
     super("Hello");
     setDefaultCloseOperation(EXIT_ON_CLOSE);
     JButton button = new JButton("Pick Me");
     ActionListener listener = new MyActionListener();
     button.addActionListener(listener);
     getContentPane().add(button, BorderLayout.CENTER);
     setSize(200, 200);
   }
   public static void main(String args[]) {
     JFrame frame = new SelectMe();
     frame.show();
   }
}

How do you learn the events that are triggered by each component? Look at the API documentation for your favorite component to reveal that answer. Just look for the pair of add/removeABCListener methods, again where ABC is the specific event type. Use each pair of add/remove methods, a different event can be generated. The removeABCListener method when you are no longer interested in knowing when an event happened.

Look at the JButton class to see what else you can listen for. The API documentation for the JButton class reveals that the button can listen for nothing. There are no add/remove methods. That's where object-oriented programming comes into play. You need to look in the superclass, AbstractButton. Lots of behavior is shared between several of the selectable Swing components, so the basis of the event handling code is moved up a level.

At the AbstractButton level, listeners you can associate with our JButton are not only the ActionListener, but also a ChangeListener and an ItemListener.

As you work through the components and their associated event observers, learn what each listener is for. Over time, this becomes second nature. Where the ActionListener is used to signify the selection of the component, the ChangeListener is used to signify the change any property of the button.

Properties of a component describe its state. In the case of a JButton, its properties are its text label, background and foreground colors, and font. If any of these or any of the many others change, then any registered ChangeListener is notified that some property of the associated component changed, but the event doesn't include information about which property changed. To listen if a change happened and to be told which property, use a PropertyChangeListener.

The following program adds a ChangeListener to the prior ActionListener example. When you run the program, you'll notice the ChangeListener is notified many times. Each state change triggers the notify, so, as a component is selected, it changes through various states, adjusting the background color and border accordingly.

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

class MyActionListener implements ActionListener {
   public void actionPerformed(ActionEvent e) {
     System.out.println("Thank you.");
   }
}

class MyChangeListener implements ChangeListener {
   public void stateChanged(ChangeEvent e) {
     System.out.println("You're welcome.");
   }
}

public class SelectMe extends JFrame {

   public SelectMe() {
     super("Hello");
     setDefaultCloseOperation(EXIT_ON_CLOSE);
     JButton button = new JButton("Pick Me");
     ActionListener aListener = new MyActionListener();
     button.addActionListener(aListener);
     ChangeListener cListener = new MyChangeListener();
     button.addChangeListener(cListener);
     getContentPane().add(button, BorderLayout.CENTER);
     setSize(200, 200);
   }
   public static void main(String args[]) {
     JFrame frame = new SelectMe();
     frame.show();
   }
}

As previously mentioned, there's also the ItemListener that can be associated with a JButton. But event handling for a button doesn't stop there. Moving past AbstractButton takes us to its superclass, JComponent.

From JComponent, there's its parent class Container, and then the parent class of Container, the Component class. Each of these levels adds its own set of listeners that can be associated with the button. The java.lang.Object class doesn't add any of its own.

The following table lists all the different events that a JButton can trigger and you can listen for.

  • java.awt.Component: ComponentListener, FocusListener, HierarchyBoundsListener, HierarchyListener, InputMethodListener, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener, PropertyChangeListener

  • java.awt.Container: ContainerListener, PropertyChangeListener javax.swing.JComponent AncestorListener, PropertyChangeListener, VetoableChangeListener

  • javax.swing.AbstractButton: ActionListener, ChangeListener, ItemListener

Such a large list might seem overwhelming, but take it easy. In most cases, you just associate an ActionListener to the button so you can respond when it's selected.

Most components contain a similar lengthy list of listeners. It just takes time and practice to learn about the most commonly used one.

Now you can test your knowledge about event handling with this online quiz:

Java Bits

Adapter Classes

AWT and the Project Swing APIs define interfaces called listeners. Every type of event has a listener interface, and each listener has methods for every event that can occur.

A listener interface requires that you override all of its abstract methods with defined methods in your class. Even if you don't need all of those methods, you still must implement the methods with empty code bodies. This can be time-consuming and clutters code since some interfaces have as many as seven abstract methods to be implemented.

For example, the MouseListener interface is designed for receiving mouse events, such as press, release, click, enter, and exit on a component. To use the MouseListener interface, you must implement the following five methods:

  • public void mouseClicked(MouseEvent e)
  • public void mousePressed(MouseEvent e)
  • public void mouseReleased(MouseEvent e)
  • public void mouseEntered(MouseEvent e)
  • public void mouseExited(MouseEvent e)

If you only needed to override one of those methods for your application, you'd still have to implement the others. You can avoid having to implement empty interface methods by using adapter classes.

Adapter classes provide empty implementation of all the methods in an event listener interface. You define a new class to act as an event listener by extending one of the adapter classes, which make it possible for you to override only the methods of interest.

The following example creates an application with two buttons. Mouse over a button, and the button name appears in the text field. This application extends the MouseAdapter class so only two methods are implemented instead of all five in the MouseListener interface:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MouseAdapterExample extends JFrame
 {
   JButton button1, button2;
   JTextField tf;
   
   public MouseAdapterExample()
     {//open constructor
     
      //Create buttons and add listeners
      button1 = new JButton("Button 1");
      button1.setName("Button 1");
      button1.addMouseListener(new MouseHandler());
      button2 = new JButton("Button 2");
      button2.setName("Button 2");
      button2.addMouseListener(new MouseHandler());
       
      //Create text field that does not allow the user
      // to enter text.
      tf = new JTextField(25);
      tf.setEditable(false);
      
      //Create panels and add buttons and text field
      JPanel p1 = new JPanel();
      p1.setBackground(Color.white);
      p1.add(button1);
      p1.add(button2);
      
      JPanel p2 = new JPanel();
      p2.setBackground(Color.white);
      p2.add(tf);
      
      //Get the content pane and add the panels
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(p1, BorderLayout.NORTH);
      getContentPane().add(p2, BorderLayout.SOUTH);
      
      addWindowListener(new WinClosing());
      setBounds(100, 100, 300, 100);
      setVisible(true);
      
      } // close constructor
      
      //MouseHandler handles the mouse events and 
      //extends an adapter class that provides empty 
      //methods. This MouseHandler class overrides the  
      //mouseEntered and mouseExit methods.
      class MouseHandler extends MouseAdapter
       {
         public void mouseEntered(MouseEvent me)
           {
             //When the mouse moves over a button, the 
             //name is captured and set in the text field.
             tf.setText("Mouse is over 
                 "+me.getComponent().getName());
            }
         public void mouseExited(MouseEvent me) 
           {
             //When the mouse exits the button area, 
             //the text field is set to no text.
             
             tf.setText("");
           }
       }// close MouseHandler
       
      public static void main(String args[])
       {
        MouseAdapterExample mae = new MouseAdapterExample();
        }
     }
     //This class also extends an adapter class and 
     //overrides only one method: windowClosing. Instead  
     //of using this class for window closing, you can 
     //instead add one line to your code: 
     //setDefaultCloseOperation(EXIT_ON_CLOSE); as shown  
     //in the SelectMe example above.
     class WinClosing extends WindowAdapter
      {
        public void windowClosing(WindowEvent we)
         {
           System.exit(0);
          }
       }

MouseAdapter

Making Sense of the Java Class Libraries

KeyListener Interface and Abstract KeyAdapter Class

Key events tell you when a user is typing at the keyboard. The KeyListener interface is used for receiving these types of keyboard events. Listener objects are registered with a component, such as a window or panel, using the component's addKeyListener method. The relevant method in the listener object is invoked, and the KeyEvent is passed to it.

A class that is interested in processing a keyboard event either implements this interface and all the methods it contains, or it extends the abstract KeyAdapter class. By extending the abstract KeyAdapter class, you can override only the methods relevant to your application's needs.

As an example, the following application creates an object that listens for a key typed. When the user types a key, the key typed is set in a label at the bottom of the screen:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class KeyAdapterExample extends JFrame
  {
    //Label to display the character typed.
    JLabel label;
    //Panel to mouse over and type character 
    JPanel p;
    
      public KeyAdapterExample ()
       {
         label = new JLabel("You typed: ");
         
         p = new JPanel();
         p.setBackground(Color.white);
         //Register for key typed
         p.addKeyListener(new KeyHandler());
         //Register to mouse over the blank panel.
         p.addMouseListener(new MyMouseAdapter(p));
         
         //Get the content pane and set layout.
         getContentPane().setLayout(new BorderLayout());
         getContentPane().add(p, BorderLayout.CENTER);
         getContentPane().add(label, BorderLayout.SOUTH);
         //Register to exit program
         addWindowListener(new WinClosing());
         setBounds(100, 100, 200, 200);
         setVisible(true);
        } //close constructor
     
     //Class to handle the typing of keys   
    class KeyHandler extends KeyAdapter
     {
       //Method to get the character typed and
       //set it on the label.
       public void keyTyped(KeyEvent ke)
         {  
           label.setText("You typed: " + ke.getKeyChar());
           label.invalidate();
           invalidate();
           validate();
           }
      }
     //Class to handle mousing over the panel 
     class MyMouseAdapter extends MouseAdapter
       {
         MyMouseAdapter (Component c)
           {
             this.c = c;
            }
          public void mousePressed(MouseEvent e)
           {
             c.requestFocus();
           }
           
           private Component c;
        }
      
    public static void main(String args[])
      {
        KeyAdapterExample kae = new KeyAdapterExample();
       }
     }

    class WinClosing extends WindowAdapter 
    
     {
       public void windowClosing(WindowEvent we)
         {
           System.exit(0);
         }
      }

KeyAdapter

Program Challenge

Create the JustWindows Application

  • Create a draggable JWindow.
  • Have the window display its current position to the console when it is dragged.
  • Close the window on double-click of the mouse.

See a possible solution to Challenge:

For More Information

Event Handling

Lesson: Writing Event Listeners

Lesson: Swing Features and Concepts

How to Write a Mouse Listener

Building an Application Introduction, Part 3

Program Challenge Solution

See one possible solution to the June Program Challenge:

Downloading the Java 2 Platform

For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the J2SE development kit.

IMPORTANT: Please read our Terms of Use and Privacy policies:

Copyright 2002 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA

FEEDBACK

Tell us what you think of this supplement.

Duke

 Very worth reading  Worth reading  Not worth reading

If you have other comments or ideas for future technical content, please type them here:

Have a question about programming? Use Java Online Support.

- Note -

Sun respects your online time and privacy. The Java Developer Connection mailing lists are used for internal Sun Microsystems purposes only. You have received this email because you elected to subscribe.

- Subscribe/Unsubscribe -

To subscribe, go to the subscriptions page, choose the newsletters you want to subscribe to and click Update

To unsubscribe, go to the subscriptions page, uncheck the appropriate check box, and click Update

This document is protected by copyright.

Java Technology Fundamentals
August 2002

Sun, Sun Microsystems, Java, J2SE are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.