AbstractShape implements Shape (these are drawable shapes): BoxShape EllipseShape, ImageShape, RectangleShape, TextShape LineShape ArrowShape ContainerShape: Holds groups of Shape objects CanvasShape: The object that provides a surface on which Shapes are drawn Shape Interface: addInteractor/removeInteractor: adds an event handler to this object draw(Graphics2D): renders the object using the given Graphics2D context contains(x,y): indicates whether or not the object contains the given (x,y) point getBounds: returns the bounding box for this object Example draw routine for a TextShape: public void draw(Graphics2D g) { if (visible) { if (filled) { // fill a box behind the TextShape g.setColor(fillColor); // width and height may require a special calculation g.fillRect(left, top, getWidth(), getHeight()); } g.setColor(lineColor); g.setFont(font); FontMetrics fm = g.getFontMetrics(); g.drawString(text, left, top + fm.getAscent()); } DisplayManager interface display(Graphics2D g): draws all the shapes in the canvas damage(Rectangle r): indicates what portion of the canvas has changed and needs to be redrawn setCanvas(CanvasShape): indicates which canvas this display manager will be managing
Subclasses: BoxShape, LineShape Defined properties visible parent lineColor fillColor Filled: whether or not the object is filled or transparent There is no location or size attributes because rectangular objects and line objects represent this information differently Line objects might not have a fill color but arrowlines might, so it is okay to have the fillColor property defined for line objects
BoxShape Subclasses: EllipseShape, ImageShape, RectangleShape, TextShape Defined properties left, top width, height
LineShape Subclasses: ArrowLineShape Defined properties x1, y1 x2, y2
ContainerShape: container object--uses a BoxShape for composition. Does not want to provide an interface that allows the setting of line or fill properties, so it cannot be a subclass of BoxShape Defined properties shapes: list of shapes for this container layoutManager: the layout manager for this container New methods add: adds an object to the container bringToFront/sendToBack: brings an object to the front of the container or sends it to the back, so that it is covered by the other objects in the container getShapes: returns a list of the shapes in this container, ordered from back to front (i.e., the first items in the list should be in back and the last items should be in front) get/setLayoutManager revalidate: asks the layout manager to re-layout the objects in the container public void draw(Graphics2D g) { for each shape in getShapes() { shape.draw(g); } }
CanvasShape: creates a JPanel that can be added to a Java container Superclass: JPanel Uses a ContainerShape for composition, since a CanvasShape is essentially a container object. It will delegate the add, getShapes, and BringToFront/SendToBack methods to the container while ignoring the layout methods, since it will be communicating with a display manager instead Methods void setDisplayManager(DisplayManager d) { displayMgr = d; } paintComponent(Graphics g) { super.paintComponent(g); displayMgr.Display((Graphics2D)g); }
The following pseudo-code shows how a sample display manager might be implemented:
class TotalRedraw implements DisplayManager { CanvasShape canvas; public void setCanvas(CanvasShape c) { canvas = c; } public void damage(Rectangle r) { // do nothing since we are doing a total redraw } public void Display(Graphics2D g) { for each shape in canvas.getShapes() { shape.draw(g); } } }