Question: A Drawing Program, Part 2 This is the second in a series of assignments in which you will implement a crude but functional drawing program.
A Drawing Program, Part 2
This is the second in a series of assignments in which you will implement a crude but functional drawing program. The drawing program will allow the user to create shapes and place them on screen by entering instructions through the text console.
In this second part you will implement a class that manages references to four objects that represent the geometrical shapes that the drawing program can create. That class will be called ShapeManager. ShapeManager will work alongside the FairfieldDraw class. As with Part 1, FairfieldDraw is the main Java application (it has a public static void main(String[] args) method). It creates a window to serve as a drawing canvas, and takes user input from the console to draw shapes at certain locations on the canvas.
Provided Code
For this assignment you will be provided with source code for two Java classes and one Java enum to start with. These are in the files FairfieldDraw.java, FairfieldDrawHelper.java, and ShapeType.java. FairfieldDraw is incomplete and will not compile because it depends on classes that you create in this assignment (and four from the previous assignment). The zip archive containing the code is in the Blackboard folder for the assignment. Do not modify FairfieldDraw.java, FairfieldDrawHelper.java, or ShapeType.java. You should not need to modify them to complete this assignment.
You will need to add your Rectangle.java, Circle.java, Triangle.java and Line.java to the project in order for FairfieldDraw to compile and run. We suggest using the same Eclipse project as for Part 1, adding and replacing files to that project as needed. (Note that FairfieldDraw.java in this assignment is different from FairfieldDraw.java from Part 1). When it is complete, your project should have eight files: FairfieldDraw.java, FairfieldDrawHelper.java, ShapeType.java, ShapeManager.java, Rectangle.java, Circle.java Triangle.java and Line.java.
A ShapeManager Class
To complete this assignment, you need to implement a class that that manages references to four classes that represent the geometrical shapes that your drawing program can draw. Create a new class and name it ShapeManager. Your
ShapeManager class should have four instance/member variables. One should be declared as type Rectangle, one as Circle, one as Triangle, and one as Line. These instance/member variables will be references to a Rectangle object, a Circle object, a Triangle object, and a Line object respectively. You can name these instance variables however you like, but we suggest meaningful names like rect or rectangle for the Rectangle reference. (Notice that its ok to name an instance rectangle with a lower-case r but not with a capital R since then its name would collide with the name of the class.)
The methods you will implement in ShapeManager will use and manipulate these objects. You will implement a createShape() method which creates the shape objects, and deleteShape(), which removes them. You will also implement a drawShapes() method which calls paint() on each of the geometrical shape objects. These methods allow the FairfieldDraw application to create and delete geometrical shape objects and render them to the screen. Details of how to implement each of these methods are below.
The createShape() method
In your ShapeManager class, implement a method of this form:
void createShape(ShapeType shapeType, int newShapeX, int newShapeY) {
... }
The method name is createShape, and it has three arguments/parameters: a parameter of type ShapeType called shapeType representing the type of Shape to create, and two ints, newShapeX and newShapeY, representing the x and y coordinates at which the shape is to be located. Notice that the parameter shapeType has a lower-case s, which does not conflict with the name of the enum type, ShapeType (capital S). The return value type is void indicating that the method does not return a value.
The code in the body of the method (between the { and } ) should do the following: 1. If shapeType is equal to the enum value ShapeType.rectangle, then
a. Use the new operator and the Rectangle constructor (e.g. new Rectangle()) to create a new Rectangle and assign your ShapeManagers Rectangle reference to point to that new rectangle.
Note: Do NOT declare a reference to a Rectangle within the createShape() method as part of doing this. Simply assign the member variable reference that was declared in the ShapeManager class declaration. (By now you should know the difference between declaring and assigning).
b. Then assign the x member variable of the rectangle to the value of the method parameter newShapeX, and assign the y member variable of the rectangle to the value of the method parameter newShapeY. This makes it so that the Rectangle is drawn in the location specified by the user.
2. Implement similar code for cases where shapeType is equal to ShapeType.circle, ShapeType.triangle, or ShapeType.line.
The deleteShape() method
In your ShapeManager class, implement a method of the form
void deleteShape(ShapeType shapeType) {
... }
The method name is deleteShape, and it has one parameter, a parameter of type ShapeType called shapeType representing the type of Shape to delete. The return value type is void indicating that the method does not return a value.
The code in the body of the method (between the { and } ) should do the following:
If shapeType is equal to the enum value ShapeType.rectangle, then assign your ShapeManagers Rectangle reference the value null. Assigning the special value null (meaning nonexistent, nothing) means your Rectangle reference isnt pointing at an object anymore, and when the screen is redrawn, its paint() method will not be called. This effectively deletes the shape.
Implement similar code for cases where shapeType is equal to ShapeType.circle, ShapeType.triangle, or ShapeType.line.
The paintShapes() method
In your ShapeManager class, implement a void paintShapes(Graphics g) {...} method. The method name is paintShapes, and it has one parameter, a parameter of type Graphics called g. The return value type is void indicating that it does not return a value. Just like with your geometric shape classes in Part 1, youll need a statement at the top of your ShapeManager.java file that says import java.awt.Graphics; that imports the Graphics class.
The paintShapes() method should do the following:
Your ShapeManager has a reference to a Rectangle object as a member variable. The paintShapes() method should have a statement that calls the Rectangle objects paint() method, passing g as the parameter to it. However there may not be a rectangle object if it has not been created yet, or if it has been deleted. Therefore paintShapes() should only call paint() on the rectangle object if the reference to the rectangle object is not the value null. (Hint: use an if statement to take care of this). If you dont do this, youll get a null pointer exception error when you run your program.
Do the same as #1, but with your ShapeManagers Circle, Triangle, and Line references. In all, your paintShapes() method should have four separate if statements.
The Complete Program
If your ShapeManager class is written correctly, you should be able to compile your FairfieldDraw, FairfieldDrawHelper, ShapeType, ShapeManager, Line, Rectangle, Triangle, and Circle classes together in the same project. When you run FairfieldDraw (which has a public static void main()), it should open an application in a second window, but the console will still be active. Follow instructions on the console to draw shapes on the second window. However, your program can only draw at most one rectangle, one circle, one square, and one line.
Code provided:
Fairfield Draw:
import java.awt.*;
import javax.swing.*;
public class FairfieldDraw extends JPanel {
static final long serialVersionUID = 1L;
ShapeManager manager;
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5));
manager.paintShapes(g);
}
static ShapeType convertToShapeType(char c) {
switch (c) {
case 'r': return ShapeType.rectangle;
case 'c': return ShapeType.circle;
case 't': return ShapeType.triangle;
case 'l': return ShapeType.line;
default: return ShapeType.none;
}
}
public static void main(String args[]) {
FairfieldDraw draw = new FairfieldDraw();
draw.manager = new ShapeManager();
draw.setVisible(true);
JFrame frame = new JFrame();
frame.setSize(800, 500);
frame.setTitle("Fairfield Draw");
frame.add(draw);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int newShapeX, newShapeY;
char shapeTypeChar;
ShapeType shapeType;
System.out.println("What operation would you like to perform?");
System.out.println("Enter c to create a shape, or d to delete a shape. Enter q to quit.");
char operation = FairfieldDrawHelper.nextCharacter();
while (operation == 'c' || operation == 'd') {
if (operation == 'c') {
System.out.println("What type of object would you like to create?");
System.out.println("Enter r for rectangle, t for triangle, l for line, c for circle. Then press return.");
shapeTypeChar = FairfieldDrawHelper.nextCharacter();
System.out.println("Where would you like to create it? Enter x and y components of position.");
System.out.println("Enter two integers. Press return after each integer.");
newShapeX = FairfieldDrawHelper.nextInteger();
newShapeY = FairfieldDrawHelper.nextInteger();
shapeType = convertToShapeType(shapeTypeChar);
draw.manager.createShape(shapeType, newShapeX, newShapeY);
} else {
System.out.println("What type of object would you like to create?");
System.out.println("Enter r for rectangle, t for triangle, l for line, c for circle. Then press return.");
shapeTypeChar = FairfieldDrawHelper.nextCharacter();
shapeType = convertToShapeType(shapeTypeChar);
draw.manager.deleteShape(shapeType);
}
draw.repaint();
System.out.println("What operation would you like to perform?");
System.out.println("Enter c to create a shape, or d to delete a shape. Enter q to quit.");
operation = FairfieldDrawHelper.nextCharacter();
}
System.exit(0);
}
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
