CIT 591 Random Activity -- Additional Information
Fall 2008, David Matuszek

The following problems were encountered in lab. Here are some explanations and corrections.

JPanel

In the starter code I used the java.awt.Panel class. I meant to use the javax.swing.JPanel class. Please make the appropriate substitutions. (Either one works, though.)

paint(g) vs. draw(g)

In the RandomActivity class I said

// Call paint(g) for each and every one of your figures

Then, in the description of Figure and its subclasses, I said these classes "should have a public void draw(Graphics g) method."

These were supposed to be the same method. Use the name draw rather than paint.

Getting width and height

First of all, you can set the size of the JFrame. The JFrame contains the JPanel, and the JPanel changes size when the JFrame does. You can't (easily) set the size of the JPanel itself.

Secondly, when you are drawing, you are drawing in the JPanel, and you want to get the size of the panel. You do not care about the size of the JFrame.

Now, that panel is defined in the RandomActivity class. If, in the Figure class, you want to get the size of the panel, then the Figure class has to know how to refer to the panel. To accomplish this, declare a static JPanel panel variable in the Figure class, and put the following function there:

 static void setPanel(JPanel panel) {
    this.panel = panel;
}

Once you use this method to tell the Figure class about the panel, you can then ask it for its size with panel.getWidth() and panel.getHeight(). These methods will always return the current size of the panel, even if the user has resized the window.

Finally, I said in the assignment to write a method static void setLimits(int maxX, int maxY) in the Figure class. However, if you write a setPanel method, the setLimits method is unnecessary. Feel free to leave it out.

A problem with constructors

It is a good idea to write your own constructor for your Figure class, for example,

 Figure(int width, int height, Color color) {
    ...
}

However, if you do this, you must write a constructor in each subclass of Figure, and the first line of each of those constructors must call the Figure constructor, with the correct types of parameters, by using the special keyword super--like so:

 SmileyFace(int width, int height) {
        super(width, height, Color.YELLOW);
    ...
}

Flicker

Your figures may flicker (flash on and off) a bit, but the problem should not be too severe. This is because I took some shortcuts when I set up the framework for you to use. (I knew this was risky, but the problem doesn't happen on my computers.) Good animation requires a bit more work than this. If there is time, perhaps we can talk about animation later in the course.

If you get a really irritating amount of flicker, then either you are using a pretty slow computer, and there isn't a lot you can do about it; or, your draw methods are doing far more computation than they should, and you should get help fixing the problem. But in almost all cases, this isn't your fault, and you don't need to worry about it.

Doesn't draw in an enlarged window

This took me a while to figure out!

When the user resizes a window (JFrame) by clicking and dragging on the screen, the JPanel does automatically change size along with it exactly as I said. However, you don't actually draw on the panel; you draw on its Graphics, g. It turns out that the Graphics does not automatically change size when the panel size changes. The solution is to ask the panel for its Graphics every time you want to do a bunch of drawing. (Once inside the loop is enough.) So instead of doing this:

while (true) {
    // Erase the window by filling it with white
    ...
}

you need do this:

while (true) {
    g = panel.getGraphics(); // Tell the Graphics the new panel size
    // Erase the window by filling it with white
    ...
}