Objective

Implement multiple shape objects in such a way that they can be rendered to the screen and manipulated by the mouse. You will practice implementing interfaces, class hierarchies, abstract classes, and ArrayLists. You will also be exposed to polymorphism and graphical user interface programming.

Functional Requirements

Clicking on any of the “new XYZ” buttons on the top toolbar will create a shape of that type, randomly sized and positioned, on the drawing canvas. The Clear button will delete all shapes. You must be able to create Rectangles, Squares, Circles, Ovals, and Triangles. You may optionally support hexagons and octagons for bonus points.

Z-order

Objects should respect Z-order, the most recently added shape should be drawn “on top” of other objects. When a shape is clicked on, it should be moved to the front of the Z-order and be drawn on top of all other objects.

Hot state

When the mouse hovers over a shape, it should become “hot”, and rendered differently. In our case, we will render an object “hot” by filling it with its border color. Non-hot shapes will be filled with white. Multiple objects can be “hot” at the same time if the mouse hovers over overlapping shapes.

Drag to reposition

When the user performs mouse drag starting on a shape, it will move with the mouse to a new location. It should update in real time as the mouse moves. Only a single shape should be moved at a time, if multiple shapes hit test the topmost one should be grabbed for the drag operation. A drag operation should have no effect on the Z-order.

Dynamic Background Color

The background color of the panel should gradually transition from white to black as more shapes are added. This darkening should correspond to the cumulative area of all added shapes as a ratio to the total pane area – 0:1 area is white, 1:1 (or greater) is black.

Color

A toolbar may be implemented that allows the user to change the color of new shapes created, and clicking on a shape will also change its color along with bringing it to the front of the Z-order.

Architecture Requirements

Shape classes

All shapes must implement the Shape interface, as defined here:

  • interface Shape this method should render your Shape. If the shape is in the "hot" state, meaning the mouse is over the shape, it should render fully opaque, with color specified by setColor. If the shape is not in the hot state, it should render a white background (fill) and just a border in the color specified by setColor.
  • public void render(Graphics g); determine if the given point is within the shape. Keep track of if the shape is currently hit tested or not, and call listener.OnHitTestChange() whenever the state changes. You will need this state to determine if it should be rendered in the "hot" state or not.
  • public boolean hitTest(Point pt, HitTestChangeListener listener); allow the outline color to be set (or fill color while in the "hot" state).
  • public void setColor(Color color); calculate the area of the shape.
  • public double getArea(); get/set the position of the shape. This point can be anywhere on (or even off) the shape that you want, but you must be consistent and accept a change to setPosition().
  • public Point getPosition();
  • public void setPosition(Point point);

You encouraged to implement additional base classes (some of which may be abstract) to implement all required shapes in an effort to eliminate redundancy.

ShapeFactory

The shapes should be created by the ShapeFactory, for which you will complete the implementation. This class should determine a random place to position the new shape along with random parameters (size, width, etc), then call into the constructors for the various Shape classes you implemented. No shape should ever have a shape greater than 25% of the total pane’s area.

DrawingArea

You will need to implement a DrawingArea class, which extends the abstract class DrawingAreaBase and implements the required methods. These methods are:

  • abstract public double getTotalShapeArea(); compute the cummulative area of all shapes
  • abstract public void renderShapes(Graphics g); render all shapes
  • abstract public Shape findFirstShapeHit(Point point); find the first shape hit by the given point
  • abstract public void handleShapeClicked(Shape shape); handle a click event on the current shape as per functional requirements
  • abstract public void hitTestAllShapes(Point point); perform hit testing on all shapes
  • abstract public void addShape(Shape s); add a shape to the drawing area
  • abstract public void removeAllShapes(); remove all shapes from the drawing area

An ArrayList will probably be helpful.

Color Selection

Modify the ShapePanel class to include a second toolbar for selecting new shape color. See image.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.