Teach Yourself Java in 21 Days tyj12x.htm

- Day 12

- Managing Simple Events and Interactivity

- Mouse Clicks

- mouseDown and mouseUp
- An Example Spots

- Mouse Movements

- mouseDrag and mouseMove
- mouseEnter and mouseExit
- (d)An Example Drawing Lines

- Keyboard Events

- The keyDown and keyUp Methods
- Default Keys
- An Example Entering, Displaying, and Moving Characters
- Testing for Modifier Keys

- The AWT Event Handler
- Summary
- Q&A

#
Day 12

## Managing Simple Events and Interactivity

by Laura Lemay

Java events are part of the Java AWT (Abstract Windowing Toolkit) package. An event is the way that the AWT communicates to you, as the programmer, and to other Java AWT components that something has happened. That something can be input from the user (mouse movements or clicks, keypresses), changes in the system environment (a window opening or closing, the window being scrolled up or down), or a host of other things that might, in some way, be interesting to the operation of the program.

Note: Java's Abstract Windowing Toolkit is a package of classes that implements most common UI components, such as windows, buttons, menus, and so on. It is also specifically the AWT, and not Java, that generates and manages events.

In other words, whenever just about anything happens to a Java AWT component, including an applet, an event is generated. Some events are handled by the AWT or by the browser without your needing to do anything. paint() methods, for example, are generated and handled by the browser—all you have to do is tell the AWT what you want painted when it gets to your part of the window. Some events, however—for example, a mouse click inside the boundaries of your applet—you may need to know about. Writing your Java programs to handle these kinds of events enables you to get input from the user and have your applet change its behavior based on that input.

Today, you'll learn about managing simple events, including the following basics:

- Mouse clicks
- Mouse movements, including mouse dragging
- Keyboard actions

You'll also learn about the handleEvent() method, which is the basis for collecting, handling, and passing on events of all kinds from your applet to other UI components in the window or in your applet itself. Tomorrow, you'll learn how to combine events with the AWT to create a complete interface for your applet.

### Mouse Clicks

Let's start with the most common event you might be interested in: mouse clicks. Mouse-click events occur when your user clicks the mouse somewhere in the body of your applet. You can intercept mouse clicks to do very simple things—for example, to toggle the sound on and off in your applet, to move to the next slide in a presentation, or to clear the screen and start over—or you can use mouse clicks in conjunction with mouse movements to perform more complex motions inside your applet.

#### mouseDown and mouseUp

When you click the mouse once, the AWT generates two events: a mouseDown event when the mouse button is pressed, and a mouseUp event when the button is released. Why two individual events for a single mouse action? Because you may want to do different things for the "down" and the "up." For example, look at a pull-down menu. The mouseDown extends the menu, and the mouseUp selects an item (with mouseDrags between—but you'll learn about that one later). If you have only one event for both actions (mouseUp and mouseDown), you cannot implement that sort of user interaction.

Handling mouse events in your applet is easy—all you have to do is override the right method definition in your applet. That method will be called when that particular event occurs. Here's an example of the method signature for a mouseDown event:

    public boolean mouseDown(Event evt, int x, int y) {

    ...

    }

The mouseDown() method (and the mouseUp() method as well) takes three parameters: the event itself and the x and y coordinates where the mouseDown or mouseUp event occurred.

The event argument is an instance of the class Event. All system events generate an instance of the Event class, which contains information about where and when the event took place, the kind of event it is, and other information that you might want to know about this event. Sometimes having a handle to that event object is useful, as you'll discover later on in this section.

The x and the y coordinates of the event, as passed in through the x and y arguments, are particularly nice to know because you can use them to determine precisely where the mouse click took place.

For example, here's a simple method that prints out information about a mouseDown when it occurs:

    public boolean mouseDown(Event evt, int x, int y) {

        System.out.println("Mouse down at " + x + "," + y);

        return true;

    }

By including this method in your applet, every time your user clicks the mouse inside your applet, this message will get printed.

Note that this method, unlike the other system methods you've studied this far, returns a boolean value instead of not returning anything (void). This will become important tomorrow when you create user interfaces and then manage input to these interfaces; having an event handler return true or false determines whether a given UI component can intercept an event or whether it needs to pass it on to the enclosing component. The general rule is that if your method deals with the event, it should return true, which for the focus of today's lesson is almost always the case.

The second half of the mouse click is the mouseUp() method, which is called when the mouse button is released. To handle a mouseUp event, add the mouseUp() method to your applet. mouseUp() looks just like mouseDown():

    public boolean mouseUp(Event evt, int x, int y) {

        ....

    }

#### An Example Spots

In this section, you'll create an example of an applet that uses mouse events—mouseDown events in particular. The Spots applet starts with a blank screen and then sits and waits. When you click the mouse on that screen, a blue dot is drawn. You can place up to ten dots on the screen. Figure 12.1 shows the Spots applet.

Figure 12.1. The Spots applet.

Let's start from the beginning and build this applet, starting from the initial class definition:

    import java.awt.Graphics;

    import java.awt.Color;

    import java.awt.Event;

    public class Spots extends java.applet.Applet {

        final int MAXSPOTS = 10;

        int xspots[] = new int[MAXSPOTS];

        int yspots[] = new int[MAXSPOTS];

        int currspots = 0;

    }

This class uses three other AWT classes: Graphics, Color, and Event. That last class, Event, needs to be imported in any applets that use events. The class has four instance variables: a constant to determine the maximum number of spots that can be drawn, two arrays to store the x and y coordinates of the spots that have already been drawn, and an integer to keep track of the number of the current spot.

Note: This class doesn't include the implements Runnable words in its definition. As you'll see later on as you build this applet, it also doesn't have a run() method. Why not? Because it doesn't actually do anything on its own—all it does is wait for input and then do stuff when input happens. There's no need for threads if your applet isn't actively doing something all the time.

Let's start with the init() method, which has one line, to set the background to white:

    public void init() {

            setBackground(Color.white);

    }

Set the background here, instead of in paint(), because paint() is called repeatedly each time a new spot is added. Because you really need to set the background only once, putting it in the paint() method unnecessarily slows down that method. Putting it here is a much better idea.

The main action of this applet occurs on the mouseDown() method, so let's add that one now:

    public boolean mouseDown(Event evt, int x, int y) {

        if (currspots < MAXSPOTS)

                addspot(x,y);

            else System.out.println("Too many spots.");

            return true;

    }

When the mouse click occurs, the mouseDown() method tests to see whether there are less than ten spots. If so, it calls the addspot() method (which you'll write soon). If not, it just prints an error message. Finally, it returns true, because all the event methods have to return a boolean value (usually true).

What does addspot() do? It adds the coordinates of the spot to the arrays that store the coordinates, increments the currspots variable, and then calls repaint():

    void addspot(int x, int y) {

            xspots[currspots] = x;

            yspots[currspots] = y;

            currspots++;

            repaint();

        }

You may be wondering why you have to keep track of all the past spots in addition to the current spot. The reason is because of repaint(): each time you paint the screen, you have to paint all the old spots in addition to the newest spot. Otherwise, each time you painted a new spot, the older spots would get erased. Now, on to the paint() method:

    public void paint(Graphics g) {

        g.setColor(Color.blue);

        for (int i = 0; i < currspots; i++) {

            g.fillOval(xspots[i] -10, yspots[i] - 10, 20, 20);

        }

    }

Inside paint, you just loop through the spots you've stored in the xspots and yspots arrays, painting each one (actually, painting them a little to the right and upward so that the spot is painted around the mouse pointer rather than below and to the right).

That's it! That's all you need to create an applet that handles mouse clicks. Everything else is handled for you. You have to add the appropriate behavior to mouseDown() or mouseUp() to intercept and handle that event. Listing 12.1 shows the full text for the Spots applet.

Listing 12.1. The Spots applet.

     1: import java.awt.Graphics;

     2: import java.awt.Color;

     3: import java.awt.Event;

     4:

     5: public class Spots extends java.applet.Applet {

     6:

     7: final int MAXSPOTS = 10;

     8:     int xspots[] = new int[MAXSPOTS];

     9:     int yspots[] = new int[MAXSPOTS];

    10:     int currspots = 0;

    11:

    12:     public void init() {

    13:         setBackground(Color.white);

    14:     }

    15:

    16:     public boolean mouseDown(Event evt, int x, int y) {

    17:         if (currspots < MAXSPOTS)

    18:             addspot(x,y);

    19:         else System.out.println("Too many spots.");

    20:         return true;

    21: }

    22:

    23:     void addspot(int x,int y) {

    24:         xspots[currspots] = x;

    25:         yspots[currspots] = y;

    26:         currspots++;

    27:         repaint();

    28:     }

    29:

    30:     public void paint(Graphics g) {

    31:         g.setColor(Color.blue);

    32:         for (int i = 0; i < currspots; i++) {

    33:             g.fillOval(xspots[i] - 10, yspots[i] - 10, 20, 20);

    34:         }

    35:     }

    36: }

### Mouse Movements

Every time the mouse is moved a single pixel in any direction, a mouse move event is generated. There are two mouse movement events: mouse drags, where the movement occurs with the mouse button pressed down, and plain mouse movements, where the mouse button isn't pressed.

To manage mouse movement events, use the mouseDrag() and mouseMove() methods.

#### mouseDrag and mouseMove

The mouseDrag() and mouseMove() methods, when included in your applet code, intercept and handle mouse movement events. The mouseMove() method, for plain mouse pointer movements without the mouse button pressed, looks much like the mouse-click methods:

    public boolean mouseMove(Event evt, int x, int y) {

        ...

    }

The mouseDrag() method handles mouse movements made with the mouse button pressed down (a complete dragging movement consists of a mouseDown event, a series of mouseDrag events for each pixel the mouse is moved, and a mouseUp even when the button is released). The mouseDrag() method looks like this:

    public boolean mouseDrag(Event evt, int x, int y) {

        ...

    }

#### mouseEnter and mouseExit

Finally, there are the mouseEnter() and mouseExit() methods. These two methods are called when the mouse pointer enters the applet or when it exits the applet. (In case you're wondering why you might need to know this, it's more useful on components of user interfaces that you might put inside an applet. You'll learn more about UI tomorrow).

Both mouseEnter() and mouseExit() have similar signatures—three arguments: the event object and the x and y coordinates of the point where the mouse entered or exited the applet.

    public boolean mouseEnter(Event evt, int x, int y) {

        ...

    }

    public boolean mouseExit(Event evt, int x, int y) {

        ...

    }

#### (d)An Example Drawing Lines

Examples always help to make concepts more concrete. In this section you'll create an applet that enables you to draw straight lines on the screen by dragging from the startpoint to the endpoint. Figure 12.2 shows the applet at work.

Figure 12.2. Drawing Lines.

As with the Spots applet (on which this applet is based), let's start with the basic definition and work our way through it. Listing 12.2 shows the top of the Lines applet.

Listing 12.2. The top of the Lines applet.

     1: import java.awt.Graphics;

     2: import java.awt.Color;

     3: import java.awt.Event;

     4: import java.awt.Point;

     5:

     6: public class Lines extends java.applet.Applet {

     7:

     8:     final int MAXLINES = 10;

     9:     Point starts[] = new Point[MAXLINES]; // starting points

    10:     Point ends[] = new Point[MAXLINES];    // ending points

    11:     Point anchor;    // start of current line

    12:     Point currentpoint; // current end of line

    13:     int currline = 0; // number of lines

    14:

    15:     public void init() {

    16:         setBackground(Color.white);

    17:     }

    18:

Compared to Spots, this applet added a few extra things. Unlike Spots, which keeps track of individual integer coordinates, this one keeps track of Point objects. Points represent an x and a y coordinate, encapsulated in a single object. To deal with points, you import the Point class (line 4) and set up a bunch of instance variables that hold points:

- The starts array holds points representing the starts of lines already drawn.
- The ends array holds the endpoints of those same lines.
- anchor holds the starting point of the line currently being drawn.
- currentpoint holds the current endpoint of the line currently being drawn.
- currline holds the current number of lines (to make sure you don't go over MAXLINES).

Finally, the init() method (lines 15 through 17), as in the Spots applet, sets the background of the applet to white.

The three main events this applet deals with are mouseDown(), to set the anchor point for the current line, mouseDrag(), to animate the current line as it's being drawn, and mouseUp(), to set the ending point for the new line. Given that you have instance variables to hold each of these values, it's merely a matter of plugging the right variables into the right methods. Here's mouseDown(), which sets the anchor point:

    public boolean mouseDown(Event evt, int x, int y) {

        anchor = new Point(x, y);

        return true;

    }

While the mouse is being dragged to draw the line, the applet animates the line being drawn. As you drag the mouse around, the new line moves with it from the anchor point to the tip of the mouse. The mouseDrag event contains the current point each time the mouse moves, so use that method to keep track of the current point (and to repaint for each movement so the line "animates"):

    public boolean mouseDrag(Event evt, int x, int y) {

        currentpoint = new Point(x, y);

        repaint();

        return true;

    }

The new line doesn't get added to the arrays of old lines until the mouse button is released. Here's mouseUp(), which tests to make sure you haven't exceeded the maximum number of lines before calling the addline() method (described next):

    public boolean mouseUp(Event evt, int x, int y) {

        if (currline < MAXLINES)

            addline(x, y);

        else System.out.println("Too many lines.");

        return true;

    }

The addline() method is where the arrays of lines get updated and where the applet is repainted to take the new line into effect:

    void addline(int x, int y) {

        starts[currline] = anchor;

        ends[currline] = new Point(x, y);

        currline++;

        currentpoint = null;

        repaint();

    }

Note that in this line you also set currentpoint to null. Why? Because the current line you were drawing is over. By setting currentpoint to null, you can test for that value in the paint() method.

Painting the applet means drawing all the old lines stored in the starts and ends arrays, as well as drawing the current line in process (whose endpoints are in anchor and currentpoint, respectively). To show the animation of the current line, draw it in blue. Here's the paint() method for the Lines applet:

    public void paint(Graphics g) {

        // Draw existing lines

        for (int i = 0; i < currline; i++) {

            g.drawLine(starts[i].x, starts[i].y,

                ends[i].x, ends[i].y);

        }

        // Draw current line

        g.setColor(Color.blue);

        if (currentpoint != null)

            g.drawLine(anchor.x, anchor.y,

                currentpoint.x, currentpoint.y);

    }

In paint, when you're drawing the current line, you test first to see whether currentpoint is null. If it is, the applet isn't in the middle of drawing a line, so there's no reason to try drawing a line that doesn't exist. By testing for currentpoint (and by setting currentpoint to null in the addline() method), you can paint only what you need.

That's it—just 60 lines of code and a few basic methods, and you have a very basic drawing application in your Web browser. Listing 12.3 shows the full text of the Lines applet so that you can put the pieces together.

Listing 12.3. The Lines applet.

     1: import java.awt.Graphics;

     2: import java.awt.Color;

     3: import java.awt.Event;

     4: import java.awt.Point;

     5:

     6: public class Lines extends java.applet.Applet {

     7:

     8:     final int MAXLINES = 10;

     9:     Point starts[] = new Point[MAXLINES]; // starting points

    10:     Point ends[] = new Point[MAXLINES];    // endingpoints

    11:     Point anchor;    // start of current line

    12:     Point currentpoint; // current end of line

    13:     int currline = 0; // number of lines

    14:

    15:     public void init() {

    16:         setBackground(Color.white);

    17:     }

    18:

    19:     public boolean mouseDown(Event evt, int x, int y) {

    20:         anchor = new Point(x,y);

    21:         return true;

    22:     }

    23:

    24:     public boolean mouseUp(Event evt, int x, int y) {

    25:         if (currline < MAXLINES)

    26:             addline(x,y);

    27:         else System.out.println("Too many lines.");

    28:         return true;

    29:     }

    30:

    31:     public boolean mouseDrag(Event evt, int x, int y) {

    32:         currentpoint = new Point(x,y);

    33:         repaint();

    34:         return true;

    35:     }

    36:

    37:     void addline(int x,int y) {

    38:         starts[currline] = anchor;

    39:         ends[currline] = new Point(x,y);

    40:         currline++;

    41:         currentpoint = null;

    42:         repaint();

    43:     }

    44:

    45:     public void paint(Graphics g) {

    46:

    47:         // Draw existing lines

    48:         for (int i = 0; i < currline; i++) {

    49:             g.drawLine(starts[i].x, starts[i].y,

    50:                  ends[i].x, ends[i].y);

    51:         }

    52:

    53:         // draw current line

    54:         g.setColor(Color.blue);

    55:         if (currentpoint != null)

    56:             g.drawLine(anchor.x,anchor.y,

    57:             currentpoint.x,currentpoint.y);

    58:     }

    59: }

### Keyboard Events

Keyboard events are generated whenever users press a key on the keyboard. By using key events, you can get hold of the values of the keys they pressed to perform an action or merely to get character input from the users of your applet.

#### The keyDown and keyUp Methods

To capture a keyboard event, use the keyDown() method:

    public boolean keyDown(Event evt, int key) {

        ...

    }

The keys generated by keyDown events (and passed into keyDown() as the key argument) are integers representing ASCII character values, which include alphanumeric characters, function keys, tabs, returns, and so on. To use them as characters (for example, to print them), you need to cast them to characters:

    currentchar = (char)key;

Here's a simple example of a keyDown() method that does nothing but print the key you just typed in both its ASCII and character representation:

    public boolean keyDown(Event evt, int key) {

        System.out.println("ASCII value: " + key);

        System.out.println("Character: " + (char)key);

        return true;

    }

As with mouse clicks, each keyDown event also has a corresponding keyUp event. To intercept keyUp events, use the keyUp() method:

    public booklean keyUp(Event evt, int key)  {

       ...

    }

#### Default Keys

The Event class provides a set of class variables that refer to several standard nonalphanumeric keys, such as the arrow keys. If your interface uses these keys, you can provide more readable code by testing for these names in your keyDown() method rather than testing for their numeric values. For example, to test whether the up arrow was pressed, you might use the following snippet of code:

    if (key == Event.UP) {

        ...

    }

Because the values these class variables hold are integers, you also can use the switch statement to test for them.

Table 12.1 shows the standard event class variables for various keys and the actual keys they represent.

Table 12.1. Standard keys defined by the event class.

    Class Variable

    Represened Key

Event.HOME | The Home key
Event.END | The End key
Event.PGUP | The Page Up key
Event.PGDN | The Page Down key
Event.UP | The up arrow
Event.DOWN | The down arrow
Event.LEFT | The left arrow
Event.RIGHT | The right arrow

#### An Example Entering, Displaying, and Moving Characters

Let's look at an applet that demonstrates keyboard events. This one enables you to type a character, and it displays that character in the center of the applet window. You then can move that character around on the screen by using the arrow keys. Typing another character at any time changes the character as it's currently displayed. Figure 12.3 shows an example.

Figure 12.3. The Keys applet.

This applet is actually less complicated than the previous applets you've used. This one has only three methods: init(), keyDown(), and paint(). The instance variables are also simpler, because the only things you need to keep track of are the x and y positions of the current character and the values of that character itself. Here's the top of this class definition:

    import java.awt.Graphics;

    import java.awt.Event;

    import java.awt.Font;

    public class Keys extends java.applet.Applet {

        char currkey;

        int currx;

        int curry;

The init() method is responsible for three things: setting the background color, setting the applet's font (here, 36 point Helvetica bold), and setting the beginning position for the character (the middle of the screen, minus a few points to nudge it up and to the right):

        public void init() {

            currx = (size().width / 2) - 8;  // default

            curry = (size().height / 2) - 16;

            setBackground(Color.white);

            setFont(new Font("Helvetica", Font.BOLD, 36));

        }

Because this applet's behavior is based on keyboard input, the keyDown() method is where most of the work of the applet takes place:

    public boolean keyDown(Event evt, int key) {

       switch (key) {

             case Event.DOWN:

                 curry += 5;

                 break;

             case Event.UP:

                 curry -= 5;

                 break;

             case Event.LEFT:

                 currx -= 5;

                 break;

             case Event.RIGHT:

                 currx += 5;

                 break;

             default:

                 currkey = (char)key;

             }

             repaint();

             return true;

    }

In the center of the keyDown() applet is a switch statement that tests for different key events. If the event is an arrow key, the appropriate change is made to the character's position. If the event is any other key, the character itself is changed. The method finishes up with a repaint() and returns true.

The paint() method here is almost trivial; just display the current character at the current position. However, note that when the applet starts up, there's no initial character and nothing to draw, so you have to take that into account. The currkey variable is initialized to 0, so you paint the applet only if currkey has an actual value:

        public void paint(Graphics g) {

            if (currkey != 0) {

                g.drawString(String.valueOf(currkey), currx,curry);

            }

        }

Listing 12.4 shows the complete source for the Keys applet:

Listing 12.4. The Keys applet.

     1: import java.awt.Graphics;

     2: import java.awt.Event;

     3: import java.awt.Font;

     4:

     5: public class Keys extends java.applet.Applet {

     6:

     7:    char currkey;

     8:    int currx;

     9:     int curry;

    10:

    11:     public void init() {

    12:         currx = (size().width / 2) -8;  // default

    13:         curry = (size().height / 2) -16;

    14:

    15:         setBackground(Color.white);

    16:         setFont(new Font("Helvetica",Font.BOLD,36));

    17:     }

    18:

    19:     public boolean keyDown(Event evt, int key) {

    20:         switch (key) {

    21:         case Event.DOWN:

    22:             curry += 5;

    23:             break;

    24:         case Event.UP:

    25:             curry -= 5;

    26:             break;

    27:         case Event.LEFT:

    28:             currx -= 5;

    29:             break;

    30:         case Event.RIGHT:

    31:             currx += 5;

    32:             break;

    33:         default:

    34:             currkey = (char)key;

    35:         }

    36:

    37:         repaint();

    38:         return true;

    39:     }

    40:

    41:     public void paint(Graphics g) {

    42:         if (currkey != 0) {

    43:             g.drawString(String.valueOf(currkey), currx,curry);

    44:         }

    45:     }

    46: }

#### Testing for Modifier Keys

Shift, control, and meta are modifier keys. They don't generate key events themselves, but when you get an ordinary mouse or keyboard event, you can test to see whether those keys were held down when the event occurred. Sometimes it may be obvious—shifted alphanumeric keys produce different key events than unshifted ones, for example. For other events, however—mouse events in particular—you may want to handle an event with a modifier key held down differently from a regular version of that event.

The Event class provides three methods for testing whether or not a modifier key is held down: shiftDown(), metaDown(), and controlDown(). All return boolean values based on whether that modifier key is indeed held down. You can use these three methods in any of the event handling methods (mouse or keyboard) by calling them on the event object passed into that method:

    public boolean mouseDown(Event evt, int x, int y ) {

        if (evt.shiftDown())

             // handle shift-click

        else // handle regular click

    }

### The AWT Event Handler

The default methods you've learned about today for handling basic events in applets are actually called by a generic event handler method called handleEvent(). The handleEvent() method is how the AWT generically deals with events that occur between application components and events based on user input.

In the default handleEvent() method, basic events are processed and the methods you learned about today are called. To handle events other than those mentioned here, to change the default event handling behavior, or to create and pass around your own events, you need to override handleEvent() in your own Java programs. The handleEvent() method looks like this:

    public boolean handleEvent(Event evt) {

        ...

    }

To test for specific events, examine the ID instance variable of the Event object that gets passed in. The event ID is an integer, but fortunately, the Event class defines a whole set of event IDs as class variables that you can test for in the body of the handleEvent(). Because these class variables are integer constants, a switch statement works particularly well. For example, here's a simple handleEvent() method to print out debugging information about mouse events:

    public boolean handleEvent(Event evt) {

        switch (evt.id) {

        case Event.MOUSE_DOWN:

            System.out.println("MouseDown: " +

                    evt.x + "," + evt.y);

            return true;

        case Event.MOUSE_UP:

            System.out.println("MouseUp: " +

                    evt.x + "," + evt.y);

            return true;

        case Event.MOUSE_MOVE:

            System.out.println("MouseMove: " +

                    evt.x + "," + evt.y);

            return true;

        case Event.MOUSE_DRAG:

            System.out.println("MouseDown: " +

                    evt.x + "," + evt.y);

            return true;

        default:

            return false;

        }

    }

You can test for the following keyboard events:

- Event.KEY_PRESS is generated when a key is pressed (the same as the keyDown() method).
- Event.KEY_RELEASE is generated when a key is released.
- Event.KEY_ACTION and Event.KEY_ACTION_RELEASE are generated when a key is pressed and released.

You can test for these mouse events:

- Event.MOUSE_DOWN is generated when the mouse button is pressed (the same as the mouseDown() method).
- Event.MOUSE_UP is generated when the mouse button is released (the same as the mouseUp() method).
- Event.MOUSE_MOVE is generated when the mouse is moved (the same as the mouseMove() method).
- Event.MOUSE_DRAG is generated when the mouse is moved with the button pressed (the same as the mouseDrag() method).
- Event.MOUSE_ENTER is generated when the mouse enters the applet (or a component of that applet). You can also use the mouseEnter() method.
- Event.MOUSE_EXIT is generated when the mouse exits the applet. You can also use the mouseExit() method.

In addition to these events, the Event class has a whole suite of methods for handling UI components. You'll learn more about these events tomorrow.

Note that if you override handleEvent() in your class, none of the default event handling methods you learned about today will get called unless you explicitly call them in the body of handleEvent(), so be careful if you decide to do this. One way to get around this is to test for the event you're interested in, and if that event isn't it, to call super.handleEvent() so that the superclass that defines handleEvent() can process things. Here's an example of how to do this:

    public boolean handleEvent(Event evt) {

        if (evt.id == Event.MOUSE_DOWN) {

            // process the mouse down

            return true;

        } else {

            return super.handleEvent(evt);

        }

    }

### Summary

Handling events in Java's Abstract Windowing Toolkit (AWT) is easy. Most of the time, all you need to do is stick the right method in your applet code, and your applet intercepts and handles that method. Here are some of the basic events you can manage in this way:

- Mouse clicks—mouseUp() and mouseDown() methods for each part of a mouse click.
- Mouse movements—mouseMove() and mouseDrag() for mouse movement with the mouse button released and pressed, respectively, as well as mouseEnter() and mouseExit() for when the mouse enters and exits the applet area.
- keyDown() and keyUp() for when a key on the keyboard is pressed.

All events in the AWT generate an Event object; inside that object, you can find out information about the event, when it occurred, and its x and y coordinates (if applicable). You can also test that event to see whether a modifier key was pressed when the event occurred, by using the shiftDown(), controlDown(), and metaDown() methods.

Finally, there is the handleEvent()method, the "parent" of the individual event methods. The handleEvent() method is actually what the Java system calls to manage events; the default implementation calls the individual method events where necessary. To override how methods are managed in your applet, override handleEvent.

### Q&A

Q: In the Spots applet, the spot coordinates are stored in arrays, which have a limited size. How can I modify this applet so that it will drawn an unlimited number of spots?

A: You can do one of a couple things:
The first thing to do is test, in your addspot() method, whether the number of spots has exceeded MAXSPOTS. Then create a bigger array, copy the elements of the old array into that bigger array (use the System.arraycopy() method to do that), and reassign the x and y arrays to that new, bigger array.
The second thing to do is to use the Vector class. Vector, part of the java.util package, implements an array that is automatically growable—sort of like a linked list is in other languages. The disadvantage of Vector is that to put something into Vector, it has to be an actual object. This means you'll have to cast integers to Integer objects, and then extract their values from Integer objects to treat them as integers again. The Vector class allows you to access and change elements in the Vector just as you can in an array (by using method calls, rather than array syntax). Check it out.

Q: mouseDown() and mouseUp() seem to apply to only a single mouse button. How can I determine which button on the mouse has been pressed?

A: At the moment, you can't. AWT assumes that you're using only one mouse button, or if you have a mouse with multiple buttons, that you're using only the left one. Although this provides some limitations on the kinds of actions you can perform in your applet, it does provide a cross-platform solution. Remember— different systems have different mice, so writing your applet to do something specific with the right mouse button isn't a good idea if the people running your applet are using Macintoshes and have only one mouse button. If you really want to have different mouse actions perform different things, test for modifier keys in your mouseDown() and mouseUp() methods.

Q: What's a meta key?

A: It's popular in Unix systems, and often mapped to Alt on most keyboards. Because Shift and Ctrl are much more popular and widespread, it's probably a good idea to base your interfaces on those modifier keys if you can.

Q: How do I test to see whether the Return key has been pressed?

A: Return (line feed) is character 10; Enter (carriage return) is character 13. Note that different platforms may send different keys for the actual key marked Return. In particular, Unix systems send line feeds, Macintoshes send carriage returns, and DOS systems send both. So, to provide a cross-platform behavior, you may want to test for both line feed and carriage return.
The word from the Java team is that a Return is a Return is a Return regardless of the platform. However, at the time of this writing, it is questionable whether or not this is currently true in the Java developer's kit. You may want to check the API documentation for the Event class to see whether this has changed in the interim.

Q: I looked at the API for the Event class, and there are many more event types listed there than the ones you mention today.

A: Yes. The Event class defines many different kinds of events, both for general user input, such as the mouse and keyboard events you learned about here, and also events for managing changes to the state of user interface components, such as windows and scroll bars. Tomorrow, you'll learn about those other events.