In this lab you will create a simple draw program. This lab will give you some practice in writing and using classes as well as using polymorphism. You also will have to explore portions of the Java API and learn to use some of the classes which Java has already created for you. Finally, you will have to be familiar enough with generic classes that you can use a generic class which I will provide although you do not yet have to be able to create your own generic classes.
I have provided you with the user interface in the file Draw.java. When you run the applet as it is, you will have a window with several Graphical User Interface `widgets' which the user can use to instruct the program in what to draw. The first one allows the user to choose between one of several colors. The second allows the user to choose a shape. When you change one of these preferences, you will notice that the change is indicated in the status bar at the bottom of the applet. You can find the corresponding `showStatus' command in the code. This is where you should put your code which initiates the response to the users input.
If you click with the mouse anywhere else on the applet window besides
on one of the widgets, then the location of the pixel where the button
was released will be indicated in the status bar. The corresponding
showStatus command is located in the method mouseClicked .
The user can use the mouse in this way to indicate the location and size
of the shape to be drawn. For example, if the user has chosen a circle
shape, the first click would indicate where the user wants the
center of the circle to be placed and the second click would indicate
how far out the radius should extend.
Once the user has input enough points to specify the shape,
that should trigger the program to draw the new shape
(in addition to all the previous shapes) on the screen.
The exception to this is a polygon which can have an arbitrary number of
points.
The final point of a polygon is indicated by clicking on the
Last Point button.
Here are how input points specify each of the shapes:
Create a superclass Shape. Then each different kind of shape will be a class which extends class Shape . The draw method should be an abstract method of class Shape (which makes the class shape an abstract class). This way, your paint method can just cycle through all the nodes in your set of points and call their draw method.
The instance variables of each class keep track of all the
relevant information about the shape: color, location, size.
Of course, keep in mind that a good principle of object oriented
programming is to keep any data or methods that are used by
all the shapes in the superclass.
The Java API already has a class Point defined
which you may find useful.
Your applet will need to have a data structure which keeps
the set of shapes drawn.
You should use the generic class GenStack<E>
which I have provided
below to keep your shapes.
Here is the interface for GenStack .
public class GenStack<E>
{
public E pop();
public boolean isEmpty();
public void push( E newElement );
public GenStackIterator<E> iterator();
public int size();
}
When you need to run through all the shapes to draw them,
you can call the method
iterator() which returns an instance of
GenStackIterator<E> .
Use this to iterate through all the shapes and draw them.
Here is the portion of the interface
for GenStackIterator<E> which you need to use:
public class GenStackIterator<E>
{
public boolean hasNext();
public E next();
}
The file for GenStack.java also includes a class
for GenLinkNode .
I didn't want to have a separate file for GenLinkNode
because the user of the stack should be completely unaware of
GenLinkNode . It is just an artifact of my using
a linked list implementation for the stack.
However, class GenStackIterator
needs to know about GenLinkNode .
Notice that the protection for GenLinkNode
is unspecified which means that it is visible to everything
in the package . In most development environments,
anything in the same project can see GenLinkNode .
You need to make sure that this is the case for your
development environment or make GenLinkNode
public.
There is no inherent limit on the number of points in a polygon.
For this reason, you need a data structure to hold an
arbitrary number of intermediate points and the
generic stack can be used for this purpose as well.
You may also use this stack to store the intermediate point
when the shape is not a polygon.
The size() method which I have provided
returns the number of elements on the stack and may be useful.
When the paint method is called, your program should run through
all the shapes it has stored and draw them on the applet.
Whenever a new object is input, you should
call repaint which in turn automatically
calls paint which will draw everything out
again.
Note that repaint automatically erases the applet
window, so your paint method needs to draw
everything from scratch.
Each class representing a shape will have a draw
method.
paint will draw each object
by just calling its draw method.
In order to draw anything, however, the method which is
drawing must have a Graphics object which
tells it where to draw. For this reason, you will have to pass the
Graphics object to the draw method of the shape object.
To figure out exactly how to draw these objects, you should
look at the following methods of class Graphics:
drawLine
drawRect
drawOval
drawPolygon
(Remember that a square is a special case of a rectangle and
and oval is a special case of a circle).
The description of the Java API will indicate exactly what the parameters
are for each of these methods.
To change the color, you should use the method of
class Graphics called setColor .
The method takes an object of class Color as an argument.
Anything drawn afterwards will be drawn in the specified color.
Check out class Color to see what data it contains.
You can use the three integers to specify any of 2^24 colors.
However, since we are only using a small number of colors,
you will probably want to use the predefined colors.
They are listed under the instance variable and method index
of class Color. These are static and final
variables
of class Color, so remember that in order to use one of there
predefined final colors, you must precede it with Color.
(e.g. Color.blue ).
It would also be useful for the user to see which points
have been input before the shape is drawn. That is, if the
user has chosen to draw a circle and has input the point
for the center but has not yet indicated the radius of the
circle, you should have your program draw a dot
(a tiny filled in circle)
in the location of the center point.
(See method fillOval
of class Graphics).
These points should not appear after the shape has been
specified and drawn.
Whenever the clear button is pressed, the applet window should be cleared. The undo button erases the most recently added shape. If the user has input one more more points in specifying the next shape when the undo button is erased, you can think of the entire group of points as a single shape to be erased. If the user has not yet input any points for the next shape, then the last shape which was drawn should be erased. If the undo button is pressed twice, the most recently drawn shape (which has not yet been erased) should be erased - just like a stack. If the user changes the shape preference, then all current points used to specify the next shape should be erased. If the user changes color, however, the points are retained and should reflect the new color.
Sit down and design your program before you start to write any code. Decide what classes you will have and which methods will reside in which classes. Keep in mind that part of your grade will depend on how you have chosen to organize your code.Here is the template for your code.