Lab 9: Graphics and Inheritance
CPS 1 - Duke University


Lab 9 Reference Sheet
Lab 9 Graphics Worksheet
Lab 9 Example

Overview

This lab lets you have fun with Java's rich graphics features while exploring the important idea of inheritance in programming. At the end of the lab period, you should have fish of your own design swimming in the aquarium you saw in lecture. For a look at what you're shooting for, click here.

You will write three classes for this lab (don't be alarmed -- they're not long), and copy one other class that you will modify.:

  1. The applet.  As always, the applet creates the things that need to show up on the screen, puts them together in the right way, and responds when a user presses a button.
  2. The Fish class itself   This is the one you're copying; the part you may modify is how it's drawn.
  3. A subclass of Fish   You've already seen an example of this in lecture: the GillFish class. This will inherit all the features of your basic class, then add to them.
  4. A subclass of the subclass   Example from lecture: FinFish. This carries over everything from your first subclass (which in turn carried over everything from Fish), and adds new stuff to it.

At the request of several people in this class, there is now a reference page that lists the important methods for the classes you will be using in the lab, along with any Unix commands you need to use. The reference page for this lab contains a summary of the Aquarium and DrawingPad classes that are used, along with a summary of the cd and cp Unix commands.

Getting Started

You should begin this lab by starting up your X windows program and getting a telnet window on your screen like you have for the other labs. Make sure you switch to your "public_html" directory like you usually do by typing:

cd public_html
There has been some confusion over the alias command and the ln command that you had to type back in lab 2, you should note that you do not have to type those each time you start up, all you need to do each time is the cd public_html command. To find out a little more about the cd command, you can check out th UNIX commands on the reference sheet.

Fish Class

First, you'll create a basic fish so you'll have something to test your program on later. To help things go along a little faster, a simple version of the Fish class is already typed up, you'll need to make some modifications to it later on in the lab, but for now you can use it as is. To copy the file to your public_html directory, type the following command into your telnet window:

cp ~srr1/public_html/Fish.java ~/public_html/Fish.java
The command "cp" above is the copy command. The first part after that, in red, tells the computer where you are getting the file from. In this case, you're getting it from the files of the user srr1 (because that's what's after the tilda and before the slash). The file is in the directory "cps1" which is in the directory "public_html". The name of the file you want to get is "Fish.java". The second part of the copy command, in blue, tells the computer where you want to copy the file to. In this case you are copying it to your files (because you don't list any other user after the tilde and before the slash). You are putting it in your "public_html" directory, and saving it as "Fish.java". For more on this check out the UNIX commands section of the reference sheet.

Once you have the file copied, you can go ahead and open it up in xemacs. You will probably want to change this code to personalize your fish a little bit. At this point you probably won't want to make too many changes, just a simple change of colors or something along those lines. You can, and should, come back to this part once you have your aquarium up and running on the web to make some changes to the fish, but for now you just want to have a working Fish class. Examples of changes you might want to make:

The Applet

Now that you have a fish to play around with, you can develop the part of the program that will display it: the applet. Open a new file in xemacs. Start off with the standard import lines at the top, and the normal first line in which you name your class. If you need some help, look back at your past labs. That first line is going to get a little longer this week: at its end (after implements ActionListener) type this:

implements Runnable

OK, now back to normal. Go ahead and type the left curly-brace, and get ready for . . .

DECLARATIONS



More mystery code

The following two methods are among those things that just have to be in the program to make the animated graphics work. Simply copy these two methods after declaring the buttons, aquarium, and thread, and before the init section.

 public void start()
 {
     animator = new Thread(this);
     animator.start();
 }

 public void run()
 {
     while(true) 
     {
        aqua.draw();
        try {Thread.sleep(20);} catch (InterruptedException e){}
     }
 }


INIT

ACTIONPERFORMED

Go ahead and write the regular first line.

Remember, since the purpose of your actionPerformed() is to respond to user buttons clicks, its basic structure consists of an if statement for each button. You'll do two of those conditionals now (for the basic fish and the Clear button), then write your own fish, then come back and write the conditionals to put them on the screen.

Now compile your class. IMPORTANT: Since you're working with a number of classes, you must select the xemacs buffer containing you applet before you compile it. After the class is compiled, you will want to make an html page to hold the applet. The page is the same as usual:

<html>
<body>
<applet code="FishTank.class" HEIGHT="350" WIDTH="500">
</applet>
</body>
</html>
You'll want to make sure the height and width of your applet in the html page is about 20 pixels wider than the aquarium you made and about 90 pixels taller.

Writing a subclass of Fish

The essential point of inheritance in Java is that a subclass inherits everything about its superclass, then adds something extra. It's a way to save both on quantity of code and complexity of design. You know inheritance is going on when you see the keyword extends in the first line of a class; you can think of extends as equivalent to "inherits from".

To really grasp the practical value of inheritance, it helps to look at examples. Here's a subclass of Fish, named GillFish

import java.awt.*;
import awb.*;

public class GillFish extends Fish
{

  public GillFish()
  {
    super();
  }

  public void draw(DrawingPad dp)
  {
    super.draw(dp);

    dp.setColor(Color.red);
    dp.drawLine(70,15,80,40);
    dp.drawLine(65,15,75,40);
    dp.drawLine(60,15,70,40);
  }
}


What you have to write

First of all, as a practical matter you should know that every class you write has to be contained in its own file. So, you should open another new file in xemacs now, and save it as whatever you named your subclass, plus a .java at the end.

You have to create, from scratch, a subclass that looks very much like GillFish. Here's what you need to change:



A subclass of a subclass

The next class you have to write will be almost exactly like the one you just did, with two notable exceptions. First, its name and draw method will be different, just as the first subclass's name and draw were different from those of a basic Fish. Second, this new subclass extends the first subclass, not Fish. So if your first subclass was called GillFish and you want to call this one FinFish, the first line of this class should be:

public class FinFish extends GillFish

Other than that, base this subclass closely on the first subclass, with a different draw method.

Wrapping up the applet

Now that you have a couple of new kinds of fish of your own, you need to write code to handle the buttons that create them. In xemacs, switch back to the first file you were working on, the one containing your applet, and go to the action method. You have two more conditional statements to write, each of which will look very similar to the first conditional. That's because they all exist to put new fish in the Aquarium. In fact, the only difference is that instead of declaring and constructing a new object of the Fish class, you'll declare and construct a new object of your subclass (for one of the conditionals) and a new object of the subclass of your subclass (for the other). You still use addFish to put your new subclass objects in the Aquarium.

That's it. Once you've written those two other conditionals, you can compile and run your program until it works and your fish look the way you want them to. Remember that you have to recompile every time you make a change in the code in order to see the effect of the change.