|
Re: Draw2D & GEF: qualified associations [message #1009513 is a reply to message #1005682] |
Fri, 15 February 2013 09:03 |
Tim E. Messages: 56 Registered: November 2012 |
Member |
|
|
Just to help people with the same problem, here is my solution by extending the ConnectionLocator class. May not be the best solution, but at least it is one
public class EndPointFigureLocator extends ConnectionLocator {
private enum POSITION {
NORTH, EAST, SOUTH, WEST;
}
private IFigure figure;
/**
* Constructor
*
* @param connection The {@link Connection} this locator should be used for.
* @param align The alignment of the locator. Only if
* {@link ConnectionLocator#SOURCE} and
* {@link ConnectionLocator#TARGET} will change the behavior. If
* {@link ConnectionLocator#MIDDLE} is passed, the default behavior
* of {@link ConnectionLocator} is used.
* @param figure The {@link IFigure} that should be placed at the Endpoint of
* the connection.
*/
public EndPointFigureLocator(Connection connection, int align, IFigure figure) {
super(connection, align);
this.figure = figure;
}
@Override
protected Point getLocation(PointList points) {
// size of figure
Dimension prefsLabel = figure.getPreferredSize();
int lHeight = prefsLabel.height;
int lWidth = prefsLabel.width;
Connection con = getConnection();
switch (getAlignment()) {
case SOURCE:
ConnectionAnchor sAnchor = con.getSourceAnchor();
IFigure fig = sAnchor.getOwner();
if (fig == null) {
return super.getLocation(points);
}
Rectangle bounds = fig.getBounds();
Point point = points.getPoint(Point.SINGLETON, 0);
switch (computePosition(bounds, point)) {
case EAST:
point = new Point(point.x + lWidth / 2 - 4, point.y);
break;
case NORTH:
point = new Point(point.x, point.y - lHeight / 2);
break;
case SOUTH:
point = new Point(point.x, point.y + 2);
break;
case WEST:
point = new Point(point.x - lWidth / 2 + 2, point.y);
break;
}
return point;
case TARGET:
ConnectionAnchor tAnchor = con.getTargetAnchor();
fig = tAnchor.getOwner();
if (fig == null) {
return super.getLocation(points);
}
bounds = fig.getBounds();
point = points.getPoint(Point.SINGLETON, points.size() - 1);
switch (computePosition(bounds, point)) {
case EAST:
point = new Point(point.x + lWidth / 2 - 4, point.y);
break;
case NORTH:
point = new Point(point.x, point.y - lHeight / 2);
break;
case SOUTH:
point = new Point(point.x, point.y + 2);
break;
case WEST:
point = new Point(point.x - lWidth / 2 + 2, point.y);
break;
}
return point;
case MIDDLE:
if (points.size() % 2 == 0) {
int i = points.size() / 2;
int j = i - 1;
Point p1 = points.getPoint(j);
Point p2 = points.getPoint(i);
Dimension d = p2.getDifference(p1);
return Point.SINGLETON.setLocation(p1.x + d.width / 2, p1.y + d.height / 2);
}
int i = (points.size() - 1) / 2;
return points.getPoint(Point.SINGLETON, i);
default:
return new Point();
}
}
private POSITION computePosition(Rectangle figBounds, Point location) {
int figX = figBounds.x;
int figY = figBounds.y;
int figH = figBounds.height;
int figW = figBounds.width;
int locX = location.x;
int locY = location.y;
if (locX >= figX && locY <= figY) {
return POSITION.NORTH;
}
if (locX >= figX && locY >= figY + figH) {
return POSITION.SOUTH;
}
if (locX <= figX && locY >= figY) {
return POSITION.WEST;
}
if (locX >= figX + figW && locY >= figY) {
return POSITION.EAST;
}
// special case, this is the top left corner
if (locX < figX && locY < figY) {
return POSITION.NORTH;
}
return null;
}
|
|
|
Powered by
FUDForum. Page generated in 0.01958 seconds