/* * @(#)AbstractConnector.java * * Copyright (c) 1996-2010 The authors and contributors of JHotDraw. * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.draw.connector; import edu.umd.cs.findbugs.annotations.Nullable; import org.jhotdraw.draw.*; import java.io.IOException; import java.awt.*; import java.awt.geom.*; import org.jhotdraw.geom.*; import org.jhotdraw.xml.DOMInput; import org.jhotdraw.xml.DOMOutput; import org.jhotdraw.xml.DOMStorable; /** * This abstract class can be extended to implement a {@link Connector}. * * @see Connector * * @author Werner Randelshofer * @version $Id$ */ public class AbstractConnector implements Connector, DOMStorable { private static final long serialVersionUID = 1L; /** * The owner of the connector */ @Nullable private Figure owner; /** * Whether we should connect to the figure or to its decorator. */ private boolean isConnectToDecorator; /** * Whether the state of this connector is persistent. * Set this to true only, when the user interface allows to change the * state of the connector. */ private boolean isStatePersistent; /** * Constructs a connector that has no owner. It is only * used internally to resurrect a connectors from a * StorableOutput. It should never be called directly. */ public AbstractConnector() { owner = null; } /** * Constructs a connector with the given owner figure. */ public AbstractConnector(Figure owner) { this.owner = owner; } public void setConnectToDecorator(boolean newValue) { isConnectToDecorator = newValue; } public boolean isConnectToDecorator() { return isConnectToDecorator; } protected final Figure getConnectorTarget(Figure f) { return (isConnectToDecorator && ((DecoratedFigure) f).getDecorator() != null) ? ((DecoratedFigure) f).getDecorator() : f; } /** * Tests if a point is contained in the connector. * This implementation tests if the point is contained by the figure * object, which owns this connector. */ @Override public boolean contains(Point2D.Double p) { return getOwner().contains(p); } @Override public Point2D.Double findStart(ConnectionFigure connection) { return findPoint(connection); } @Override public Point2D.Double findEnd(ConnectionFigure connection) { return findPoint(connection); } /** * Gets the connection point. Override when the connector * does not need to distinguish between the start and end * point of a connection. */ protected Point2D.Double findPoint(ConnectionFigure connection) { return Geom.center(getBounds()); } /** * Gets the connector's owner. */ @Override public Figure getOwner() { return owner; } /** * Sets the connector's owner. */ protected void setOwner(Figure newValue) { owner = newValue; } @Override public Object clone() { try { AbstractConnector that = (AbstractConnector) super.clone(); return that; } catch (CloneNotSupportedException e) { InternalError error = new InternalError(e.toString()); //error.initCause(e); <- requires JDK 1.4 throw error; } } /** * This is called, when the start location of the connection has been * moved by the user. The user has this probably done, to adjust the layout. * The connector may use this as a hint to improve the results for the next * call to findEnd. */ public void updateStartLocation(Point2D.Double p) { } /** * This is called, when the end location of the connection has been * moved by the user. The user has this probably done, to adjust the layout. * The connector may use this as a hint to improve the results for the next * call to findStart. */ public void updateEndLocation(Point2D.Double p) { } @Override public Point2D.Double getAnchor() { return Geom.center(getBounds()); } @Override public void updateAnchor(Point2D.Double p) { } @Override public Rectangle2D.Double getBounds() { return isConnectToDecorator() ? ((DecoratedFigure) getOwner()).getDecorator().getBounds() : getOwner().getBounds(); } @Override public void read(DOMInput in) throws IOException { if (isStatePersistent) { isConnectToDecorator = in.getAttribute("connectToDecorator", false); } if (in.getElementCount("Owner") != 0) { in.openElement("Owner"); } else { in.openElement("owner"); } this.owner = (Figure) in.readObject(0); in.closeElement(); } @Override public void write(DOMOutput out) throws IOException { if (isStatePersistent) { if (isConnectToDecorator) { out.addAttribute("connectToDecorator", true); } } out.openElement("Owner"); out.writeObject(getOwner()); out.closeElement(); } @Override public Rectangle2D.Double getDrawingArea() { Point2D.Double anchor = getAnchor(); return new Rectangle2D.Double(anchor.x - 4, anchor.y - 4, 8, 8); } @Override public void draw(Graphics2D g) { Point2D.Double anchor = getAnchor(); Ellipse2D.Double e = new Ellipse2D.Double(anchor.x - 3, anchor.y - 3, 6, 6); g.setColor(Color.BLUE); g.fill(e); //g.setColor(Color.BLACK); //g.draw(e); } }