Lab 4 In-Class: Graphics
Lab Objectives
- Learn about the Color class and how colors are
represented in Java
- Gain more experience with graphics.
|
Getting Started
Log onto the Linux system, open Firefox and an xterm window.
In Firefox, go to the home page for this class and open up this lab.
In an xterm,
go to your Labs directory for this course and create a lab4
subdirectory for today's work. Change into that subdirectory.
Graphics and Color Codes
The basic scheme for representing a picture in a computer is to
break the picture down into small elements called pixels,
short for picture elements, and
then represent the color of each pixel by a numeric code (this
idea is discussed on pages 802 and 803 of the text). There are many systems for
representing colors. One of the most common systems on computers is to use the
same three additive colors that computer displays use.
In this system the three additive colors are represented with three numbers --
one representing the amount of red in the color, another the amount
of green, and the third the amount of blue. These numbers are referred to
as the RGB value of the color. In Java, each of the three
primary colors is represented by an 8-bit code. Hence, the possible
base 10 values for each have a range of 0-255. Zero means none of that
color while 255 means the maximum amount of the color. Pure red is
represented by 255 for red, 0 for green, and 0 for blue, while magenta
is a mix of red and blue (255 for red, 0 for green, and 255 for blue).
In Java you can create your own colors. So far in the graphics programs
we have written we have used the pre-defined colors, such as Color.red,
from the Color class. However, we may also create our own Color object
by specifying the red, green, and blue attributes.
One way to create a Color object
is to declare a variable of type Color and instantiate it using
the constructor that requires three integer parameters -- the first
representing the red attribute (the amount of red), the second the green
attribute, and
the third the blue attribute of the color. The signature for that
constructor is
Color (int r, int g, int b)
where r is the integer code for red, g the code for green, and b
the code for blue. For example, the following
declares the Color object myColor and instantiates it to a color
with code 255 for red, 0 for green, and 255 for blue.
Color myColor = new Color(255, 0, 255);
The Graphics object (page) can use a color object to set the foreground
color for the page. The statement:
page.setColor(myColor);
will set the current drawing color to be myColor .
The file Colors.java contains an application that
defines myColor to be a Color object with color code (200, 100, 255) -
a shade of purple - and later redefines myColor to be a Color
object with code (100, 100, 200).
Save Colors.java to your lab4 directory, open it in the Emacs editor,
compile, and run the program.
Now do the following:
- Study the code to see what is going on. First observe that there
are two classes - the Colors class sets up the frame for drawing
but the paintComponent method in the ColorsPanel class is where
all the drawing instructions are.
Note the two places in paintComponent where
the Color constructor is invoked to instantiate a new Color object.
Also note how the x, y, width, and height variables are computed
to place the two ovals (they are computed in terms of the PAGE_WIDTH
and PAGE_HEIGHT constants). Finally note the use of the drawString
method. The signature for the method is given on page 804 of the text.
- Change the first instantiation of a Color object
so the color code is (0,0,0) --- absence of
color. What color should this be? Compile and run the program to check.
- Try a few other combinations of color codes to see what you get.
Find something you like for each of the ovals that are drawn.
- Use the drawString method to put your name centered in the bottom
right oval. Place your statement in the code where indicated by the
comment (after the oval is drawn). Be sure to use the current values of
x, y, width, and height in calculating the x and y values that position
the string (you will need to make an adjustment that depends on the length
of your name similar to the 35 used in positioning the "Color Codes" string).
- Compile and run the application to make sure it is correct.
- Now add a rectangle in the center of the frame. The height of
the rectangle should be half the height of the frame page and the
width should be half the width of the page. Use the x, y, width, and
height variables to calculate the position. The calculations should
involve the PAGE_WIDTH and PAGE_HEIGHT constants. Run
the application to make sure it is correct before proceeding.
Resize the window to see that the shapes resize with it (they will if you
used calculations for x, y, width, and height involving the page size
constants; they won't if you hardcoded numbers instead).
- Now we will modify the program to generate random colors using
a different constructor. (NOTE: a class can have multiple constructors -
having more than one version of a method, including a constructor,
is called method overloading.)
There is a constructor for the Color
class that takes a single integer as an argument. Its signature is:
Color (int rgb)
The first 8 bits
of the integer argument are ignored while the last 24 bits define the color --
8 bits for red, 8 for green, and the last 8 bits for blue. Hence,
the bit pattern
00000000000000001111111100000000
should represent pure green. Its base 10 value is 65280. Just
before your code for the rectangle (but after the comment about
drawing a rectangle) add a new
instantiation of the myColor object to
myColor = new Color (65280);
You also need to use the setColor method to set the color
to myColor.
Run the application. Is your rectangle green?
- Now add the following statements to the program:
- Declare colorCode to be a variable of type int;
- Declare a constant COLOR_MAX and initialize it to 16777216.
Put your declaration up with the other constants near the
beginning of the main method.
(NOTE: This number comes from
the fact that a color is represented by a 24 bit code - how
many unique items can be represented by a 24 bit code?)
- Use the random class method nextInt
to generate a random integer value
in the range 0 - 16777215 (use the constant just declared!). Store
the result in the colorCode variable.
- replace the number 65280 in the Color constructor above with the
variable colorCode
Run the program -- restart the program several times
so you can see the different random colors generated.
- The Color class has methods that return the individual color codes (for
red, green, and blue) for a Color object. For example, the
getRed method returns the red component of a Color
object. Its signature is as follows:
int getRed()
The methods
that return the green and blue components are getGreen and
getBlue, respectively. Add statements to the program
to get the three color codes (you need to declare some
integer variables to store the codes - for example you could declare
an int named redCode to store the red component, then assign
it a value using
an assignment statement that invokes the getRed method to get the
red component from the myColor object).
Then add statements such as
page.drawString("Red: " + redCode, ____ , ____ );
to label the rectangle with the three color codes (this assumes
your variable for the red attribute is redCode). You need to
fill in the
blanks with appropriate coordinates so each string is drawn inside
the rectangle -- to do this make adjustments to the
x and y coordinates for the rectangle.
You also need to set the drawing color to something such as
black so the strings will show up.
Run the program to make sure it works. Restart several times
to see the different colors and their corresponding codes displayed.
- If you restarted the program enough times you probably noticed that
the black (or whatever color you used) strings didn't always show up. Our
final task is to fix this so the color of the strings will always show up.
We'll do this by creating a new color from the red, green, blue attributes
of the rectangle color. So add the following to your program
to get the new color:
- [READ ALL OF THIS BEFORE DOING ANYTHING!!]
Before you set the color for the strings,
instantiate a new Color object that is sort of "half way" around
the color spectrum from the color of the rectangle. We'll do
this by adding
128 (half of 256) to the red, green, blue attributes of the rectangle color.
However we can't just add 128 because the Color constructor that has 3 integer
arguments requires that the integers be in the
range 0 - 255. To get the codes back in the proper range we
take the remainder when dividing by 256.
Hence, what you need to do for each color attribute, add 128 then
take the remainder when the result is divided by 256 (write
a Java expression that does this). For example,
if redCode is currently 220 then when you add 128 you get 348
then taking the remainder when you divide by 256 gives 92. You can
either introduce new variables for each of the new codes and
store the new values in those variables before instantiating the
new Color object OR you can just put the calculations for the new
codes directly in the arguments for the constructor.
- Set the color for drawing to be your new color instead of black
(or whatever color you used before).
- Test your program!
- Print your final program.
More Graphics
So far we have drawn rectangles, ovals,and strings but there's
lots more that can be done with Java graphics. For starters,
you can draw
lines and arcs. All of these shapes can be drawn in
outline with the "draw" methods (drawRect, drawArc, etc), or
drawn in filled in form with the "fill" methods (fillRect,
fillArc, etc).
Refer to the list of graphics methods on page 804.
The descriptions are on pages 803-806. Pay particular attention
to how an arc is defined (note the diagram on page 805).
Now save files MoreShapes.java
to your lab4 directory. Open the file in Emacs and examine
the code then compile and execute the program.
To be
sure you understand the arc methods do the following:
- Observe that currently the red arc has a start angle of 0
and an arc angle of 90. This draws a quarter of an oval.
Change the start angle to 45 and run
to see what happens. Where does the arc start? How far does it go?
- Change the arc angle to 180 and see what happens.
- Currently the black outline arc has a start angle of 120
and an arc angle of 160. Observe what this looks like then change
the arc angle to 300. See what this does.
Creating a Pie Chart
In this exercise you will write an application that
draws a pie chart showing how
household income is divided among various expense categories.
Java applications that use
graphics all have the same general format. The file
PieChart.java contains a shell for the
program. Open it in Emacs and note that it already has
the following necessary components (with few changes from MoreShapes.java):
- the import
statements needed for a graphics application
- the main
method that sets up the graphics frame. Note that it
declares and instantiates a PieChartPanel object rather than a
MoreShapesPanel object for the frame.
- a class for the PieChartPanel containing the paintComponent
method.
Your job is to fill in
the paintComponent method with code to draw the pie chart.
To do this you need to think
about what shapes make up a pie chart to plan the program.
For your pie chart use the percentages
below:
Rent and Utilities | 35%
|
Transportation | 15%
|
Food | 15%
|
Educational | 25%
|
Miscellaneous | 10%
|
Each section of the pie should be in a different color, of course.
Label each section of the pie with the category it represents
and the appropriate percent (such as "Food (15%)") -- the labels
should appear outside the pie itself. Be sure your pie pieces
are the appropriate proportion of a circle (for example, the one for
educational expenses should be 25% of a circle).
Print the completed program.
What to turn in
- Turn in hardcopy of your two files: Colors.java
and PieChart.java
- Tar up your lab4 directory (change to your lab4 directory,
then do
tar czf yourNamelab4.tgz .
)
- To submit your code, copy the tar file containing your code
to the directory:
~ingram/CPSC120/yourname
(Of course, instead of yourname put the name I have set up for
you - the name you go by all lowercase.)