/*
* @(#)ConnectionHandle.java 5.1
*
*/
package CH.ifa.draw.standard;
import java.awt.*;
import CH.ifa.draw.framework.*;
import CH.ifa.draw.util.Geom;
/**
* A handle to connect figures.
* The connection object to be created is specified by a prototype.
*
* Design Patterns
*
* Prototype
* ConnectionHandle creates the connection by cloning a prototype.
*
*
* @see ConnectionFigure
* @see Object#clone
*/
public class ConnectionHandle extends LocatorHandle {
/**
* the currently created connection
*/
private ConnectionFigure fConnection;
/**
* the prototype of the connection to be created
*/
private ConnectionFigure fPrototype;
/**
* the current target
*/
private Figure fTarget = null;
/**
* Constructs a handle with the given owner, locator, and connection prototype
*/
public ConnectionHandle(Figure owner, Locator l, ConnectionFigure prototype) {
super(owner, l);
fPrototype = prototype;
}
/**
* Creates the connection
*/
public void invokeStart(int x, int y, DrawingView view) {
fConnection = createConnection();
Point p = locate();
fConnection.startPoint(p.x, p.y);
fConnection.endPoint(p.x, p.y);
view.drawing().add(fConnection);
}
/**
* Tracks the connection.
*/
public void invokeStep (int x, int y, int anchorX, int anchorY, DrawingView view) {
Point p = new Point(x,y);
Figure f = findConnectableFigure(x, y, view.drawing());
// track the figure containing the mouse
if (f != fTarget) {
if (fTarget != null)
fTarget.connectorVisibility(false);
fTarget = f;
if (fTarget != null)
fTarget.connectorVisibility(true);
}
Connector target = findConnectionTarget(p.x, p.y, view.drawing());
if (target != null)
p = Geom.center(target.displayBox());
fConnection.endPoint(p.x, p.y);
}
/**
* Connects the figures if the mouse is released over another
* figure.
*/
public void invokeEnd(int x, int y, int anchorX, int anchorY, DrawingView view) {
Connector target = findConnectionTarget(x, y, view.drawing());
if (target != null) {
fConnection.connectStart(startConnector());
fConnection.connectEnd(target);
fConnection.updateConnection();
} else
view.drawing().remove(fConnection);
fConnection = null;
if (fTarget != null) {
fTarget.connectorVisibility(false);
fTarget = null;
}
}
private Connector startConnector() {
Point p = locate();
return owner().connectorAt(p.x, p.y);
}
/**
* Creates the ConnectionFigure. By default the figure prototype is
* cloned.
*/
protected ConnectionFigure createConnection() {
return (ConnectionFigure)fPrototype.clone();
}
/**
* Finds a connection end figure.
*/
protected Connector findConnectionTarget(int x, int y, Drawing drawing) {
Figure target = findConnectableFigure(x, y, drawing);
if ((target != null) && target.canConnect()
&& !target.includes(owner())
&& fConnection.canConnect(owner(), target)) {
return findConnector(x, y, target);
}
return null;
}
private Figure findConnectableFigure(int x, int y, Drawing drawing) {
FigureEnumeration k = drawing.figuresReverse();
while (k.hasMoreElements()) {
Figure figure = k.nextFigure();
if (!figure.includes(fConnection) && figure.canConnect()) {
if (figure.containsPoint(x, y))
return figure;
}
}
return null;
}
protected Connector findConnector(int x, int y, Figure f) {
return f.connectorAt(x, y);
}
/**
* Draws the connection handle, by default the outline of a
* blue circle.
*/
public void draw(Graphics g) {
Rectangle r = displayBox();
g.setColor(Color.blue);
g.drawOval(r.x, r.y, r.width, r.height);
}
}