Java, Java, Java!
Chapter 4:Input/Output: Designing the User Interface
In the Laboratory: CyberPetApplet

R. Morelli

©2006 Prentice-Hall


In the Laboratory: CyberPetApplet

The purpose of this lab exercise is to familiarize you with Java applets. You will make several modifications to extend the functionality of the CyberPetApplet class. The objectives of the lab are

Problem Description

Extend the CyberPet and CyberPetApplet classes by adding a third state to the pet simulation -- for example, thinking. The applet GUI should continue to display the CyberPet's name and current state as well as an image that depicts the pet's current state. It should also include command buttons for each of CyberPet's states.

Lab Exercise 1: Getting Set Up

Download the provided CyberPet.java and the CyberPetApplet.java source files. These files correspond to the programs developed in this chapter. Place both of these files into the same directory.

Compile and run CyberPetApplet to make sure it runs properly. If you are using JDK, you can compile both CyberPetApplet.java and CyberPet.java by simply typing

    javac CyberPetApplet.java

at the command line. The compiler will look for CyberPet.java in the same directory and will compile it automatically. To run the applet with JDK you will need an HTML file which contains the following applet tag:

   <APPLET CODE="CyberPetApplet.class" WIDTH=325 HEIGHT=75>
   </APPLET>

Assuming the HTML file is named CyberPetApplet.html, you can run it with the appletviewer by typing

    appletviewer CyberPetApplet.html

Lab Exercise 2: Resizing the Applet Window

Controlling the size of the applet's window is important because in this version of the program the applet's components appear in what's called a FlowLayout. Under this layout, components are just placed in the applet, one after another, in a row from left to right until there's no more room in the row. Then a new row is started.

The applet tag in PetApplet.html should contain WIDTH and HEIGHT parameters, which control the initial size of the applet. By carefully setting these values, you can exert some control over the applet's layout. Try changing both of these values, one at a time, and observing the effect it has on the appearance of the applet. Through trial and error find appropriate values for the applet's size.

Lab Exercise 3: Paying Attention to Java Syntax

Make each of the following changes to CyberPetApplet.java, one at a time, then recompile it and note the syntax  error that results. Copy the syntax error into your write-up for this lab with a brief note of what caused the error.

Lab Exercise 4: Tracing the Applet

CyberPetApplet inherits a number of methods from its superclasses. The main ones are

In addition to the above methods, which are inherited from Applet, our applets implement the ActionListener interface, so they also inherit the following method, which must be redefined in the applet.

Of these methods, CyberPetApplet redefines init() and implements actionPerformed(). Definitions for the other methods don't appear in CyberPetApplet.

Place a System.out.println("In method X") statement, where X is the name of the method, in each method of both the CyberPetApplet and CyberPet classes. Run the program and note the output that it produces. Write down the order of execution of the statements in CyberPetApplet and CyberPet for various actions, such as clicking on the eat button or the sleep button.

Lab Exercise 5: Paying Attention to Runtime Errors

Make each of the following changes, one at a time, to your program and then rerun it. Make a note of the semantic errors that occur and try to explain each error.

This last semantic  error is a very subtle one and is worth additional comment. Consider the example in Fig 1. The semantic error in this case is a scoping error. There are two variables with the same identifier. The first is the instance variable, whose scope  extends throughout the class. It has class scope . The second is the local variable declared within the init() method, the scope of which is limited to that method. Once the init() completes its execution, the local variable ceases to exist. Outside of the init() method, any references to b1 will refer to the instance variable. The problem here is that the instance variable was never instantiated. So there is no actual button associated with its name. In the actionPerformed() method, the reference to b1 is a reference to the instance variable, but there is no button on the applet that corresponds to this variable, because in the init() method, the local  variable's button was added to the applet.



Debugging Tip: Scope Error. Don't declare a component variable in the init() method. You won't be able to refer to it in the rest of the program.



  
Figure 1: A subtle semantic error occurs in this program because the instance Button b1 is never instantiated.
\begin{figure}
\rule{4.75in}{.05cm}
\scriptsize
\begin{verbatim}
import java.awt...
 ...ed()
} // SemanticError\end{verbatim}\normalsize\rule{4.75in}{.05cm}\end{figure}

Lab Exercise 6: Adding a New State to CyberPet

Add a third state to the CyberPet class and make the appropriate changes in the CyberPetApplet. Let's suppose you are adding a thinking state. You will need to create an instance variable for isThinking and a think() method, plus you need to revise the other access methods. All of these revisions would occur in the CyberPet.java file. In the CyberPetApplet.java file, you would need to add a third button to the applet. If you add a third button, you would need to revise the actionPerformed() method to handle clicks on the new button.

Lab Exercise 7: Adding Images to CyberPetApplet (optional)

Download the image files provided for this lab. There are three images: spidereat.gif, spidersleep.gif, and spiderthink.gif. Place them in the same directory as your source code (*.java) files.

Add images to the applet that correspond to CyberPet's three states. Follow the example shown in this chapter. There are two modifications that must be made to that example. First, the paint() method should draw the image that corresponds to CyberPet's current state:

    public void paint(Graphics g)
    {
        String petState = pet1.getState();        // Get pet1's state
        if (petState.equals("Eating"))            // Draw the appropriate image
            g.drawImage(eatImage, 20, 100, this);
        else if ( petState.equals("Sleeping"))
            g.drawImage(sleepImage, 20, 100, this);
        else if ( petState.equals("Thinking"))
            g.drawImage(sleepImage, 20, 100, this);
    }

Finally, it is necessary to repaint() the applet after each button click. To do this you would add the following statement at the end of your actionPerformed() method:

    repaint(); // Call the paint() method

The repaint() method just calls the applet's paint() method. The reason that paint(Graphics) is not called directly here is because it requires a Graphics parameter, which is not directly available to the actionPerformed() method. The repaint() method takes care of getting the applet's Graphics object and passing it to paint(), so the images can be displayed on it.



Ralph Morelli {Faculty}
12/22/1999