/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ /* * @(#)AbstractConnector.java 3.0 2007-05-18 * * Copyright (c) 1996-2007 by the original authors of JHotDraw * and all its contributors. * All rights reserved. * * The copyright of this software is owned by the authors and * contributors of the JHotDraw project ("the copyright holders"). * You may not use, copy or modify this software, except in * accordance with the license agreement you entered into with * the copyright holders. For details see accompanying license terms. */ package 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; /** * AbstractConnector provides default implementation for * the Connector interface. * * @see Connector * * @author Werner Randelshofer * @version 3.0 2007-05-18 Rewritten due to changes in Connector interface. * <br>2.1 2006-06-05 Support connection to decorator. * <br>2.0 2006-01-14 Changed to support doubl precision coordinates. * <br>1.0 2003-12-01 Derived from JHotDraw 5.4b1. */ public class AbstractConnector implements Connector { /** * The owner of the connector */ 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. */ public boolean contains(Point2D.Double p) { return getOwner().contains(p); } public Point2D.Double findStart(ConnectionFigure connection) { return findPoint(connection); } 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. */ public Figure getOwner() { return owner; } /** * Sets the connector's owner. */ protected void setOwner(Figure newValue) { owner = newValue; } 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) { } public Point2D.Double getAnchor() { return Geom.center(getBounds()); } public void updateAnchor(Point2D.Double p) { } public Rectangle2D.Double getBounds() { return isConnectToDecorator() ? ((DecoratedFigure) getOwner()).getDecorator().getBounds() : getOwner().getBounds(); } 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(); } public void write(DOMOutput out) throws IOException { if (isStatePersistent) { if (isConnectToDecorator) { out.addAttribute("connectToDecorator", true); } } out.openElement("Owner"); out.writeObject(getOwner()); out.closeElement(); } public Rectangle2D.Double getDrawingArea() { Point2D.Double anchor = getAnchor(); return new Rectangle2D.Double(anchor.x - 4, anchor.y - 4, 8, 8); } 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); } }