CIT 591 Assignment 4: Random Activity
Fall 2008, David Matuszek

Purposes of this assignment:

General idea of the assignment:

Create a bunch of objects, and move them around on the screen.

This program won't do anything useful; it's just eye candy.


How do you draw an object?

You have already done some drawing, in the first assignment. In that assignment you drew on an applet. This assignment will be a little different, because it's an application, and you have to set up window yourself. A framework for doing that will be given below.

cross in circle All but very simple drawings will have several parts. For example, suppose you draw a cross inside a circle. Each of these is drawn starting at a slightly different location on the screen. Here's some code:
 g.drawOval(200, 150, 20, 20);    // starts at 200, 150
 g.drawLine(200, 160, 220, 160);  // starts at 200, 160
 g.drawLine(210, 150, 210, 170);  // starts at 210, 150
If you want to be able to draw this figure anywhere on the screen, it is best to draw the figure starting at (0, 0), and to add an x, y displacement to every position. Like this:
 x = 200;
 y = 150;
 g.drawOval(x, y, 20, 20);         // starts at 200, 150
 g.drawLine(x, y + 10, 220, 160);  // starts at 200, 160
 g.drawLine(x + 10, y, 210, 170);  // starts at 210, 150

How do you move an object?

If you have drawn the object as recommended above, all you have to do is change the values of x and y. That will change where the program "thinks" the object is. Unfortunately, changing the values of some variables in your program doesn't change the screen; you have to tell it to display the changed data.

To actually display the object in its new position, you should first erase it from its old position, then paint it at its new position. The simplest way to do this is to erase the entire screen (use the fillRect method to paint everything white), the have a method public void paint(Graphics g) to draw the object on g. Tell each and every one of your objects to paint themselves.

What's g? That comes from the framework. See below.

Do this:

Create a new project. Name it RandomActivity.

Within the project, create a new package. Name it randomActivity.

Within the package, create a new class. Name it RandomActivity.

Next, replace (copy & paste) all the code in your RandomActivity class with the following code:

package randomActivity;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Panel; import javax.swing.JPanel;
import java.util.Random;
import javax.swing.JFrame;

public class RandomActivity extends JFrame {
    Random rand = new Random();
    final int WIDTH = 500;
    final int HEIGHT = 500;

    public static void main(String args[]) {
        RandomActivity p = new RandomActivity();

    void doTheWork() {

        // Declare any variables you need here

        Panel panel = new Panel();         // Creates a Panel to hold our drawing
        JPanel panel = new JPanel();
        add(panel);                        // Puts the Panel in the window
        setSize(WIDTH, HEIGHT);            // Sets the size of the window (OK to change)
        setVisible(true);                  // Makes the window visible on the screen
        Graphics g = panel.getGraphics();  // Gets the Graphics context
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // Quit cleanly

        // Put your code here to create a bunch of "figures"--these
        // will not be instances of class Figure, but will be instances
        // of the subclasses of Figure (for example, maybe a SmileyFace).

        // Tell the Figure class what the window size is
        // Put each figure somewhere in the window
        while (true) {
            g = panel.getGraphics(); // Tell the Graphics the new panel size
            // Erase the window by filling it with white
            // Move each and every one of your figures

            // Call paint(g) for each and every one of your figures
            try {
                Thread.sleep(50); // pause for a little while
            catch (InterruptedException e) {}

After each full-line comment in the above, fill in the actual code to do what the comment says.

Additional classes:


Next, write a class Figure that describes the general characteristics of every figure you will put on the screen. It must define at least the following instance variables (you can have more if you like):

All the figures will move in the same way, so you should put a move method in the Figure class that can be inherited by each Figure. It should be declared as public void move(), and here's what it should do:

Since the figures should not move beyond the edges of the window, figures need to know the size of the window. Since the window is the same size for all the Figures, the width and height of the window should be static variables in the Figure class. You can, if you wish, write a method static void setLimits(int maxX, int maxY) in the Figure class to set these variables. Even better, though, is to write a static void setPanel(JPanel panel) method in the Figure class; then you can use the methods panel.getWidth() and panel.getHeight() to get the current size of the panel, in case the user changes it.

All figures will not be drawn in the same way, but you need to put a "placeholder" method public void draw(Graphics g) in the Figure class. The purpose of this is to assure Java that every figure has such a method. The method should simply draw an unfilled black rectangle of the height and width of the figure.

Subclasses of Figure

Finally, create three or more subclasses of Figure, giving them meaningful names. Each subclass should assign values to its (inherited) variables width and height, its initial position (x = 0, y = 0 is OK), and its deltaX and deltaY. It should have a public void draw(Graphics g) method that draws an interesting figure (not too simple, but not too complex, either--somewhere between three and ten drawing commands is probably about right). Figure out the width and height of this drawing, and use those values for the width and height of this subclass (not all subclasses should have the same width and height).

Each instance of a figure that you create should have an initial deltaX and deltaY. It works out well to make these randomly chosen small numbers (say, between -10 and 10). But make sure that they aren't both zero, or your figure won't move.

Bits and Pieces:

When you move a Figure, you should keep it within the JPanel. This involves some arithmetic, and it also involves knowing the size of the JPanel. You can find the size of the JFrame or the size of the JPanel by sending either the messages getWidth() and getHeight(); these methods return ints. You should check the JPanel size each time you start to draw, because the user is able to resize the window. (What happens to a figure if the user suddenly makes the window so small that the figure is entirely outside it? Be sure to do something sensible!)

As I've defined the program, the Graphics object for the JPanel is used as a parameter to the draw method. Another way to do this is to store the Graphics object in a class variable of the Figure class. That way you don't have to keep passing it as a parameter.

Notice that the JPanel is slightly smaller than the JFrame you put it in.

To choose a random number, import java.util.* (or just java.util.Random), create the object

static Random random = new Random();

and send it the message nextInt(n) to get a random integer between 0 and n - 1. Be sure not to create more than one Random object (that's why I suggest making it static).

Don't worry about objects "bumping" into one another. The right thing happens automatically--if you erase the figures when I said to erase them.

Due date:

Your program is due before midnight, Thursday October 2. Zip up the entire directory for this project, and submit via Blackboard. You will have a partner for this assignment. The two of you should turn in one copy of your program. Both your names should be in a comment in the program. In addition, whichever of you turns the program in, should put your partner's name in the comments in Blackboard.