CpSc 124 - Spring 2003

Lab 11: Applets and Events


In todays lab, you will write two different applets. The first applet, you will write from scratch. You may look at the examples in section 6.1 of the text to see the general outline of an applet. For the second applet you will learn some new ideas and will modify the source code for an applet that is already provided.

The files for today's lab can be found in the directory /home/cs124/lab11, which you should copy into your account. You should read the two small blurbs below and then move on to the exercises.


A Little Knowledge

It's annoying to keep making small .html files just to test your applets. Here's something you can do about that, but if you do this, make sure that you understand what you are doing, or you will confuse yourself.

The appletviewer will actually take any kind of file. It doesn't have to be an .html file. It only has to contain a valid <applet> tag. The trick is to put the applet tag in a comment in your .java file. For example, this might look like:

     /*
        <applet code="SillyButton.class" width=300 height=200>
        </applet>
     */

The java compiler will ignore this since it is in a comment, but if you apply appletviewer to the .java file -- for example, appletviewer SillyButton.java -- then appletviewer will find the applet tag and run the applet. You don't need a separate .html file.


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. The project can be either an applet or a stand-alone program. You now have an idea of many of the capabilities of Java that you might use in a final project. The major things that we still have to cover are: More on using GUI components, including buttons, text-input boxes, scrollbars, and so on; 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 exercise 2 below) 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.


Exercises

Here are the exercises that you should do for this week's lab report. The report (consisting as usual of a2ps printouts) is due in class next Wednesday, April 9. Your applets should be placed on your web pages and available at that time. Don't forget to copy all the necessary supporting files to your ~/www directory.

Exercise 1: A Simple Button Applet 

In this exercise, you will add a button to an applet and make the applet respond when the button is pressed. When a button is pressed, it generates an ActionEvent. We haven't fully discussed this in class yet, but there is a very good example in the book in Section 6.1 which you should have read by now. If you haven't, well it's time... Briefly, there are four things that you need to do to make an applet respond to button clicks: (1) import java.awt.event.* (in addition to java.awt.* and java.applet.*); (2) declare that the applet implements the ActionListener interface; (3) define an actionPerformed() method in the applet to respond to clicks on the button; and (4) register the applet to listen for ActionEvents from the button by calling button.addActionListener(this), where button is a variable that refers to the Button. In addition, to get the button to actually appear in the applet, you have to use the applet's add() method to add the button to the applet.

Besides working with a button, in this exercise you'll learn a bit about doing "layout." Usually, applets and other containers use layout managers to manage the sizes and positions of the components that they contain. With a layout manager, all you do is add the component to the applet. The layout manager decides where to put the component and how big to make it. There are a lot of advantages to this system, especially when the applet can change size. However, using layout managers can be tricky (and we will cover them in more detail later). Conceptually, it's easier to do the layout by hand. For this to work, you have to get rid of the layout manager that the applet uses by default. To do this, add the statement

          setLayout(null);

to the init() method of the applet. You are now responsible for setting the size and position of any component that you add to the applet by calling the component's setBounds(x,y,width,height) method. You can do this in the init() method as well. For example, if button refers to a Button, you can call

          button.setBounds(10,20,100,30);

to put the Button's upper left corner at (10,20) and to make the button 100 pixels wide and 30 pixels high. You can compute the values of the parameters, if you want. For example, if you want the upper left corner to be at (a,b), you would just call button.setBounds(a,b,100,30).

Now, there is nothing to stop you from moving the button elsewhere in the applet. You just have to call setBounds() again. That is your assignment for this exercise: Write an applet that contains a button that jumps to a randomly selected location when you click on it. Here is an applet that does this:

The button should start out at the center of the applet, and when it jumps, it should remain entirely within the applet. Ideally, you should ensure that the new position of the button does not intersect the old position, but I will give extra credit for this, since the calculation is a little tricky. (The idea is to keep selecting possible random positions until you get one that doesn't intersect the current position.)

Exercise 2: Saving an Applet's State  

Now it was not required in the exercise above that you take care of making sure that the applet properly redraws itself if it's covered up with another window and then uncovered. When an applet is covered and then uncovered, 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, which we haven't talked about yet. 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()). (Note that the cards and the message are not buttons, which is why you can't use the ActionListener interface as you could on the exercise above.)

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. The "state" of an applet can consist of more than just information for redrawing the applet. It can also include the state that a game is in (if the applet represents a game for example). 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.


Scotty Orr
Last modified: Thu Apr 3 09:27:22 EST 2003