📄 sequencediagram.java
字号:
Activation a = (Activation) activationIter.next(); a.drawMessageSend(g, fm, x); } } } /** * An activation frame on a lifeline. */ private class Activation { private Lifeline fOwner; private MOperationCall fOpCall; private int fStart; private int fEnd; private Activation fSrc; private int fNesting; Activation(int start, Lifeline owner, MOperationCall opcall, Activation src) { fStart = start; fOwner = owner; fOpCall = opcall; fSrc = src; } void setEnd(int end) { fEnd = end; fOwner.exitActivation(); } void setNesting(int n) { fNesting = n; } Lifeline owner() { return fOwner; } void drawMessageSend(Graphics2D g, FontMetrics fm, int x) { g.setColor(Color.black); boolean isRecursive = fSrc != null && fSrc.owner() == fOwner; int x1, x2, xd; int y0 = Y_START + fStart * Y_STEP; int x0 = 20; // invoked by other object if (fSrc != null ) x0 += fSrc.owner().column() * X_STEP; if (x0 < x ) { x0 += 5; if (fSrc != null ) x0 += fSrc.fNesting * FRAME_OFFSET; x = x - 5 + fNesting * FRAME_OFFSET; x1 = x0; x2 = x; } else if (x0 > x ) { x0 -= 5; if (fSrc != null ) x0 += fSrc.fNesting * FRAME_OFFSET; x = x + 5 + fNesting * FRAME_OFFSET; x1 = x; x2 = x0; } else { x0 = x0 + 5 + fSrc.fNesting * FRAME_OFFSET; x = x + 5 + fNesting * FRAME_OFFSET; x1 = x0; x2 = x; } // draw message line // recursive edge? if (isRecursive ) { g.drawArc(x2 - 40, y0 - Y_STEP / 3, 80, Y_STEP / 3, -90, 180); xd = +10; } else { g.drawLine(x1, y0, x2, y0); xd = ( x0 <= x ) ? -10 : +10; } // arrow head int[] xp = { x, x + xd, x + xd }; int[] yp = {y0, y0 - 4, y0 + 4 }; g.fillPolygon(xp, yp, xp.length); // draw message name String msgLabel = fOpCall.operation().name(); if (fShowValues ) msgLabel += "(" + StringUtil.fmtSeq(fOpCall.argValues(), ",") + ")"; if (isRecursive ) g.drawString(msgLabel, x1 + 15, y0 - Y_STEP / 3 - 2); else { int labelWidth = fm.stringWidth(msgLabel); g.drawString(msgLabel, x1 + (x2 - x1 - labelWidth) / 2, y0 - 2); } // a return may be missing because the operation may still // be active during animation if (fEnd != 0 ) { // red lines for failing postconditions if (! fOpCall.postconditionsOkOnExit() ) g.setColor(Color.red); y0 = Y_START + fEnd * Y_STEP; String resultLabel = null; if (fShowValues ) { Value result = fOpCall.resultValue(); if (result != null ) resultLabel = result.toString(); } Stroke oldStroke = g.getStroke(); g.setStroke(dashedStroke); if (isRecursive ) { // recursive edge g.drawArc(x2 - 40, y0, 80, Y_STEP / 3, -90, 180); xd = +10; g.setStroke(oldStroke); // arrow head int y = y0 + Y_STEP / 3; g.drawLine(x0, y, x0 + xd, y - 3); g.drawLine(x0, y, x0 + xd, y + 3); // result value text if (resultLabel != null ) g.drawString(resultLabel, x2 + 15, y0 - 2); } else { // dashed line g.drawLine(x1, y0, x2, y0); xd = ( x0 <= x ) ? +10 : -10; g.setStroke(oldStroke); // arrow head g.drawLine(x0, y0, x0 + xd, y0 - 3); g.drawLine(x0, y0, x0 + xd, y0 + 3); // result value text if (resultLabel != null ) { int labelWidth = fm.stringWidth(resultLabel); g.drawString(resultLabel, x1 + (x2 - x1 - labelWidth) / 2, y0 - 2); } } } } void drawFrame(Graphics2D g, int x) { int end = fEnd; if (end == 0 ) // frame still active end = fNumSteps; x += fNesting * FRAME_OFFSET; // nested activation g.setColor(Color.white); g.fillRect(x - 5, Y_START + fStart * Y_STEP, 10, (end - fStart) * Y_STEP); g.setColor(Color.black); g.drawRect(x - 5, Y_START + fStart * Y_STEP, 10, (end - fStart) * Y_STEP); } } void update() { fLifelines = new HashMap(); int column = 1; int eventStep = 1; Stack activationStack = new Stack(); List cmds = fSystem.commands(); Iterator cmdIter = cmds.iterator(); while (cmdIter.hasNext() ) { MCmd cmd = (MCmd) cmdIter.next(); if (cmd instanceof MCmdOpEnter) { MCmdOpEnter openter = (MCmdOpEnter) cmd; MOperationCall opcall = openter.operationCall(); MObject obj = opcall.targetObject(); Lifeline ll = (Lifeline) fLifelines.get(obj); // need new lifeline? if (ll == null ) { ll = new Lifeline(column++, obj); fLifelines.put(obj, ll); } // get source of operation call Activation srcAct = null; if (! activationStack.empty() ) srcAct = (Activation) activationStack.peek(); // add new activation and push on stack Activation a = new Activation(eventStep, ll, opcall, srcAct); ll.enterActivation(a); activationStack.push(a); eventStep++; } else if (cmd instanceof MCmdOpExit) { // finish current activation Activation a = (Activation) activationStack.pop(); a.setEnd(eventStep); eventStep++; } else if (! fCompactDisplay ) eventStep++; } fNumSteps = eventStep + 1; setPreferredSize(new Dimension(20 + fLifelines.size() * X_STEP + X_STEP / 2, Y_START + fNumSteps * Y_STEP + 10)); revalidate(); repaint(); } /** * Prints the diagram. Implementation of Printable interface. */ public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { if (pi >= 1 ) return Printable.NO_SUCH_PAGE; Graphics2D g2d = (Graphics2D) g; g2d.translate(pf.getImageableX(), pf.getImageableY()); g2d.translate(pf.getImageableWidth() / 2, pf.getImageableHeight() / 2); Dimension d = getSize(); double scale = Math.min(pf.getImageableWidth() / d.width, pf.getImageableHeight() / d.height); // fit to page if (scale < 1.0 ) g2d.scale(scale, scale); g2d.translate(-d.width / 2.0, -d.height / 2.0); Font f = Font.getFont("use.gui.print.diagramFont", getFont()); g2d.setFont(f); drawDiagram(g2d); return Printable.PAGE_EXISTS; } void printDiagram(PageFormat pf) { PrinterJob job = PrinterJob.getPrinterJob(); job.setJobName("Sequence diagram"); job.setPrintable(this, pf); if (job.printDialog() ) { // Print the job if the user didn't cancel printing try { job.print(); } catch (Exception ex) { JOptionPane.showMessageDialog(this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -