CoSTARS Note #5:
Graphics


1.  Introduction

So far, we have written programs that can read in text from the user, perform some arithmetic, and print out answers as text.  While such text-based (or "console") programs are common and can be very useful, they do not contain any graphics or pictures.  Here, we learn how to draw graphics using Java programs.  We start with some graphics gray code (which is also available in the file HelloGraphics.java):

// HelloGraphics.java
// To draw graphics, copy this file to a directory,
// and place a copy of the file CoStarsComponent.class in that directory!
import java.awt.*;
import javax.swing.*;
public class HelloGraphics extends CoStarsComponent {
   public void paint(Graphics2D page, int width, int height) {
      // This program paints nothing!
      // Put your drawing code here!

   }
   public static void main(String[] args) { CoStarsComponent.launch(); }
}


*** Important Note ***:  To compile this program, you must first place a copy of the file CoStarsComponent.class in the same directory as the program.  If you cannot download this class file for some reason, then download the file CoStarsComponent.java and compile it -- this creates your own copy of the CoStarsComponent.class file.

*** Another Note ***:  A more complete demonstration of graphics and events can be found in this file: SampleGraphics.java.  Many of the ideas demonstrated in that file will be covered later, but the file is included here so curious students can begin exploring them now.

Place a copy of CoStarsComponent.class in the same directory as this program, then compile and run this program.  When you do, you will see a new window.  This window contains the graphics for this program.  If you look at the green code above, you will see that this program does not draw any graphics.  So the window is blank.  But at least we get a window, so now we are ready to add some graphics to it!

First, to end your graphics program, you must make the window go away.  Do this by clicking on the little "x" in the top right of the window.


2.  Filled Rectangles

We will start by drawing a filled rectangle, by replacing the green code with this:
        // draw a 50x50 filled rectangle in the top-left corner
        page.fillRect(0,0,50,50);

3 Window Coordinates and fillRect Parameters

[Discussion on coordinates + parameters to fillRect]

4.  Adjustable Sizes (Fitting the Window)

Example::
        // Fill the window with a rectangle
        page.fillRect(0,0,width,height);

Example::
        // Fill the left half of the window with a rectangle
        page.fillRect(0,0,width/2,height);

Example::
        // Fill the right half of the window with a rectangle
        page.fillRect(width/2,0,width/2,height);

5.  Unfilled Rectangles

Example::
        // draw a 50x50 unfilled rectangle in the top-left corner
        page.drawRect(0,0,50,50);

Example::
        // Use a 5-pixel-thick line
        page.setStroke(new BasicStroke(5));
        page.drawRect(0,0,50,50);

Example::
        page.setStroke(new BasicStroke(5));
        page.drawRect(0,0,50,50);
        page.drawRect(100,0,50,50);
        page.setStroke(new BasicStroke(1));
        page.drawRect(200,0,50,50);

6.  Built-in Colors

Example::
        // Draw a red rectangle
        page.setColor(Color.red);
        page.fillRect(0,0,50,50);

Example::
        page.setColor(Color.red);
        page.setStroke(new BasicStroke(5));
        page.drawRect(0,0,50,50);
        page.setColor(Color.blue);
        page.drawRect(100,0,50,50);
        page.setStroke(new BasicStroke(1));
        page.drawRect(200,0,50,50);

Here are the built-in colors:
     Color.black
     Color.blue
     Color.cyan
     Color.darkGray
     Color.gray
     Color.green
     Color.lightGray
     Color.magenta
     Color.orange
     Color.pink
     Color.red
     Color.white
     Color.yellow

7.  Drawing Flags

For a list of the flags of the world, see the CIA World Factbook's Flags of the World page.

Example::
        (Monaco)

        // Draw the red rectangle on the top
        page.setColor(Color.red);
        page.fillRect(0,0,width,height/2);

        // Draw the white rectangle on the bottom
        page.setColor(Color.white);
        page.fillRect(0,height/2,width,height/2);

Exercises:

(Poland)

(Russia)

(Armenia)

(Mauritius)

8.  Custom Colors (RGB)

Example::
        // Draw a sea green rectangle
        page.setColor(new Color(46,139,87));
        page.fillRect(0,0,50,50);

Exercises:
Match the colors exactly.

  (Italy)

  (Mali)

  (Benin)

  (Madagascar)

9.  More Flags with Rectangles

Exercises:

  (Latvia)

  (Botswana)

  (Sweden)

  (Iceland)

  (Georgia)

10.  Ovals and Circles

Example::
        // Draw a filled red oval inside a 50x100 rectangle
        page.setColor(Color.red);
        page.fillOval(0,0,50,100);

Example::
        // Draw a filled red oval inside a 50x100 rectangle
        page.setColor(Color.red);
        page.fillOval(0,0,50,100);
        // Draw an unfilled blue oval inside a 100x50 rectangle
        page.setColor(Color.blue);
        page.drawOval(0,0,100,50);

Example::
        // Draw a green CIRCLE with radius 50 centered at 300,200
        page.setColor(Color.green);
        page.fillOval(250,150,100,100);

Example::
        // Draw a green circle centered in the window with the given radius
        int radius = 100;
        page.setColor(Color.green);
        page.fillOval(width/2-radius, height/2-radius, 2*radius, 2*radius);

Exercises:

  (Japan)

  (Palau)

  (Maldives)

11.  Triangles and Polygons

Example::
        // Draw a filled red triangle with vertices at (0,0), (100,100) and (200,0)
        page.setColor(Color.red);
        Polygon p = new Polygon();
        p.addPoint(0,0);
        p.addPoint(100,100);
        p.addPoint(200,0);
        page.fillPolygon(p);

Example::
        // Draw a filled orange trapezoid filling the bottom of the window
        // but only a third of the top
        page.setColor(Color.orange);
        Polygon p = new Polygon();
        p.addPoint(0,height);
        p.addPoint(width/3,0);
        p.addPoint(2*width/3,0);
        p.addPoint(width,height);
        page.fillPolygon(p);

Exercises:

  (The Czech Republic)

  (The Bahamas)

  (Trinidad and Tobago)

  (Jamaica)

  (Guyana)

  (The Seychelles)

  (St Vincent and the Grenadines)

  (Wallis and Futuna)

  (South Africa)

12.  Lines

Note:  Unlike rectangles and ovals, lines do not use a width or a height.  Like polygons, lines only take (x,y) points.  To specify a line, provide four values (x1, y1, x2, y2) specifying two points -- the start point and the end point.

Example::
        // Draw a thin line from the top-right corner to the point (50,100)
        page.drawLine(width,0,50,100);

Example::
        // Predict what this will draw and then compile and run to confirm
        page.setStroke(new BasicStroke(5));
        page.setColor(Color.blue);
        page.drawLine(width/4,50,3*width/4,50);
        page.setColor(Color.orange);
        page.drawLine(3*width/4,height-50,3*width/4,50);
        page.setColor(Color.red);
        page.drawLine(width/2,height-50,width/4,50);
        page.setColor(Color.green);
        page.drawLine(3*width/4,height-50,width/2,height-50);

Example::
        // Predict what this will draw and then compile and run to confirm
        page.setStroke(new BasicStroke(40));
        page.setColor(Color.yellow);
        page.drawLine(0,0,width,height);
        page.setStroke(new BasicStroke(1));
        page.setColor(Color.black);
        page.drawLine(0,0,width,height);

Exercises:

Draw (or redraw) these flags using only drawLine (and not fillRect or fillPolygon).  Which way is easier?  Which way is clearer?

  (Thailand -- do not use fillRect or fillPolygon!)

  (Tonga -- do not use fillRect or fillPolygon!)

  (Trinidad and Tobago -- do not use fillRect or fillPolygon!)

  (South Africa -- do not use fillRect or fillPolygon!)

13.   More Exercises (solve by hand, without a compiler!)

Sample exercise:  What will this code draw (answer both in words and with a sketch):
        page.drawRect(a,b,c,d);
        page.drawRect(a-10,b,c,d/2);

Sample solution:  two rectangles, the second 10 pixels to the left of, and half as tall as, the first, like this:

For clarity, it is preferable that you shade the original rectangle like this:

  1. [Rectangles] For each of the following, what will the code draw (answer both in words and with a sketch, and shade the original rectangle).

    1. page.drawRect(a,b,c,d);
      page.drawRect(a-10,b,c+10,d);
       

    2. page.drawRect(a,b,c,d);
      page.drawRect(a-10,b,c+20,d);
       

    3. page.drawRect(a,b,c,d);
      page.drawRect(a-e,b,c+(2*e),d);
       

    4. page.drawRect(a,b,c,d);
      page.drawRect(a-c,b,c,d);
       

    5. page.drawRect(a,b,c,d);
      page.drawRect(a,b+d,c,d)
       

    6. page.drawRect(a,b,c,d);
      page.drawRect(a+e,b+f,c-(2*e),d-(2*f))
       

    7. page.drawRect(a,b,c,d);
      page.drawRect(0,0,a+c/2,b);
       

  2. [Polygons] For each of the following, what will the code draw (answer both in words and with a sketch, and shade the original rectangle).

    1. page.drawRect(a,b,c,d);
      Polygon p = new Polygon();
      p.addPoint(a,b);
      p.addPoint(a+c,b+d);
      p.addPoint(a+2*c,b);
      page.drawPolygon(p);
       

    2. page.drawRect(a,b,c,d);
      Polygon p = new Polygon();
      p.addPoint(a+c/2,b);
      p.addPoint(a,b+d/2);
      p.addPoint(a+c,b+d/2);
      page.drawPolygon(p);
       

    3. page.drawRect(a,b,c,d);
      Polygon p = new Polygon();
      p.addPoint(0,b);
      p.addPoint(a+c/2,b+d/2);
      p.addPoint(a,0);
      page.drawPolygon(p);
       

    4. page.drawRect(a,b,c,d);
      Polygon p = new Polygon();
      p.addPoint(a+c/2,b);
      p.addPoint(a,b+d);
      p.addPoint(a+c,b+d/3);
      p.addPoint(a,b+d/3);
      p.addPoint(a+c,b+d);
      page.drawPolygon(p);
       

  3. Write a few lines of code that draws each of the following (assume the rectangle's left-top point is at (a,b) and its width is c and height is d):

    1. An oval centered inside a rectangle.

    2. An oval centered inside a rectangle, but with 20 pixels of margin on each side.

    3. A diagonal line from the bottom-left to the top-right corners of a rectangle.

    4. A polygon connecting the midpoints of each side of a rectangle (to form a diamond inside the rectangle).

    5. A 3x3 red-and-black checkerboard that fills the rectangle (the top-left square should be red).
       

  4. Explain how to draw the "mirror image" of a picture containing rectangles and polygons.  Provide a precise answer that clearly explains each case (as the technique to convert rectangles is a little different than converting polygons, as the former are drawn using widths and heights, and the latter are not).  Using your technique, provide a mirror image of the flag of the Czech Republic.
     

  5. Explain how to "zoom" a picture containing rectangles and polygons, say to make it 2 times larger.  Demonstrate your technique by drawing a simple picture that draws (and does not fill!) a rectangle and a 5-sided polygon all in black, then redraws the zoomed versions all in orange.
     

  6. Repeat the previous problem, but zoom out to make the orange picture 2 times smaller.
     

  7. Explain how to "pan" a picture containing rectangles and polygons, say to move it 10 pixels to the right and 20 pixels down.  Once again, demonstrate your technique by drawing a simple picture that draws (and does not fill!) a rectangle and a 5-sided polygon all in black, then redraws the panned versions all in orange.
     

  8. Explain how to rotate a picture (containing rectangles and polygons) by 90 degrees counterclockwise (note that the right edge of the original picture will become the top edge of the rotated picture).  Using your technique, provide a rotated image of the flag of the Czech Republic.