views:

202

answers:

3

I am making a drawing program, and have a few question with regards to that.

I'll need the user to have the choice of drawing a rectangle, an oval and a line. I suppose I need to make a super class they all derive from. Should I make this an interface or an abstract class? And how would I set up that all the shapes have some default values when they are created, like the colour etc.

The user will use the mouse to click on the screen, and the program should make the shape with center where the user click, and use previously inputted height and length to draw it. What is the easiest way to store points gathered in the frame, and do I even need to store this information?

I also would like the user to have the option to scale the shape he has just drawn, by dragging the sides. How can I most easily set this up?

Edit: Cheers. I will try with a somewhat light-weigth MVC. I have a class DrawingModel and DrawingPanel which I instantiate in View, and then pass the DrawingModel object to the DrawingPanel object through a setModel method. One question however arises, which I can't get my head around; what part of the program will have to take care of the listeners? I suppose have to be implemented by View, but where do I place the ActionListeners?

+3  A: 

If you want all the shapes to have some common required properties (and perhaps methods), abstract class is probably the best choice. You can set these in the abstract class definition:

abstract class AbstractShape
{
    private static final Color DEFAULT_COLOR = Color.BLUE;
    private static final float DEFAULT_LINE_WIDTH = .5f;

    protected Color color = DEFAULT_COLOR;
    protected float lineWidth = DEFAULT_LINE_WIDTH;
}

class Circle extends AbstractShape
{

}

EDIT: Just to clarify, the abstract class can have a constructor, such as:

protected AbstractShape()
{
     color =  DEFAULT_COLOR; 
     lineWidth = DEFAULT_LINE_WIDTH 
}
Matthew Flaschen
A better alternative to providing constants your subclasses must reference explicitly is to define a default constructor which handles this, which subclasses can override as necessary.
Soonil
The assignments (color = DEFAULT_COLOR) can easily be moved to a constructor in the abstract class, if desired. However, with the original code above, the subclasses can already freely override the instance data (color, lineWidth).
Matthew Flaschen
+2  A: 

Have a look at the MVC design pattern. In your case, you should be creating a model object which is a collection of shapes.

Your drawing area (e.g. canvas or panel or whatever), should implement MouseListener and MouseMotionListener in order to capture mouse events. You can find out where the user has clicked by using MouseEvent's getX() and getY() methods. You can then store this shape into the model and repaint() the area.

For scaling, you will have to make use of the mouseDragged() and mouseReleased() methods which will give you the x,y coordinates. You need to identify the shape a user has clicked on, and then change its width and height based on how far the user has dragged (this could be determined by subtracting the original x,y from the new x,y coordinates).

dogbane
I agree this is good to know about, but /real/ MVC is probably overkill for what sounds like a small school project.
Matthew Flaschen
+1  A: 

To respond to your edit: It is the view that will have the ActionListener that are attached to components. Then you could have the view notify the controller (through a listener) if the model needs to be updated. When the model is updated it will usually notify the controller through a property change listener so that the controller can update the view.

willcodejavaforfood