sepbar-1.gif (3106 bytes)

Java 107 : Simple event handling

Written by David Reilly, February 21, 1998

sepbar-1.gif (3106 bytes)

Previous | Next

In the last tutorial we wrote one of the simplest applets possible, the proverbial "Hello World". It didn't actually do anything, except for displaying a text string. Now we'll learn how to write an applet that responds to user input, and introduces us to AWT event handling. We'll focus on JDK1.02 event handling for the moment, as there are plenty of web browsers out there that don't support the new JDK1.1 event handling model.

The tutorial contains two applets, and three source code files :-

disk.gif (1333 bytes) AWTEventDemo.java
disk.gif (1333 bytes) AWTEventDemo2.java
disk.gif (1333 bytes) NumberTextField.java

Responding to events

We can make our applet respond to user input by overriding event handler methods in our applet. There are a variety of event handler methods, as the first example shows. In this demonstration, the applet will display a string, which is modified by each event. The user can move his or her mouse over the applet, click on the applet, and move out of the applet.

Applet not displayed - requires a Java enabled browser

Under the JDK1.02 event model, components are notified of events by the invocation of a method that matches a specific signature. Applets can override these methods as well - providing customised event handlers to respond to the actions of a user. An example of this is shown below, where an overridden mouseMove method responds to user events.

public boolean mouseMove( Event evt, int x, int y)
{
	// Set message....
	message = "mouseMove - x:" + x + " y: " + y;

	// ... and repaint applet
	repaint();

	// Signal we have handled the event
	return true;
}

In this method, we simply change the value of a member variable (message), and assign to it data specific to the event. We call the repaint method, and our text is displayed to the user. Our applet example responds to three different events (mouseMove, MouseExit, mouseDown), but there are many events a custom component can respond to. Table One shows the major ones for subclasses of AWT components, and Listing One the code for our example applet.

AWT Event Event signature
mouseDown mouseDown (Event evt, int x, int y)
mouseUp mouseUp (Event evt, int x, int y)
mouseEnter mouseEnter (Event evt, int x, int y)
mouseExit mouseExit (Event evt, int x, int y)
mouseMove mouseMove (Event evt, int x, int y)
mouseDrag mouseDrag (Event evt, int x, int y)
gotFocus gotFocus (Event evt, Object what)
lostFocus lostFocus (Event evt, Object what)
keyDown keyDown (Event evt, int key)
keyUp keyUp (Event evt, int key)
action action (Event evt, Object what)

Table 1.0 - Major AWT component events

Each event must return a boolean value (true or false), indicating whether the event should be made available to other event handlers. If you've processed an event (for example, keyDown) you might record the value, and return true to show that no other handlers should receive the event. If, however, your custom edit box can't process the character, it may want to return false to signal that other components (the panel or applet in which the component is hosted) should process it.



/*
 *
 * AWTEventDemo.java
 * Demonstration for Java 107 tutorial
 * David Reilly, 11 February, 1998
 *
 */

import java.awt.*;
import java.applet.*;

public class AWTEventDemo extends Applet
{
	private String message = "Waiting for events...";

        // Default constructor
        public void AWTEventDemo()
        {
                // Call parent constructor
                super();
        }

	// Init method, called when applet first initialises
	public void init()
	{
		setBackground( Color.white );
	}

        // Overridden paint method
        public void paint ( Graphics g )
        {
                g.setBackground ( Color.white );
                g.setColor   ( Color.blue );
                g.drawString ( "Hello world!", 0, size().height - 5);
        }

	// Overridden methods for event handling
	public boolean mouseEnter( Event evt, int x, int y)
	{
		// Set message....
		message = "mouseEnter - x:" + x + " y: " + y;

		// ... and repaint applet
		repaint();

		// Signal we have handled the event
		return true;
	}

	public boolean mouseExit( Event evt, int x, int y)
	{
		// Set message....
		message = "mouseExit - x:" + x + " y: " + y;

		// ... and repaint applet
		repaint();

		// Signal we have handled the event
		return true;
	}

	public boolean mouseMove( Event evt, int x, int y)
	{
		// Set message....
		message = "mouseMove - x:" + x + " y: " + y;

		// ... and repaint applet
		repaint();

		// Signal we have handled the event
		return true;
	}

	public boolean mouseDown( Event evt, int x, int y)
	{
		// Set message....
		message = "mouseDown - x:" + x + " y: " + y;

		// ... and repaint applet
		repaint();

		// Signal we have handled the event
		return true;
	}
}

Listing 1.0 - AWTEventDemo.java


Responding to events of other components

Responding to AWT events for an applet is an important part of applet programming - but a far more useful task is to respond to the events of components embedded within the applet itself. Buttons, textfields, checkboxes, selection lists and choice boxes added to your applet can all respond to user events. In this next example, we'll write a custom textfield, and add a button to an applet. We'll also write a custom action method, which will respond to the events of these two AWT components.

Before you begin, take a look at what we'll be building. A simple text box is displayed, that accepts only numbers. Our applet will also provide a button that will clear the text box contents when clicked.

This applet required a Java enabled browser

Creating a custom component - NumberTextField

As an example, we'll write a customised text field, that only accepts numerical data (0-9 . -), or the backspace/delete key. Any other data we can safely ignore, because it doesn't form part of a valid number. We start by extending java.awt.TextField, and then add a custom event handler for keyDown events.

public boolean keyDown(Event evt, int key)
{
	// Cast to a character
	char keyChar = (char) key;

	// Accept 0-9, . -, backspace or delete
	if ( ((keyChar > '0') && (keyChar < '9')) ||
		 (keyChar == '.') || (keyChar == '-') ||
		 (keyChar == 8 )  || (keyChar == 127) )
	{			
		// Pass along to our superclass
		return super.keyDown(evt, key);
	}
	else
		// Yes we've handled it... by ignoring invalid data
		return true;

}

As you can see, our event handler doesn't really do much. It is only responsible for input validation. If a number, minus key, decimal point, or backspace/delete is entered, then we pass it on to our superclass event handler (which will put accept the keypress and add it to the textbox). Otherwise it just returns true, indicating that the event has already been handled (and thus should not be processed elsewhere).

Creating an applet that responds to component events

The first thing our applet will have to do is create some actual components. This is done in our init method, which is called when the applet is first created. We create an instance of our NumberTextField class, and also a button which when clicked will clear the contents of our numerical text box. Finally, we add our components to the applet container, using a flow layout manager (layout managers control how a container is laid out, but this is beyond the scope of this tutorial).

Next, we add an action event handler, which checks to see if the event's target is equal to our 'clear' button. This is the most critical part of our applet, as we are responding to user events that occur in other components (namely the button). If it is indeed the clear button that has been activated, we clear the contents of the text box, and return true to indicate we've handled the event.


/*
 *
 * AWTEventDemo2.java
 * Demonstration for Java 107 tutorial
 * David Reilly, 21 February, 1998
 *
 */	

import java.awt.*;
import java.applet.*;

public class AWTEventDemo2 extends Applet
{
	// Private references to AWT components
	private NumberTextField numberField;
	private Button clear;

	// Init method, called when applet first initialises
	public void init()
	{
		setBackground( Color.white );

		// Set default layout manager
		setLayout(new FlowLayout() );
		
		// Create an instance of NumberTextField ....
		numberField = new NumberTextField (10);

		// ... and add it to our applet
		add(numberField);
		
		// Create an instance of button ....
		clear = new Button ("Clear");

		// ... and add it to our applet
		add(clear);
	}

	public boolean action (Event evt, Object what)
	{	
		// Was the focus of the event our button
		if (evt.target == clear)
		{
			// Clear the textfield
			numberField.setText("");

			// Event handled
			return true;
		}
		else
			return false;
	}
}

Listing 1.1 -  AWTEventDemo.java


import java.awt.*;
/*
 *
 * NumberTextField.java
 * Customised AWT component
 * Demonstration for Java 107 tutorial
 * David Reilly, 21 February, 1998
 *
 */

public class NumberTextField extends TextField
{	
	public NumberTextField(int cols)
	{
		super (cols);
	}

	public boolean keyDown(Event evt, int key)
	{
		// Cast to a character
		char keyChar = (char) key;

		// Accept 0-9, . -, backspace or delete
		if ( ((keyChar > '0') && (keyChar < '9')) ||
			 (keyChar == '.') || (keyChar == '-') ||
			 (keyChar == 8 )  || (keyChar == 127) )
		{			
			// Pass along to our superclass
			return super.keyDown(evt, key);
		}
		else
			// Yes we've handled it... by ignoring invalid data
			return true;
	}
}

Listing 1.2 -  NumberTextField.java


After reading through the example code, you should have a good understanding of simple AWT event handling. Those wishing to expand their knowledge further should consult the java.awt package API, and practice writing simple applets that respond to mouse clicks, button presses, and other forms of user input. In the next tutorial, we'll work more with the AWT, and look at some of the important features it provides for developing user interfaces.

Previous | Next

<-- Back to the Java Coffee Break