CPE 102 Program 3 - Interfaces

 

Ground Rules

No collaboration is allowed on this program assignment. Your program must be an individual and original effort. Except for any situations explicitly identified in this assignment, if any, you may only receive help from your instructor or the tutors provided by the Computer Science Department. See the Syllabus for the significant consequences for disallowed collaboration and/or plagiarism.

 

Due Date and Submission Instructions

Notice that no tests are required to be handed in for this assignment. You are, however, strongly encouraged to test - especially any methods whose correctness that you are less than sure about.

Submit the following file(s) on one of the CSL servers using handin as follows:

    File(s): Canvas.java, Circle.java, ConvexPolygon.java, Rectangle.java, Shape.java, and Triangle.java 

    touser: eaugusti

    assignment/subdirectory: 102-program03


Testing With the Provided Test Driver
  1. The test driver will be published on the first due date for the assignment, usually by 10:00am.
  2. You should develop and use your own tests prior to using the provided test driver. Do not use the provided test driver until your solution is complete and you believe it is correct or you are likely to be overwhelmed with error messages and will spend unnecessary time just trying to understand the test driver - a frustrating and inefficient way to approach problem solving with computers!

  3. Using the save-as feature of your browser (or wget/curl if you are a cool kid), not cut-and-paste, save P3TestDriver.java (to be published on the due date) in the same directory as all of the source files (.java files)

  4. Compile the P3TestDriver.java, all of your source files (.java files) and run P3TestDriver (see How to Compile and Run From the Command Line, as necessary). Remember that your code will be graded on unix1 (2, 3, or 4) so, to avoid unpleasant grading surprises be sure to test on one of those machines just before handing it in!


Objectives

       

        Orientation

        You will be creating a virtual drawing canvas on which you can place various geometric shapes. You will not actually be drawing the shapes in this program, rather, you will simply be representing geometric shapes as objects and providing the ability to place them in space. The canvas will make use of an ArrayList from the Java Standard Library to collect shapes and will have methods that allow you to add, remove, and inspect the shapes it contains. All of the shapes share a common set of methods defined by a Java interface.  The behavior of these common methods varies, as appropriate, by shape. In addition, each shape has one or more methods unique to it.  The following shapes will be supported: circle, rectangle, triangle, and convex polygon.



        Suggestions

        1. Remember and use - where necessary and appropriate - the instanceof operator in the appropriate places of your solution. 

        2. Implement the Shape interface and document each of the method declarations.  Write the comments in a generic fashion that reads well for any shape you might implement.  The javadoc utility will use the javadoc comments from the interface to generate the html documentation for any class that implements the interface.  This saves you the trouble of documenting the same methods multiple times in Circle, Rectangle, Triangle, ConvexPolygon, or any other class that my implement the Shape interface in the future.

        3. Implement one shape at a time.  Test and debug the shape until you are satisfied with its design, implementation, and functionality then implement the remaining shapes.

        4. Implement the Canvas class incrementally.  Notice that many of the methods are very similar and differ only by the shape-type they work with.  Implement one of methods that works with a single shape-type, test this code until you are satisfied it is working correctly - you'll then be able to cut and paste it, with minor modification, as the solution for the other similar methods.

        5. Remember that you may import classes from the Java Standard API used in your implementation and do not need to use the fully qualified package names as done in this specification (done here to reduce potential ambiguities).

        6. For funsies I made you a driver that can draw your canvas for you: Draw.java. Read the source code to figure out how to use it. This driver is in no way an exhaustive test, but it can be a good graphical check to see if you are on the right path. I recomend modifying the driver to use one shape at a time. Warning: this driver needs ConvexPolygon to be complete before it can draw any shape except a Circle.


        Specification

        1. Your source code must meet the Programming Guidelines.

        2. Your solution must pass all test of the provided test driver (link and instruction provided below) when compiled and run on unix1, (2, 3 or 4).
        3. All classes must use the minimally necessary number of instance variables of appropriate types and that maintain encapsulation (private). In most cases the specific instance variables are not specified. You are required to make well-reasoned choices as to the data types and number of instance variables used.  Remember, each instance variable makes every object of the class require more memory.  All instance variables should be essential to defining the state of an object and/or provide a significant computational efficiency and/or allow for a significant reduction in code complexity.  All other variables should be declared as local variables in the method where they are used. Be ready to justify your choices.

        4. Note that all class in this specification that are from the Java Standard Library use their full package specification for clarity only. You may import these classes in your code and then are not required to use the full package specification. For example, if you see java.awt.Color as a return type or parameter you may import java.awt.Color and simple use Color as the return type or parameter.
        5. Document all methods in the Shape interface using the javadoc-style of documentation. See How to write Javadoc comments for assistance. You are not required to write javadoc-style comments for any other methods in any other files.

        6. Write a Java interface called Shape with the following methods:

          1. public double getArea() - Calculates and returns the area of the shape.

          2. public java.awt.Color getColor() - Returns the color of the shape.

          3. public void setColor(java.awt.Color color) - Sets the color of the shape.

          4. public boolean getFilled() - Returns true if the shape is filled with color, otherwise false (shape is wire-framed).

          5. public void setFilled(boolean filled) - Sets the filled state of the shape to the specified value.

          6. public java.awt.Point getPosition() - Returns the currrent position of the shape.

          7. public void setPosition(java.awt.Point position) - Changes the position of the shape to the specfied Point.

          8. public void move(java.awt.Point delta) - Moves the shape by the x and y amounts specified (in the Point delta).

        7. Write a class called Circle as follows:
          1. Implements the Shape interface.

          2. Implements the following additional public methods:

            1. Circle(double radius, java.awt.Point position, java.awt.Color color, boolean filled) - Constructor.  This specification should give you a large clue as to what the instance variables of the class should be!  Note that the java.awt.Point specifies the location of the center of the circle.

            2. double getRadius() - Returns the radius of the Circle object.
            3. void setRadius(double radius) - Sets the radius of the Circle object.

            4. Override the equals-method (inherited from Object) so that it returns true for two Circle objects that are logically equivalent based on the state of all of their instance variables. See How to override the equals method for assistance.

          3. Note: Be sure to use the constant Math.PI (a constant defined in the Math class found in the Java Standard Library) when performing any calculations involving PI.

        8. Write a class called Rectangle as follows:
          1. Implements the Shape interface.

          2. Implements the following additional public methods:

            1. Rectangle(int width, int height, java.awt.Point position, java.awt.Color color, boolean filled) - Constructor.  This should give you a large clue as to what the instance variables of the class should be!  Note that the java.awt.Point specifies the location of the lower-left corner of the rectangle.

            2. int getWidth() - Returns the width of the Rectangle object.
            3. void setWidth(int width) - Sets the width of the Rectangle object.

            4. int getHeight() - Returns the height of the Rectangle object.

            5. void setHeight(int height) - Sets the height of the Rectangle object.

            6. Override the equals-method (inherited from Object) so that it returns true for two Rectangle objects that are logically equivalent based on the state of all of their instance variables. See How to override the equals method for assistance.

        9. Write a class called Triangle as follows:
          1. Implements the Shape interface. Here is a link to a description of how to calculate the area of a general triangle.

          2. Implements the following additional public methods:

            1. Triangle(java.awt.Point a, java.awt.Point b, java.awt.Point c, java.awt.Color color, boolean filled) - Constructor.  This should give you a large clue as to what the instance variables of the class should be!  Note that the java.awt.Point objects represent the three vertices of the triangle in the specified order, i.e., a, b, c, and that the point represented by the parameter a represents the position of the triangle.
            2. java.awt.Point getVertexA() - Returns a specific vertex of the triangle.

            3. void setVertexA(java.awt.Point point) - Sets a specific vertex of the triangle.
            4. java.awt.Point getVertexB() - Returns a specific vertex of the triangle.

            5. void setVertexB(java.awt.Point point) - Sets a specific vertex of the triangle.

            6. java.awt.Point getVertexC() - Returns a specific vertex of the triangle.

            7. void setVertexC(java.awt.Point point) - Sets a specific vertex of the triangle.

            8. Override the equals-method (inherited from Object) so that it returns true for two Triangle objects that are logically equivalent based on the state of all of their instance variables. See How to override the equals method for assistance.

        10. Write a class called ConvexPolygon as follows:
          1. Implements the Shape interface. Here is a link to a description of how to calculate the area of a convex polygon

          2. Implements the following additional public methods:

            1. ConvexPolygon(java.awt.Point[] vertices, java.awt.Color color, boolean filled) - Constructor.  This should give you a large clue as to what the instance variables of the class should be!  Note that the array of java.awt.Point objects represents each vertex of the polygon and that the vertex at index zero represents the position of the convex polygon.
              1. A precondition is a condition that the caller of a method must meet. If the caller meets the precondition(s) of a method then the method should always produce the correct result. If the caller of a method does not meet the precondition(s) then the method is under no obligation to work correctly. In other words, you can assume the parameters meet the preconditions and do not need to verify them - a simplification of the problem and code! Note, however, that the caller does have a responsibility to meet the preconditions - you will be the caller when you test the method (you are following TDD aren't you?!?) so be sure to meet them in you test code!

              2. This constructor has a precondition that the array of vertices passed in will be full, i.e., there will be Point references in every location from index zero up to its length-1.
              3. This constructor has a precondition that the vertices be provided in counter-clockwise order. This precondition simplifies the calculation of area.

              4. This constructor has a precondition that the polygon is not closed. This mean that the first and last point are not the same point (no duplicate points).

            2. java.awt.Point getVertex(int index) - Returns the specified vertex.

            3. void setVertex(int index, java.awt.Point vertex) - Sets the specified vertex of the polygon.

            4. int numVertices() - Gets the number of vertices in this polygon.

            5. Override the equals-method (inherited from Object) so that it returns true for two ConvexPolygon objects that are logically equivalent based on the state of all of their instance variables.  When considering the vertices, consider two polygons equal only when the have the same vertices in the same order. See How to override the equals method for assistance.

        11. Write a class called Canvas as follows:
          1. Has one (and only one) instance variable of type java.util.ArrayList<Shape>.

          2. Implements the following public methods:

            1. Canvas() - Default Constructor.

            2. void add(Shape shape) - Adds objects which implement the Shape interface to the end of the Canvas's java.util.ArrayList<Shape>  instance variable.
            3. Shape remove(int index) - Removes the Shape at the specified index and returns a reference to it or null if the index is out-of-bounds.

            4. Shape get(int index) - Return the ith Shape object from Canvas.

            5. int size() - Returns the number of Shapes contained by the Canvas.

            6. java.util.ArrayList<Circle> getCircles() - Returns a java.util.ArrayList of all of the Circle objects contained in the Canvas.

            7. java.util.ArrayList<Rectangle> getRectangles() - Returns a java.util.ArrayList of all of the Rectangle objects contained in the Canvas.

            8. java.util.ArrayList<Triangle> getTriangles() - Returns a java.util.ArrayList of all of the Triangle objects contained in the Canvas.

            9. java.util.ArrayList<ConvexPolygon> getConvexPolygons() - Returns a java.util.ArrayList of all of the ConvexPolygon objects contained in the Canvas.

            10. java.util.ArrayList<Shape> getShapesByColor(java.awt.Color color) - Returns a java.util.ArrayList of all Shape objects in the Canvas that match the specified java.awt.Color.

            11. double getAreaOfAllShapes() - Returns the sum of the area of all Shape objects in the Canvas.

        Program courtesy of Kurt Mammen.