I have managed to build an inheritance hierarchy for shape class object and I am wondering if there is a better solution to combine the following 2 hierarchies.

To begin, I have a 4 shapes classes triangle, line, oval and square which 3 of (line, oval and square) inherit from abstract class SimpleTwoPointShape and this abstract class with triangle class inherits from an abstract class SimpleShape. In addition triangle, oval and square classes implement SimpleShapeAreaInterface interface. The objects of the classes are created when there are enough points (x,y) to draw the shape (which is selected to draw at that time, as each shape has the necessary number of points to draw it). Points are putted on a canvas as my class where the drawings are being done extend JPanel and override paintComponent.

As the necessary number of points are putted on the canvas the shape is created with all the necessary details and is added to a List and repaint is called, which causes the paintComponent method to be called where inside a loop that loops through all shapes and depending on which kind of shape it is creates a corresponding wrapper class object (triangleDrawer, lineDrawer, ovalDrawer and squareDrawer) which have the method to draw the shape. This 4 wrapper class inherit from an abstract class SimpleDrawer (has a setColor method) and the abstract class implements interface ShapeDrawerInterface which has the draw method.

private class MouseWatcher extends MouseAdapter {

        public void mousePressed(MouseEvent e) {
            // reset the rotation to 0 otherwise things get messy.
            currentRotation = 0;

            if (currentPoints == null) { // must be starting a new shape
                currentPoints = new ArrayList<>();
                Point firstPoint = new Point();
                firstPoint.x = e.getX();
                firstPoint.y = e.getY();
            } else {
                Point nextPoint = new Point();
                nextPoint.x = e.getX();
                nextPoint.y = e.getY();
                if (currentPoints.size() == shapeToDraw.getNumberOfPoints()) {
                    currentPoints = null;
            //repaint(); // causes paintComponent() to be called

    public void paintComponent(Graphics g) {
        // Graphics2D needed to set line thickness
        Graphics2D g2d = (Graphics2D) g;

        Stroke s = g2d.getStroke(); // save stroke to restore later

        // rotate the drawing by the current rotation amount
        double rotateTheta;
        rotateTheta = currentRotation * Math.PI / 180;
        g2d.rotate(rotateTheta, this.getWidth() / 2, this.getHeight() / 2);

        // Loop though the ArrayList drawing
        // all the shapes stored in it
        for(int i=0;i<shapes.size();i++){
            new ContextDrawing(drawingFactory.getDraweShape(shapes.get(i))).executeStrategy(g2d, currentBrightness);

        g2d.setStroke(s);  // restore saved stroke
        if (currentPoints != null) { // draw dot where line started
            for (int i = 0; i < currentPoints.size(); i++) {
                g2d.fillOval(currentPoints.get(i).x, currentPoints.get(i).y, 3, 3);

The hierarchy so far for this is as fallows: https://www.lucidchart.com/publicSegments/view/ef2ea6c4-14a6-4c5b-8b1d-69e8f3317b4d/image.png

Inheritance hierarchies

Is there a better inheritance hierarchy to use for this classes? Are there any design patterns apart from factory that can apply here?

  • 1
    \$\begingroup\$ Welcome to Code Review! Good job on your first question. \$\endgroup\$ – SirPython Mar 28 '16 at 0:32
  • \$\begingroup\$ A line is a non-area shape without volume/dimension. I would not wonder myself about a method like "getSurfaceSize()" on a shape but I would wonder myself about a the method on a line because it makes no sense for a line. \$\endgroup\$ – Peter Rader Mar 28 '16 at 2:34
  • \$\begingroup\$ @PeterRader line does not have an "getArea" method unlike oval,square and triangle. I think the class diagram with interface "SimpleShapeAreaInterface" depicts those classes which have it. Or I did not understand you correctly. \$\endgroup\$ – vsarunov Mar 28 '16 at 9:10
  • \$\begingroup\$ @PeterRader so in my case "SimpleShapeAreaInterface" is implemented only by oval, triangle and square, not by line, but as I understand you, you mean it is a bad way to implement it on each single class if at least one class of the group does not have an area to return? \$\endgroup\$ – vsarunov Mar 28 '16 at 12:38
  • \$\begingroup\$ @vsarunov Sorry, I wrote it wrong: I mean SimpleShapeTwoPointShape. As long as "shape" is in the name, i expect a 2d-volume. This indicates that a SimpleLine indirectly also is a SimpleShape. \$\endgroup\$ – Peter Rader Mar 28 '16 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.