package husacct.graphics.domain.figures; import husacct.graphics.domain.decorators.Decorator; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import org.jhotdraw.draw.AbstractAttributedCompositeFigure; import org.jhotdraw.draw.AttributeKeys; import org.jhotdraw.draw.ConnectionFigure; import org.jhotdraw.draw.connector.ChopRectangleConnector; import org.jhotdraw.draw.connector.Connector; import org.jhotdraw.draw.handle.BoundsOutlineHandle; import org.jhotdraw.draw.handle.Handle; public abstract class BaseFigure extends AbstractAttributedCompositeFigure { private static final long serialVersionUID = 971276235252293165L; public static final Color defaultBackgroundColor = new Color(252,255,182); protected int baseZIndex, zIndex, raiseZIndex; protected final String name; // Leaf name, not unique; shown as the name of the figure in diagrams protected final String uniqueName; //Used in equals() to identify objects uniquely protected final String type; // In lower case. Used to identify the module type, like subsystem, layer, package, class; also in case of a ParentFigure. private final ArrayList<Decorator> decorators = new ArrayList<Decorator>(); private boolean isSizeable = false; private boolean isEnabled = true; private boolean isStoredInContainer = false; private boolean isContext = false; public BaseFigure(String name, String uniqueName, String type) { super(); this.name = name; this.uniqueName = uniqueName; this.type = type; baseZIndex = 0; raiseZIndex = 5; zIndex = baseZIndex; } public void addDecorator(Decorator decorator) { decorators.add(decorator); } @Override public BaseFigure clone() { BaseFigure other = (BaseFigure) super.clone(); return other; } @Override public Collection<Handle> createHandles(int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); if (isSizeable) handles.addAll(createSizeableHandles(detailLevel)); else handles.addAll(createSelectionHandles(detailLevel)); return handles; } private Collection<Handle> createSelectionHandles(int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); if (detailLevel == 0) { Handle handle = new BoundsOutlineHandle(this, false, false); handles.add(handle); } return handles; } private Collection<Handle> createSizeableHandles(int detailLevel) { return super.createHandles(detailLevel); } @Override public void draw(Graphics2D g) { for (Decorator decorator : decorators) decorator.decorate(this); this.set(AttributeKeys.CANVAS_FILL_COLOR, defaultBackgroundColor); super.draw(g); } @Override protected void drawFill(Graphics2D g) { // This function is used by the JHotDraw framework to draw the // 'background' of a figure. // Since the BaseFigure is a composite figure it will not have to draw // it's background and therefore this function is empty. However, it // cannot be removed // because of the requirements to override it. } @Override protected void drawStroke(Graphics2D g) { // This function is used by the JHotDraw framework to draw the outline // of a figure // Since the BaseFigure is a composite figure it will not have to draw // it's outline // and therefore this function is empty. However, it cannot be removed // because of the // requirements to override it. } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; BaseFigure other = (BaseFigure) obj; if (uniqueName == null) { if (other.uniqueName != null) return false; } else if (!uniqueName.equals(other.uniqueName)) return false; return true; } @Override public Connector findConnector(Point2D.Double p, ConnectionFigure figure) { return new ChopRectangleConnector(this); } @Override public int getLayer() { return zIndex; } public String getName() { return name; } public String getUniqueName() { return uniqueName; } public String getType(){ return type; } public double getHeight() { return getBounds().height; } public double getWidth() { return getBounds().width; } public boolean isContext() { return isContext; } public void setContext(boolean b) { this.isContext = b; } public boolean isEnabled() { return isEnabled; } public boolean isInContainer() { return isStoredInContainer; } public boolean isLine() { // Overridden by RelationFigure return false; } public boolean isModule() { // Overridden by ModuleFigure return false; } public boolean isParent() { // Overridden by ParentFigure return false; } public boolean isSizeable() { return isSizeable; } public void raiseLayer() { zIndex = raiseZIndex; } public void removeDecorator(Decorator decorator) { willChange(); decorator.deDecorate(this); decorators.remove(decorator); changed(); } public void removeDecoratorByType(Class<?> searchClass) { ArrayList<Decorator> removes = new ArrayList<Decorator>(); for (Decorator decorator : decorators) if (decorator.getClass().isAssignableFrom(searchClass)) removes .add(decorator); removeDecorators(removes.toArray(new Decorator[] {})); } public void removeDecorators(Decorator[] decorators) { for (Decorator decorator : decorators) removeDecorator(decorator); } public void resetLayer() { zIndex = baseZIndex; } public void setEnabled(boolean newValue) { isEnabled = newValue; setVisible(newValue); setSelectable(newValue); } public void setInContainer(boolean value) { isStoredInContainer = value; } public void setSizeable(boolean newValue) { isSizeable = newValue; } public void setStrokeColor(Color newColor) { this.set(AttributeKeys.STROKE_COLOR, newColor); } @Override public void transform(AffineTransform at) { Point2D.Double anchor = getStartPoint(); Point2D.Double lead = getEndPoint(); Point2D.Double newAnchor = new Point2D.Double(0, 0), newLead = new Point2D.Double(0, 0); newAnchor = (Point2D.Double) at.transform(anchor, newAnchor); newLead = (Point2D.Double) at.transform(lead, newLead); this.setBounds(newAnchor, newLead); } public void updateLocation(double x, double y) { willChange(); double widthX = x + getBounds().getWidth(); double heightY = y + getBounds().getHeight(); this.setBounds(new Point2D.Double(x, y), new Point2D.Double(widthX, heightY)); changed(); } @Override public String toString() { String representation = ""; representation += "\nUniqueName: " + uniqueName; representation += "\nType: " + type + ", IsContext: " + isContext; representation += "\n"; return representation; } }