CPSC 124, Fall 2001
Lab 9: Applets and Events

Applets are objects that have methods to respond to various events. For example, an applet has an init() method that is called when the applet is first created. By defining this method, you say how the applet should initialize itself. An applet has a paint() method that is called when the applet needs to be drawn or redrawn. When you define the paint method, you say how the applet should draw itself. As we will see in this lab, you can also add methods to an applet to say how it will respond to other types of events, such as when the user clicks on the applet with the mouse. For all these methods, you don't call the method. The system will do that when it's appropriate. All you can do is define what should happen when the method is called. This is the essence of object-oriented thinking, and you will probably find that it takes some time to get used to it. This lab is supposed to introduce some of the ideas that you need to understand.

The files for this lab can be found in the directory /home/cs124/lab9. Begin by copying this directory into your own account, and cd into your copy of the directory.

The lab is due next Wednesday, October 31. Please make a printout of your Java source code files for Exercises 1 and Exercise 2, and add your applets to your CS124 Web site.


Exercise 1: Mousing around

For the first exercise of the lab, you will be working with the applet defined in the file MouseDemo1.java. Here is an instance of that applet:

If you click-and-drag on the applet, you will draw a thick blue curve. If you right-click the applet, you will clear any drawing you've done. "Clicking" and "dragging" are examples of events. This is the first applet you've seen that reacts to user events. Section 6.4 of the text explains how to set up an applet so that it can process mouse-related events. You don't need to know all the details right now, since the setup has already been done for you in this case. You do need to know that the system calls certain methods in the applet to tell it to handle each event. There are seven kinds of events that can be generated by the mouse, and each type of event is handled by a different method:

Each of the subroutines has a parameter of type MouseEvent. The parameter value is provided by the system when it calls the method. The parameter is an object that holds information about the event. For example, if evt is the name of the parameter, then evt.getX() is the horizontal coordinate of the mouse's position and evt.getY() is the vertical coordinate of the mouse's position. And evt.isMetaDown() is a boolean that tells whether the user is pressing the right mouse button (or, on Macintosh, pressing the mouse button while holding down the Command key).

In my MouseDemo1.java, I defined MousePressed so that it clears the drawing. This is done by calling repaint(). (The repaint() method tells the system to clear the applet and call the applet's paint() method, and in this applet, the paint method doesn't do anything except draw a border around the applet, so calling repaint() effectively clears the applet.) I also define mouseDragged so that it draws a blue oval centered on the current mouse position. It's important to understand how the drawing is done. The mouseDragged method draws just one single oval. As the user drags the mouse, the system will call mouseDragged over and over as the mouse is moved. Each time it's called, it draws another oval at the new mouse location. You see the sequence of ovals as a curve, but if you move the mouse quickly you will see the separate ovals. There is no loop in the program to draw the curve, and you have no control over how and when the methods will be called. Aside from mousePressed and mouseDragged, the other mouse methods don't do anything.

When the mouseDragged method wants to draw an oval on the applet, it needs a Graphics object to do so. For the paint() method, the system provides a Graphics object automatically. But for mouseDragged to do any painting in the applet, it must obtain a Graphics object by calling the getGraphics() method. The typical way to do drawing outside the paint() method is with some code of the form:

      Graphics g = getGraphics();
         .
         . // use g to draw in the applet
         .
      g.dispose();

The "g.dispose()" is good form, to tell the system that you are finished using the graphics object.


Your assignment is to modify MouseDemo1.java. First, you should modify it so that it uses one or more of the other mouse events in an interesting way. Some examples of this are: (1) Have mouseMoved set a random background color and call repaint() so that the applet flashes random colors as the user moves the mouse over it. (2) Draw red dots in mouseMoved. (3) Clear the applet when the user releases the mouse button. (4) Change the background color and repaint the applet when the mouse enters or leaves the applet.

A second part of the assignment is to modify the drawing so that instead of drawing blue ovals, it draws randomly colored ovals as the user drags the mouse. Alternatively, or additionally, you can modify the applet so that it draws a symmetric pattern of dots: Instead of drawing a single dot with center (x,y), draw four dots with centers at (x,y), (x,getSize().height-y), (getSize().width-x,y) and (getSize().width,getSize().height-y).

Here is a method that generates a random color:

         Color randomColor() {
            return 
               new Color(
                     (int)(256*Math.random()),
                     (int)(256*Math.random()),
                     (int)(256*Math.random())
               );
         }

If you want to do something extra for this lab, possibly for a little extra credit, you should come back after doing Exercise 2 and do something that requires saving state. This means that you will have to introduce an instance variable to save some aspect of the state of the applet. You will have to use that variable in your drawing operation. And you will have to change that variable in the appropriate methods. Here is one example. In this version of the applet, as you draw a very long curve, the color of the dots changes from bright red to dark red. When you start drawing another curve, the color changes back to bright red again:


Exercise 2: Save the State

The MouseDemo1 applet is a "bad" applet in the sense that it does not properly redraw itself if you cover it up with another window and then uncover it. When you do this, the system calls the applet's paint() method so it can redraw itself. A "good" applet keeps enough information in its instance variables so that it can redraw itself on demand. The instance variables record the state of the applet. The methods of the applet, such as the paint() method, can look at the instance variables to find out the current state. Methods can also change the state of the applet by changing the values of the instance variables. Here is an applet that keeps track of its current state. If you cover it with another window and uncover it, the cards and message will be properly redrawn:

This applet is defined in the file CardsDemo.java.

The state of the applet is stored in five variables of type Card and a variable of type String that holds the message displayed at the bottom of the applet. The paint method uses these variables to decide what to draw. Other methods in the applet change the values of these variables and then call repaint() so that the applet will be redrawn to reflect the new state.

This applet responds to mouse events. When the user clicks the mouse on a card or on the message, the mousePressed method calls one of the subroutines clickedCard(cardNum) or clickedMessage() to respond to the mouse click. If you click on a card, the clickedCard() method turns it face down. This is done simply by setting the value of the appropriate Card variable to null and calling repaint(). (Card variables with value null are displayed as face-down cards.) If you click on the message, the clickedMessage() method deals a new hand by calling the deal() method (which in turn calls repaint()).

This applet is not complete as it stands. What I want is an applet that simulates the slot machine game VideoPoker. In video poker, the user is dealt a hand of five cards. The user selects cards to be discarded. Then the user should get new cards just to replace the discarded cards. The object is to have a good poker hand after drawing the cards. (In a real slot machine game, the user would receive a pay-off that depends on the hand.) At this point, the user can begin a new game and be dealt five new cards. Here is an applet that works in this way. Note that the message on the bottom of the applet changes when the user draws the card and when the user deals the card:

Your assignment is to improve CardsDemo.java so that it works like the second version of the applet. This applet can be in one of two basic states: Either the game is in progress, and the user is able to select cards to be discarded. Or the game is over, and the user can only look at the final hand and begin a new game. So far, there is no instance variable in the applet for keeping track of this basic aspect of the state. Add an instance variable to keep track of whether the game is in progress or is over. (It could be of type boolean, for example.) This aspect of the state changes when the user clicks the message at the bottom of the applet. Write a draw() method for the applet. This method is similar to the deal() method that already exists, but it only replaces the cards that have been discarded, and it changes the message to read "Deal a new hand". Modify the clickedMessage() and clickedCard() methods so that they behave differently depending on whether the game is in progress or is over. (It should not be possible for the user to discard cards after the game is over.)

If you are looking for a little extra credit on this one, here is an idea: The user might accidently click a card and discard it unintentionally. It would be nice to be able to get it back by clicking on the discarded card. Modify the applet so that the user can turn a discarded card face up again by clicking on it. But remember, it has to be the same card that the user was dealt in the first place.

Coming up: Final Project

It's about time for you to start thinking about your final project for this course. The final project is a program that you select and design yourself, or in a group of two or three students. The project can be either an applet or a stand-alone program. You now have an idea of most of the capabilities of Java that you might use in a final project. The major things that we still have to cover are: using GUI components such as buttons and text-input boxes and using arrays to store lists or grids of values.

An example of a final project would be a more real version of a video poker slot machine in which the user could make bets and receive payoffs. The hard part of such an applet is to determine what type poker hand the user has at the end of the game (three of a kind, flush, straight, full house, etc.). An example of a less conventional project would be do a portfolio of interactive and animated "applet art." Soon, I will give out a list of other suggestions for final projects, but it would be nice if you could think up a project on your own. I encourage you to discuss your ideas with me at any time.


David Eck, 26 October 2001