Lab 2 - Drawing With Objects
Lab 2 -- Drawing with Objects
Principles of Computer Science
Spring 2005
In today's lab, we will be
writing some simple Java programs which make use of classes written by others.
The files you will need for the lab are compressed into a Java
archive file (a ".jar" file). You can save the jar file into your cs150
directory through this link: lab2.jar
Make sure your current directory is cs150. Then uncompress
the archive with the command
jar xf lab2.jar
This command
will extract the contents of the archive. In so doing, it will create a
lab2 subdirectory in your cs150 directory.
Change to the lab2 directory
(cd lab2), and use the ls command to verify that you have expanded the archive
correctly. You should see a list of the files including, among others,
ShapeApplication.java, Circle.java, Triangle.java, Square.java, and
Canvas.java.
File Circle.java defines class Circle, with the following methods and arguments:
| Circle() | creates an invisible, blue circle with diameter 30 at position (20, 60). The "position" of this circle is the its minimum x-coordinate and its minimum y-coordinate: the position of the upper left corner of a circumscribing squure. | |
| void | makeVisible() | makes the circle appear |
| void | makeInvisible() | makes the circle disappear |
| void | moveRight() | moves the circle to the right by 20 pixels |
| void | moveLeft() | moves the circle to the left by 20 pixels |
| void | moveUp() | moves the circle up by 20 pixels |
| void | moveDown() | moves the circle down by 20 pixels |
| void | moveHorizontal(int distance) |
moves the circle left or right by "distance" pixels (moves right if distance > 0, left if distance < 0) |
| void | moveVertical(int distance) | moves the circle up or down by "distance" pixels (moves up if distance < 0, down if distance > 0) |
| void | slowMoveHorizontal(int d) | animates the circle moving horizontally by "d" pixels |
| void | slowMoveVertical(int d) | animates the circle moving vertically by "d" pixels |
| void | changeSize(int d) | changes the diameter of the circle to "d" |
| void | changeColor(String color) | changes the color of the circle. Valid colors are "red", "yellow", "blue", "green", "magenta" and "black". |
| int | getXPosition() | returns the x-coordinate of the center of the circle. |
| int | getYPosition() | returns the y-coordinate of the center of the circle. |
File Triangle.java defines class Triangle, with the following methods and arguments:
| Triangle() | creates an invisible, green isoceles triangle 40 pixels wide and 30 high, oriented with its point at the top, with this point at (50, 15). | |
| void | makeVisible() | makes the triangle appear |
| void | makeInvisible() | makes the triangle disappear |
| void | moveRight() | moves the triangle to the right by 20 pixels |
| void | moveLeft() | moves the triangle to the left by 20 pixels |
| void | moveUp() | moves the triangle up by 20 pixels |
| void | moveDown() | moves the triangle down by 20 pixels |
| void | moveHorizontal(int distance) |
moves the triangle left or right by "distance" pixels (moves right if distance > 0, left if distance < 0) |
| void | moveVertical(int distance) | moves the triangle up or down by "distance" pixels (moves up if distance < 0, down if distance > 0) |
| void | slowMoveHorizontal(int d) | animates the triangle moving horizontally by "d" pixels |
| void | slowMoveVertical(int d) | animates the triangle moving vertically by "d" pixels |
| void | changeSize(int h, int w) | changes the height of the triangle to "h", the width to "w". |
| void | changeColor(String color) | changes the color of the triangle. Valid colors are "red", "yellow", "blue", "green", "magenta" and "black". |
File Square.java defines class Square, with the following methods and arguments:
| Square() | creates an invisible, red, 30x30 square with its upper left corner at (60, 50). | |
| void | makeVisible() | makes the square appear |
| void | makeInvisible() | makes the square disappear |
| void | moveRight() | moves the square to the right by 20 pixels |
| void | moveLeft() | moves the square to the left by 20 pixels |
| void | moveUp() | moves the square up by 20 pixels |
| void | moveDown() | moves the square down by 20 pixels |
| void | moveHorizontal(int distance) |
moves the square left or right by "distance" pixels (moves right if distance > 0, left if distance < 0) |
| void | moveVertical(int distance) | moves the square up or down by "distance" pixels (moves up if distance < 0, down if distance > 0) |
| void | slowMoveHorizontal(int d) | animates the square moving horizontally by "d" pixels |
| void | slowMoveVertical(int d) | animates the square moving vertically by "d" pixels |
| void | changeSize(int s) | changes each side of the square to length "s". |
| void | changeColor(String color) |
changes the color of the square. Valid colors are "red", "yellow", "blue", "green", "magenta" and "black". |
You're now ready to do today's lab.
Part one.
Draw a picture.
To start you off, there is a simple application
called ShapeApplication. You can try running it with the command
java ShapeApplication .
Now, draw your own picture. Follow
the basic structure of the ShapeApplication program. You'll just have to
modify the contstructor for the class.
Give your own name to the class
you create. The name should reflect the picture you are drawing, such as
face, house, etc.
Use at least five shape objects, including at least one
of each type (circle, square, triangle).
To make your picture more
interesting, you can animate part of it. You can use the same technique I
used in the example we looked at in class. The animation was achieved by
putting a sequence of calls to the "move" methods within a while loop.
That program is also found in the archive, under the name
ShapeAnimation.java.
Part two. Building multiple
houses.
In this part of the lab you will be working with an application
program which draws a picture of a house. The application is in the file
House.java. It will illustrate one of the ways in which we can take
advantage of the power of object-oriented programming to group together related
data items.
Open House.java in an emacs window. You'll see that the
House class has instance variables that represent the components of the house
picture: some squares and a triangle.
The code to draw the house
picture is in a method called "draw". The main method of the class
definition instantiates the class once, creating one house object, with the
statement "House house = new House();", and then tells the house to draw itself.
(We assume that a house knows how to draw itself.)
Try this
first: Notice that there are a number of statments for each component of the
house. For instance to create the wall(s) of our house we have
wall = new Square();
wall.moveHorizontal(138);
wall.moveVertical(80);
wall.changeSize(100);
wall.makeVisible();
To see the effect of these statements, comment out the three inner
statements and compile and run the program. You may want to comment out other
parts of the program and observe any changes in the output. Once you see and
understand what is happening, restore the program to its original state before
you proceed.
Question: Could we create more than one House, just by modifying the
main method to create two new houses instead of one?
Try this out and see
what happens. Add a statement to the main method that creates another
House object. The reference returned by the new operator should be
stored in a variable other than "house", which is already being used to store
the reference to the first House. Then compile and run the
program.
Do you see two houses? You shouldn't, because one is drawn
on top of the other!
What can you do so that both houses are
visible?
All you need to do is to move each of the houses from its
initial position to another location on the screen. This could be done by
modifying the parameters to the "move" method calls in the two different houses,
but that would require writing a different draw method for each house.
There must be a simpler way to do this!
What we would like to have
is a way to simply tell the House to move, then let it figure out how to do it.
How will the House move? A house can move by telling each of its
components to move. This is the strategy we will use.
Write a
method called "moveHorizontal" in House.java. The header line for the
method should look like:
public void moveHorizontal(int
pixels)
The parameter indicates how many pixels to move; a positive
number means move to the right, a negative number means move to the
left.
The body of the method should consist of a sequence of method calls
to the "moveHorizontal" method of each of the House components. That is,
the House can move horizontally by telling each of its components to move
horizontally. This is an example of delegation of responsibility, a common
theme in object-oriented programming.
When you have finished writing this
method, you can test it out by making calls to it from the main method.
The main method creates two House objects. Add method calls to tell
one of the houses to move to the right and the other to move to the left.
(About 100 pixels each should work.)
After you have made all of
these changes, compile and run your program again. You should be able to
see both houses now.
This example illustrates the use of composition in
defining classes. As a result,
- The main method simply tells each house to move, in a single line of code. It doesn't know or care how the house moves. That's the responsibility of the house.
- The house is really composed of several different objects, but from the point of view of the main method, it can be treated as a single object.
- The house delegates responsibility for the move operation to its components.
Part three. One thing you may have noticed about the program in part two is that, when the program is run, you can see the original picture in the center of the window, then see it move to the left and right. Modify the program to avoid that; that is, neither house should be visible until it has been placed in its proper position. If you give the program a better structure this will happen naturally.
Handin.
Submit your results using the handin program you used last week. The lab2 directory should contain a separate .java file for each part of the lab, along with the class files that resulted from compilation. Make sure that the directory contains your final, correct version of each program before submitting it.
Change directory to the cs150, then run handin. At the prompts, enter the course number (150), the assignment number (lab1), and the file/directory name (lab1).
Congratulations! You have now finished lab2.