1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| public interface Arrow extends Shape {
/** Gets the first point of the arrow.
* @return A <code>Point2D</code> copy of the start point, never <code>null</code>.
*/
public Point2D getStart();
/** Gets the last point of the arrow.
* @return A <code>Point2D</code> copy of the end point, never <code>null</code>.
*/
public Point2D getEnd();
/** Gets the tail object of the arrow.
* <br>The tail usually sits on the first point of the arrow.
* @return An <code>ArrowTail</code> instance ; maybe <code>null</code>
*/
public ArrowTail getTail();
/** Gets the head object of the arrow.
* <br>The head usually sits on the last point of the arrow.
* @return An <code>ArrowHead</code> instance ; maybe <code>null</code>
*/
public ArrowHead getHead();
}
public interface ArrowHead extends Shape {
}
public interface ArrowTail extends Shape {
}
public class DefaultArrow implements Arrow {
private List<Point2D> pointList = new LinkedList();
private ArrowHead head;
private ArrowTail tail;
private GeneralPath delegate = new GeneralPath();
public DefaultArrow() {
pointList.add(new Point());
pointList.add(new Point());
head = new DefaultArrowHead();
tail = new DefaultArrowTail();
recalculateGeometry();
}
////////////////////////
// Shape interface. //
////////////////////////
// We delegate everything to the included GeneralPath object.
/** @inheritDoc.
*/
public Rectangle getBounds() {
return delegate.getBounds();
}
/** @inheritDoc.
*/
public Rectangle2D getBounds2D() {
return delegate.getBounds2D();
}
[...]
////////////////////////
// Arrow interface. //
////////////////////////
/** @inheritDoc.
*/
public Point2D getStart() {
return pointList.get(0).clone();
}
/** @inheritDoc.
*/
public Point2D getEnd() {
return pointList.get(pointList.size()-1).clone();
}
[...]
//////////////////////
// Own methods. //
//////////////////////
public void setArrowHead(ArrowHead head) {
this.head = head;
recalculateGeometry();
}
[...]
private recalculateGeometry() {
delegate.reset();
int pointNumber = pointList.size();
for (int i = 0 ; i < pointNumber ; i++) {
Point2D p = pointList.get(i);
if (i == 0) {
delegate.moveTo(p.getX(), p.getY());
}
else {
delegate.lineTo(p.getX(), p.getY());
}
}
if (tail != null) {
Point2D p = getStart();
/** @todo calculate angle of the first segment. */
AffineTransform t = new AffineTranform();
t.translate(p.getX(), p.getY());
t.rotate(angle);
// We suppose the origin (0, 0) of this shape is where the tail/start point is supposed to be.
Shape s = t.transform(tail);
delegate.append(s);
}
if (head != null) {
Point2D p = getEnd();
/** @todo calculate angle of the last segment. */
AffineTransform t = new AffineTranform();
t.translate(p.getX(), p.getY());
t.rotate(angle);
// We suppose the origin (0, 0) of this shape is where the head/end point is supposed to be.
Shape s = t.transform(head);
delegate.append(s);
}
}
} |
Partager