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);
}
}
}