Written by David Reilly, February 21, 1998
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 :-
AWTEventDemo.java
AWTEventDemo2.java
NumberTextField.java
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.
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 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.
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).
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.