// ServicePrimitive.java (C) I. A. Robin, K. J. Turner 08/03/06 package simulator; import java.awt.*; import support.ProtocolEvent; public class ServicePrimitive extends TSDSymbol { public static final int HEAD = 0; public static final int TAIL = 1; private static final int labelPadding = 5; private static int headLength = 8; private static int headWidth = 5; private int width; private boolean lToR; private String label; private int labelPos; public ServicePrimitive( ProtocolEvent event, boolean lToR, int col, int top, int height) { super(event, col, top); this.lToR = lToR; width = arrowWidth; this.height = height; } public void setLabel(String lbl, int pos) { label = lbl; labelPos = pos; } // Draw filled triangle at head of arrow // l = length, w = width of arrowhead private void drawHead( Graphics g, int xHead, int yHead, int xTail, int yTail, int l, int w) { int dx = xHead - xTail; int dy = yHead - yTail; int[] xh = new int[3]; int[] yh = new int[3]; xh[0] = xHead; yh[0] = yHead; float length = (float)(Math.sqrt(dx*dx + dy*dy)); xh[1] = xh[0] - Math.round((l*dx + w*dy)/length); yh[1] = yh[0] + Math.round((w*dx - l*dy)/length); xh[2] = xh[0] - Math.round((l*dx - w*dy)/length); yh[2] = yh[0] - Math.round((w*dx + l*dy)/length); g.fillPolygon(xh, yh, 3); } private void drawLabel( Graphics g, int xHead, int yHead, int xTail, int yTail) { g.setFont(TimeSequenceDiagram.labelFont); FontMetrics fm = g.getFontMetrics(TimeSequenceDiagram.labelFont); int labelWidth = fm.stringWidth(label); int labelX = xTail - labelWidth - labelPadding; int labelY = (labelPos == HEAD)? yHead : yTail; if (lToR && labelPos == HEAD) labelX = xHead + labelPadding; if (!lToR && labelPos == TAIL) labelX = xTail + labelPadding; if (!lToR && labelPos == HEAD) labelX = xHead - labelWidth - labelPadding; g.drawString(label, labelX, labelY - 3); } // Draw arrow across column boundary from sourceCol // in specified direction (lToR = true/false) // with text label at "labelPos" (HEAD / TAIL) public void draw(Graphics g) { int xMid = inset + col*columnWidth; // midpoint of shaft if (!lToR) xMid += columnWidth; // Locations of arrow head and tail int xHead = xMid + width/2; int xTail = xMid - width/2; if (!lToR) { // adjust for rightwards arrow xHead -= width; xTail += width; } int yTail = top; int yHead = yTail + height; drawLabel(g, xHead, yHead, xTail, yTail); // draw label g.drawLine(xTail, yTail, xHead, yHead); // draw shaft of arrow if (lToR) { // prepare head of arrow g.drawLine(xTail, yTail - 1, xHead - 4, yHead - 1); xHead += 2; } else { g.drawLine(xTail, yTail - 1, xHead + 4, yHead - 1); xHead -= 2; } drawHead(g, xHead, yHead, xTail, yTail, headLength, headWidth); } }