Objects and Graphics

In lab this week we will be creating our own objects and practice using Java graphics. To get you started thinking about the subject, there is a small applet below demonstrating objects we'd like to be able to build.

You need a Java-enabled browser to view this applet.

On the left are instances of the PulsatingRectangle class and on the right are instances of the RotatingArc class. Both classes are extensions of a TickObject which is any object which implements a tick method which moves the object from one state to another and a draw method which draws the object on a given Graphics context. We will go over the contract for the TickObject in lab. The animation above has a definite time limit. The applet has the property that every time the applet is drawn in the browser, the animation will start again from the beginning. So, to see the animation again you can scroll down and up or move focus away from the browser window and back.


Understanding PulsatingRectangle

The two pulsating rectangles above are created by the following two lines of code:
PulsatingRectangle rect1 = new PulsatingRectangle(50,50,0,0,40,40,10,Color.cyan,Color.black);
PulsatingRectangle rect2 = new PulsatingRectangle(200,50,20,10,80,40,30,Color.red,Color.white);
The contract for the PulsatingRectangle constructor is
public PulsatingRectangle (int x, int y, int minWidth, int minHeight,
                           int maxWidth, int maxHeight,int steps,
                           Color color, Color bgColor)
where This method creates a rectangle of the minimum width and height centered at the given x and y coordinates of the color given on a background rectangle of the maximum width and height centered at the same x and y coordinates with the specified background color. With each execution or its tick method, the rectangle is redrawn and grows or shrinks by a specified amount such that in the given number of steps the rectangle has spanned sizes from the minimum size to the maximum size or vice versa.

The complete code for this class is below. Your task is to try to understand it.


class PulsatingRectangle extends TickObject {

  private int x; // center of rectangle
  private int y; // center of rectangle
  private int minWidth;
  private int minHeight;
  private int maxWidth;
  private int maxHeight;
  private int steps;
  private Color color;
  private Color bgColor;

  // internal representation of state
  private int width;  // current width
  private int height; // current height
  private int dx;     // how much to change the width by for each tick
  private int dy;     // how much to change the height by for each tick

  // Constructor method creates the object	
  public PulsatingRectangle (int x, int y, int minWidth, int minHeight,
                             int maxWidth, int maxHeight,int steps,
                             Color color, Color bgColor) {
    this.x = x;
    this.y = y;
    this.minWidth = minWidth;
    this.minHeight = minHeight;
    this.maxWidth = maxWidth;
    this.maxHeight = maxHeight;
    this.steps = steps;
    this.color = color;
    this.bgColor = bgColor;
    this.width = minWidth;
    this.height = minHeight;
    this.dx = (maxWidth-minWidth)/steps;
    this.dy = (maxHeight-minHeight)/steps;
  }

  // Tell us the name of the object	
  protected String name () {
    return "PulsatingRectangle";
  }

  // Tell us the state of this object (external representation)
  public String toString () {
    return name() + "[x = " + this.x
                 + "; y = " + this.y
                 + "; minWidth = " + this.minWidth
                 + "; minHeight = " + this.minHeight
                 + "; maxWidth = " + this.maxWidth
                 + "; maxHeight = " + this.maxHeight
                 + "; steps = " + this.steps
                 + "; color = " + this.color
                 + "; bgColor = " + this.bgColor
                 + "]";
  }

 // Tell us the state of this object (internal representation)
  private String getState () {
    return name() + "[width = " + this.width
                 + "; height = " + this.height
                 + "; dx = " + this.dx
                 + "; dy = " + this.dy
                 + "]";
  }

  // Clear the object from the screen by drawing over it in the background color.
  public void clear (Graphics g) {
    g.setColor(this.bgColor);
    g.fillRect(x-maxWidth/2,y-maxHeight/2,maxWidth,maxHeight);
  }

 // Draw the object on the screen
  public void draw (Graphics g) {
    clear(g);
    g.setColor(this.color);
    g.fillRect(x-width/2,y-height/2,width,height);
  }
	
  // Update the state of the object to the next state
  public void tick () {
    width = width + dx;    // the new width
    height = height + dy;  // the new height
    if ((width>=maxWidth) || (height>=maxHeight)) {
      // the object is too big, make it the maximum size
      width = maxWidth;
      height = maxHeight;
      // in the future, shrink the object
      dx = -dx;
      dy = -dy;
    } else if ((width<=minWidth) || (height<=minHeight)) {
      // the object is too small, make it the minimum size
      width = minWidth;
      height = minHeight;
      // in the future, expand the object
      dx = -dx;
      dy = -dy;
    }
  }

  // Draw the object and then update its state to the next state
  public void drawAndTick (Graphics g) {
    draw(g);
    tick();	
  }
	
}

Implementing RotatingArc

The two rotating arcs above are created by the following two lines of code:
RotatingArc arc1 = new RotatingArc(350,50,40,40,90,6,6,false,Color.magenta,Color.darkGray);
RotatingArc arc2 = new RotatingArc(500,50,80,40,0,90,90,true,Color.blue,Color.lightGray);
The contract for the RotatingArc constructor is
public RotatingArc (int x, int y, int xRadius, int yRadius,
                    int startAngle, int arcAngle, int dAngle,
                    boolean counterclockwise, Color color, Color bgColor)
where This method creates an arc of the specified arcAngle starting at the specified startAngle in a rectangle centered at the given x and y coordinates with a width of twice the given xRadius and a height of twice the given yRadius on a background oval of the specified background color in the same space. With each execution of its tick method, the arc is redrawn in a position which is shifted by the number of degrees specified by dAngle. The value of counterclockwise determines in which direction the arc is rotated.

Your task is to think about how to write the code for RotatingArc. Try to answer the following questions:

If you don't remember how to draw ovals and arcs, you can refer to the Graphics Contract which is linked off the the Lecture Notes section of the CS111 web site.