0001: // The UMLet source code is distributed under the terms of the GPL; see license.txt
0002: package com.umlet.element.base;
0003:
0004: import java.awt.Graphics;
0005: import java.awt.Graphics2D;
0006: import java.awt.font.TextLayout;
0007: import java.awt.geom.AffineTransform;
0008: import java.awt.geom.Rectangle2D;
0009: import java.util.ArrayList;
0010: import java.util.Collection;
0011: import java.util.Comparator;
0012: import java.util.HashMap;
0013: import java.util.Iterator;
0014: import java.util.TreeSet;
0015: import java.util.Vector;
0016:
0017: import com.umlet.control.Constants;
0018:
0019: public class ActivityDiagram extends Entity {
0020: static final long serialVersionUID = 0;
0021: private static final int distance = 80;
0022: private static int INITIAL_OFFSET = 10; //offset from border
0023: private int yOffsetforTitle = 0;
0024: private HashMap<String, ElementObject> elementsH = null;
0025: private int[] columnOffset = new int[20];
0026: private Vector<Verb> verbindungen = null;
0027:
0028: public ActivityDiagram() {
0029: }
0030:
0031: private String getHashKey(String elementName) {
0032: String elementIdent = "";
0033:
0034: if (elementName.startsWith("if("))
0035: return elementName.substring(0,
0036: elementName.indexOf("){") + 1);
0037: if (elementName.startsWith("forkH:"))
0038: return elementName.substring(0, elementName.indexOf("{"));
0039: if (elementName.startsWith("join:")) {
0040: if (elementName.length() > "join:".length())
0041: return elementName.substring("join:".length());
0042: else
0043: return elementName;
0044: }
0045: if (elementName.startsWith("fend:")) {
0046: if (elementName.length() > "fend:".length())
0047: return elementName.substring("fend:".length());
0048: else
0049: return elementName;
0050: }
0051:
0052: //### handle syncH, sigSend, sigRec, sigTime
0053: String head = null;
0054: if (elementName.startsWith("syncH:")) {
0055: head = "syncH:";
0056: } else if (elementName.startsWith("sigSend:")) {
0057: head = "sigSend:";
0058: } else if (elementName.startsWith("sigRec:")) {
0059: head = "sigRec:";
0060: } else if (elementName.startsWith("sigTime:")) {
0061: head = "sigTime:";
0062: }
0063: if (head != null) {
0064: String text = elementName.substring(head.length());
0065: if (text.indexOf(':') > 0)
0066: elementIdent = text.substring(text.indexOf(':') + 1);
0067: return (!elementIdent.equals("")) ? (elementIdent) : text;
0068: }
0069:
0070: //### handle actions
0071: if (elementName.indexOf(':') > 0)
0072: elementIdent = elementName.substring(elementName
0073: .indexOf(':') + 1);
0074: return (!elementIdent.equals("")) ? (elementIdent)
0075: : elementName;
0076: }
0077:
0078: public void paint(Graphics g) {
0079: // Some unimportant initialization stuff; setting color, font
0080: // quality, etc. You should not have to change this.
0081: Graphics2D g2 = (Graphics2D) g;
0082: g2.setFont(Constants.getFont());
0083: g2.setColor(_activeColor);
0084: Constants.getFRC(g2);
0085:
0086: //draw the border
0087: g2.drawRect(0, 0, this .getWidth() - 1, this .getHeight() - 1);
0088:
0089: //### init columns ###
0090: for (int i = 0; i < columnOffset.length; i++) {
0091: columnOffset[i] = 125 * (i + 1) - 50;
0092: }
0093: verbindungen = new Vector<Verb>(); //clear verbindungen vector
0094:
0095: Vector<String> lines = Constants.decomposeStrings(this
0096: .getPanelAttributes(), "\n");
0097: if (lines.size() == 0)
0098: return;
0099:
0100: if (lines.elementAt(0).startsWith("title:")) {
0101: String title = lines.elementAt(0).substring(
0102: "title:".length());
0103: if (title != null && title.length() > 0) {
0104: Constants.write(g2, title, 10, Constants.getFontsize()
0105: + Constants.getDistLineToText(), false);
0106: int titlewidth = Constants.getPixelWidth(g2, title);
0107: int ty = 8 + Constants.getFontsize()
0108: + Constants.getDistTextToLine();
0109: g2.drawLine(0, ty, titlewidth + 10, ty);
0110: g2.drawLine(titlewidth + 10, ty, titlewidth + ty + 10,
0111: 0);
0112: lines.remove(0);
0113: //INITIAL_OFFSET+=25;
0114: yOffsetforTitle = 25;
0115: }
0116: }
0117:
0118: //### identify all elements
0119: elementsH = new HashMap<String, ElementObject>(); //[elementText][elementIdent]
0120: for (int i = 0; i < lines.size(); i++) {
0121: String line = lines.elementAt(i);
0122: Vector<String> elementsOfLine = Constants.decomposeStrings(
0123: line, "->", "<-");
0124: for (int el = 0; el < elementsOfLine.size(); el++) {
0125: String element = elementsOfLine.elementAt(el);
0126: if (element.startsWith("if(")) { //DECISION##########################################
0127: // System.err.println("IF: "+element);
0128: //### get decisions ###
0129: Vector<String> ifs = Constants.decomposeStrings(
0130: element, "if(");
0131: for (int j = 0; j < ifs.size(); j++) {
0132: //System.err.println("___if: if("+ifs.get(j));
0133: ElementObject eo = new ElementObject();
0134: String key = getHashKey("if(" + ifs.get(j));
0135: eo.name = key;
0136: eo.ident = key;
0137: elementsH.put(key, eo);
0138: }
0139:
0140: //### get elements referenced by the decisions ###
0141: String s = element;
0142: while (s.indexOf("{") >= 0 && s.indexOf("}") > 0) {
0143: int p2 = s.indexOf("}");
0144: //if(p2>0) {
0145: String elementIdent = s.substring(s
0146: .indexOf("{") + 1, p2);
0147: if (elementIdent.startsWith("if(")
0148: && elementIdent.indexOf("{") >= 0) {
0149: elementIdent = elementIdent
0150: .substring(elementIdent
0151: .indexOf("{") + 1);
0152:
0153: }
0154: s = s.substring(p2 + 1);
0155: String key = getHashKey(elementIdent);
0156: //System.err.println("////:"+elementIdent+ " / "+key);
0157: if (!elementsH.containsKey(key)) {
0158: ElementObject eo = new ElementObject();
0159: eo.name = key;
0160: eo.ident = key;
0161: elementsH.put(key, eo);
0162: }
0163: //}
0164: }
0165: } else if (element.startsWith("forkH:")) { //FORK######################################
0166: // System.err.println("FORK: "+element);
0167: ElementObject eo = new ElementObject();
0168: String key = getHashKey(element);
0169: eo.name = key;
0170: eo.ident = key;
0171: elementsH.put(key, eo);
0172: // System.out.println("FORK:key:"+key);
0173:
0174: //### get elements referenced by the fork ###
0175: String destinations = element.substring(element
0176: .indexOf("{"));
0177: Vector<String> dests = Constants.decomposeStrings(
0178: destinations, "}{");
0179: for (int j = 0; j < dests.size(); j++) {
0180: String d = dests.get(j);
0181: if (d.startsWith("{"))
0182: d = d.substring(1);
0183: else if (d.endsWith("}"))
0184: d = d.substring(0, d.length() - 1);
0185:
0186: key = getHashKey(d);
0187: if (!elementsH.containsKey(key)) {
0188: eo = new ElementObject();
0189: eo.name = key;
0190: eo.ident = key;
0191: elementsH.put(key, eo);
0192: }
0193: }
0194: } else if (element.startsWith("syncH:")) {
0195: ElementObject eo = new ElementObject();
0196: String key = getHashKey(element);
0197: eo.name = element; //key?
0198: eo.ident = key;
0199: elementsH.put(key, eo);
0200: } else if (element.startsWith("join:")) { //JOIN#######################################
0201: ElementObject eo = new ElementObject();
0202: String key = getHashKey(element);
0203: eo.name = element; //key?
0204: eo.ident = key;
0205: elementsH.put(key, eo);
0206: } else { //OTHER/ACTION###############################################################
0207: String key = getHashKey(element);
0208: if (!elementsH.containsKey(key)) {
0209: ElementObject eo = new ElementObject();
0210: eo.name = element;
0211: eo.ident = key;
0212: elementsH.put(key, eo);
0213: }
0214: }
0215: }
0216: }
0217:
0218: //### draw strang
0219: int columnCounter = 0;
0220: for (int i = 0; i < lines.size(); i++) {
0221: String line = lines.elementAt(i);
0222: Vector<String> elementsOfLine = Constants.decomposeStrings(
0223: line, "->");
0224:
0225: int y = INITIAL_OFFSET + yOffsetforTitle;
0226: ElementObject fromEl = null;
0227:
0228: Iterator<String> elementIterator = elementsOfLine
0229: .iterator();
0230: int elPos = 0;
0231: while (elementIterator.hasNext()) {
0232: boolean newColUsed = false;
0233: String elementX = elementIterator.next();
0234: Vector<String> revElements = Constants
0235: .decomposeStrings(elementX, "<-");
0236: System.out.println("revElements: " + revElements);
0237: for (int el = 0; el < revElements.size(); el++) {
0238: String element = revElements.elementAt(el);
0239: String key = getHashKey(element);
0240:
0241: ElementObject actEl = elementsH.get(key);
0242: if (actEl != null) {
0243: if (elPos < elementsOfLine.size() - 1
0244: || el < revElements.size() - 1)
0245: actEl.conn++; //wenn nicht letztes el in zeile, conn erhöhen
0246: if (actEl != null && actEl.x == 0
0247: && actEl.y == 0 && actEl.w == 0
0248: && actEl.h == 0) {
0249: int column = columnCounter;
0250: if (fromEl != null)
0251: column = fromEl.colNr + fromEl.conn - 1;
0252: y = processElement(g2, y, fromEl, actEl,
0253: element, column);
0254: newColUsed = true; //nur wenn neues Element in columne eingefügt
0255: } else {
0256: y = actEl.y + distance;//+actEl.h+
0257: }
0258:
0259: doArrow(fromEl, actEl, 0, 0, null, revElements
0260: .size() > 1);
0261:
0262: fromEl = actEl;
0263: }
0264: if (newColUsed)
0265: columnCounter++;
0266: }
0267: elPos++;
0268: }
0269:
0270: }
0271: // System.err.println(columnCounter);
0272: Collection coll = elementsH.values();
0273: Iterator it = coll.iterator();
0274: while (it.hasNext()) {
0275: ElementObject el = (ElementObject) it.next();
0276: if (el != null)
0277: el.draw(g2);
0278: }
0279:
0280: //get all destination-referenced syncs
0281: Vector<ElementObject> eov = new Vector<ElementObject>();
0282: for (int i = 0; i < verbindungen.size(); i++) {
0283: Verb v = verbindungen.get(i);
0284: if (v != null && v.dst != null && v.dst.type != null
0285: && v.dst.type.equals("syncbar")) {
0286: if (!eov.contains(v.dst))
0287: eov.add(v.dst);
0288: }
0289: }
0290:
0291: //### sort the verbs of the bar, so the arrows are not mixed, but ordered from left to right
0292: //### according to the column their source objects are
0293: TreeSet<Verb> sortedVerbs = new TreeSet<Verb>(
0294: new Comparator<Verb>() { //sorted TreeSet using an anonymous Comparator-class
0295: public int compare(Verb v1, Verb v2) {
0296: if (v1.src.colNr > v2.src.colNr)
0297: return 1;
0298: else if (v1.src.colNr == v2.src.colNr)
0299: return 0;
0300: else
0301: /*if(v1.src.colNr <v2.src.colNr)*/return -1;
0302: }
0303: });
0304:
0305: Vector<Verb> unsortedVerbs = new Vector<Verb>();
0306: for (int i = 0; i < eov.size(); i++) {
0307: for (int vi = 0; vi < verbindungen.size(); vi++) {
0308: Verb v = verbindungen.get(vi);
0309: ElementObject e1 = v.dst;
0310: ElementObject e2 = eov.get(i);
0311: if (e1.equals(e2) && v.src != null) {
0312: sortedVerbs.add(v); //collect verbs
0313: unsortedVerbs.add(v);
0314: }
0315: }
0316: Iterator<Verb> iter = sortedVerbs.iterator();
0317: int j = 0;
0318: while (iter.hasNext()) { //replace unsorted verbs with sorted ones
0319: Verb vs = iter.next();
0320: int idx = verbindungen.indexOf(unsortedVerbs.get(j));
0321: if (idx >= 0)
0322: verbindungen.set(idx, new Verb(vs.src, vs.dst,
0323: vs.name, vs.amount, vs.amountPos,
0324: vs.direction));
0325: j++;
0326: }
0327: }
0328:
0329: //### draw the arrows ###
0330: for (int i = 0; i < verbindungen.size(); i++) {
0331: Verb v = verbindungen.get(i);
0332: drawArrow(g2, v.src, v.dst, v.amount, v.amountPos, v.name,
0333: v.direction);
0334: }
0335: System.err
0336: .println("------------------------------------------------------------------------------------");
0337: }
0338:
0339: //###########################################################################################################
0340: private int processElement(Graphics2D g2, int row,
0341: ElementObject fromEl, ElementObject actEl, String element,
0342: int colNr) {
0343: if (actEl == null || element == null) {
0344: System.err.println("ACTEL NULL");
0345: return 0;
0346: }
0347: if (actEl.x == 0 && actEl.y == 0 && actEl.w == 0
0348: && actEl.h == 0) { //nur zeichnen wenn noch nicht gezeichnet
0349: if (element.equals("start"))
0350: doStart(row, actEl, colNr); //draw start element
0351: else if (element.equals("end"))
0352: doEnd(row, actEl, colNr); //draw end element
0353: else if (element.startsWith("fend:"))
0354: doFlowEnd(row, actEl, colNr); //draw flow-end element
0355: else if (element.startsWith("if("))
0356: processIf(g2, row, element, fromEl, colNr);
0357: else if (element.startsWith("forkH:"))
0358: processFork(g2, row, element, fromEl, colNr);
0359: else if (element.startsWith("syncH:"))
0360: doSyncBar(row, actEl, colNr); //draw bar element
0361: else if (element.startsWith("join:"))
0362: doDecisionJoin(row, actEl, colNr); //draw join element
0363: else if (element.startsWith("sigTime:"))
0364: doTimeSignal(row, element, actEl, colNr); //draw time signal element
0365: else
0366: doAction(g2, row, element, actEl, colNr); //draw action element
0367: }
0368: return actEl.y + distance;
0369: }
0370:
0371: private void moveAllExistingElements() {
0372: Collection coll = elementsH.values();
0373: Iterator it = coll.iterator();
0374: while (it.hasNext()) {
0375: ElementObject el = (ElementObject) it.next();
0376: if (el != null)
0377: el.colNr++;
0378: }
0379: }
0380:
0381: private void processFork(Graphics2D g2, int row, String element,
0382: ElementObject fromEl, int colNr) {
0383: String destinations = element.substring(element.indexOf("{"));
0384: Vector<String> dests = Constants.decomposeStrings(destinations,
0385: "}{");
0386:
0387: String key = getHashKey(element);
0388: ElementObject actEl = elementsH.get(key);
0389: actEl.conn++;
0390:
0391: ArrayList<String> destsX = new ArrayList<String>();
0392: for (int j = 0; j < dests.size(); j++) {
0393: String d = dests.get(j);
0394: if (d.startsWith("{"))
0395: d = d.substring(1);
0396: else if (d.endsWith("}"))
0397: d = d.substring(0, d.length() - 1);
0398: destsX.add(d);
0399: }
0400:
0401: if (destsX.size() == 2) {
0402: doForkBar(row, actEl, colNr + (destsX.size() - 2));
0403: } else if (destsX.size() >= 3) {
0404: if (fromEl != null && fromEl.conn == 1 && actEl != null
0405: && actEl.colNr == 0)
0406: moveAllExistingElements();
0407: fromEl = actEl;
0408: doForkBar(row, actEl, colNr + (destsX.size() - 2));
0409: } else {
0410: //forks are not centered but placed n-1
0411: }
0412:
0413: actEl.conn = destsX.size();
0414: fromEl = actEl;
0415: row = actEl.y + distance;
0416:
0417: for (int i = 0; i < destsX.size(); i++) {
0418: String elementIdent = destsX.get(i);
0419: key = getHashKey(elementIdent);
0420: actEl = elementsH.get(key);
0421: processElement(g2, row, fromEl, actEl, elementIdent, colNr
0422: + i);
0423: doArrow(fromEl, actEl, destsX.size() + 1, i + 1, null,
0424: false);
0425: }
0426: }
0427:
0428: private void processIf(Graphics2D g2, int row, String element,
0429: ElementObject fromEl, int colNr) {
0430: Vector<String> ifs = Constants.decomposeStrings(element, "if(");
0431: for (int j = 0; j < ifs.size(); j++) {
0432: String key = getHashKey("if(" + ifs.get(j));
0433: ElementObject actEl = elementsH.get(key);
0434: actEl.conn++;
0435:
0436: //### get conditions from decision-elements
0437: ArrayList<String> conditions = new ArrayList<String>();
0438: char[] cArr = element.toCharArray();
0439: int startPos = 0, endPos = 0;
0440: for (int ci = 0; ci < cArr.length; ci++) {
0441: if (cArr[ci] == '(')
0442: startPos = ci;
0443: if (cArr[ci] == ')')
0444: endPos = ci;
0445: if (startPos != 0 && endPos != 0) {
0446: conditions.add("["
0447: + element.substring(startPos + 1, endPos)
0448: + "]");
0449: startPos = 0;
0450: endPos = 0;
0451: }
0452: }
0453:
0454: //### get referenced elements
0455: String s = element;
0456: ArrayList<String> ifelements = new ArrayList<String>();
0457: while (s.indexOf("{") >= 0 && s.indexOf("}") > 0) {
0458: int p2 = 0;
0459: boolean nest = false;
0460: if (s.substring(s.indexOf("{") + 1).startsWith("if(")) {
0461: nest = true;
0462: p2 = s.indexOf("}}");
0463: }
0464: if (p2 <= 0)
0465: p2 = s.indexOf("}");
0466: if (p2 > 0) {
0467: String elementIdent = s.substring(
0468: s.indexOf("{") + 1, p2 + (nest ? 1 : 0));
0469: s = s.substring(p2 + 1);
0470: ifelements.add(elementIdent);
0471: }
0472: }
0473:
0474: if (ifelements.size() == 2) {
0475: doDecisionJoin(row, actEl, colNr);
0476: } else if (ifelements.size() == 3) {
0477: if (fromEl != null && fromEl.conn == 1 && actEl != null
0478: && actEl.colNr == 0)
0479: moveAllExistingElements();
0480: fromEl = actEl;
0481: doDecisionJoin(row, actEl, colNr + 1);
0482: } else {
0483: //System.err.println("IF FEHLERHAFT");
0484: //currently there is no support for decisions with more than 3 destinations
0485: }
0486:
0487: actEl.conn = ifelements.size();
0488: fromEl = actEl;
0489: row = actEl.y + distance;//actEl.y+actEl.h+distance;
0490:
0491: for (int i = 0; i < ifelements.size(); i++) {
0492: String elementIdent = ifelements.get(i);
0493: key = getHashKey(elementIdent);
0494: actEl = elementsH.get(key);
0495: /*boolean nest=elementIdent.startsWith("if("); //nested decisions to be done soon
0496: if(nest) {
0497: actEl.colNr++;
0498: ElementObject ifEl = new ElementObject();
0499: ifEl=actEl;
0500: processElement(g2,row,fromEl, ifEl,elementIdent, colNr+i);//+(nest?0:0));
0501: }
0502: else*/processElement(g2, row, fromEl, actEl,
0503: elementIdent, colNr + i);//+(nest?1:0));
0504: if (i < conditions.size())
0505: doArrow(fromEl, actEl, ifelements.size() + 1,
0506: i + 1, conditions.get(i), false);
0507: }
0508: }
0509: }
0510:
0511: //#### drawings ##########################
0512: //#### drawings ##########################
0513: //#### drawings ##########################
0514:
0515: private void doSyncBar(int row, ElementObject el, int colNr) {
0516: el.type = "syncbar";
0517: el.w = 80;
0518: el.h = 5;
0519: el.x = columnOffset[colNr] - el.w / 2;
0520: el.y = row;
0521: el.colNr = colNr;
0522: }
0523:
0524: private void doForkBar(int row, ElementObject el, int colNr) {
0525: el.type = "forkbar";
0526: el.w = 80;
0527: el.h = 5;
0528: el.x = columnOffset[colNr] - el.w / 2;
0529: el.y = row;
0530: el.colNr = colNr;
0531: }
0532:
0533: private void doDecisionJoin(int row, ElementObject el, int colNr) {
0534: el.type = "decisionjoin";
0535: el.w = 30;
0536: el.h = el.w;
0537: el.x = columnOffset[colNr] - el.w / 2;
0538: el.y = row;
0539: el.colNr = colNr;
0540: }
0541:
0542: private void doStart(int row, ElementObject el, int colNr) {
0543: el.type = "start";
0544: el.w = 20;
0545: el.h = el.w;
0546: el.x = columnOffset[colNr] - el.w / 2;
0547: el.y = row;
0548: el.colNr = colNr;
0549: }
0550:
0551: private void doEnd(int row, ElementObject el, int colNr) {
0552: el.type = "end";
0553: el.w = 20;
0554: el.h = el.w;
0555: el.x = columnOffset[colNr] - el.w / 2;
0556: el.y = row;
0557: el.colNr = colNr;
0558: }
0559:
0560: private void doFlowEnd(int row, ElementObject el, int colNr) {
0561: el.type = "flowend";
0562: el.w = 20;
0563: el.h = el.w;
0564: el.x = columnOffset[colNr] - el.w / 2;
0565: el.y = row;
0566: el.colNr = colNr;
0567: }
0568:
0569: private void doTimeSignal(int row, String element,
0570: ElementObject el, int colNr) {
0571: el.type = "sigTime";
0572: el.x = columnOffset[colNr];
0573: el.y = row;
0574: el.w = 0;
0575: el.h = 30;
0576: el.colNr = colNr;
0577: int d1 = element.indexOf(":") + 1;
0578: int d2 = element.indexOf(":", d1);
0579: if (d2 > 0) { //two ':'?
0580: el.text = element.substring(d1, d2);
0581: }
0582: el.text = element.substring("sigTime:".length());
0583: }
0584:
0585: private void doAction(Graphics2D g2, int row, String element,
0586: ElementObject el, int colNr) {
0587: String textLine = element;
0588: if (element.startsWith("sigSend:")) {
0589: el.type = "sigSend";
0590: textLine = textLine.substring("sigSend:".length());
0591: } else if (element.startsWith("sigRec:")) {
0592: textLine = textLine.substring("sigRec:".length());
0593: el.type = "sigRec";
0594: } else
0595: el.type = "action";
0596: int textWidth = 100;
0597: Vector<String> lines = Constants.decomposeStrings(textLine,
0598: "\\");
0599: textWidth = new ElementObject()
0600: .getActionTextWidth(g2, textLine);
0601: el.x = columnOffset[colNr] - textWidth / 2 - 3;
0602: el.y = row;
0603:
0604: //if the action got more than 2 lines of text, resize and move the rectangle by half a line height
0605: int rectHeight = 40; //initial rectheight
0606: int slh = (Constants.getFontsize() + Constants
0607: .getDistTextToText())
0608: * lines.size() + 2 * Constants.getDistTextToLine();
0609: if (slh > rectHeight) { //correct rechHeight and y-Pos
0610: rectHeight = slh;
0611: el.y -= (slh - 40) / 2;
0612: }
0613:
0614: //### draw text line(s)
0615: int stringY = el.y + Constants.getFontsize()
0616: + Constants.getDistTextToLine(); //initial ypos of text
0617: if (lines.size() == 1)
0618: stringY += (Constants.getFontsize() + Constants
0619: .getDistTextToText()) / 2; //vertical offset, if text has just one line (center)
0620: for (int i = 0; i < lines.size(); i++) {
0621: int d = Constants.getFontsize()
0622: + Constants.getDistTextToText();
0623: stringY += d;
0624: }
0625:
0626: el.w = textWidth + 2 * Constants.getDistTextToLine();
0627: el.h = rectHeight;
0628: el.colNr = colNr;
0629: el.text = textLine;
0630: }
0631:
0632: private void doArrow(ElementObject src, ElementObject dst,
0633: int amount, int amountPos, String name, boolean direction) {
0634: if (src == null || dst == null)
0635: return; //skip
0636: Verb v = new Verb(src, dst, name, amount, amountPos, direction);
0637: verbindungen.add(v);
0638: if (dst.type != null && dst.type.equals("syncbar")
0639: && src != null) {
0640: dst.in_amount++;
0641: }
0642: }
0643:
0644: private void drawArrowHead(Graphics2D g2, int x, int y, int winkel) {
0645: AffineTransform at = g2.getTransform();
0646: AffineTransform at2 = (AffineTransform) at.clone();
0647: at2.rotate(winkel * Math.PI / 180, x, y);
0648: g2.setTransform(at2);
0649: g2.setColor(_activeColor);
0650: g2.drawLine(x, y, x - 5, y - 10);
0651: g2.drawLine(x, y, x + 5, y - 10);
0652: g2.setTransform(at);
0653: }
0654:
0655: private void drawArrow(Graphics2D g2, ElementObject src,
0656: ElementObject dst, int amount, int amountPos, String name,
0657: boolean direction) {
0658: if (src != null && dst != null && src.type != null
0659: && dst.type != null) {
0660: if (src == dst)
0661: return; //self calls are not allowed
0662: int quad = 0;
0663: int srcMX = src.x + src.w / 2;
0664: int srcMY = src.y + src.h / 2;
0665: int dstMX = dst.x + dst.w / 2;
0666: int dstMY = dst.y + dst.h / 2;
0667: if ((srcMX <= dstMX + 5 && srcMX >= dstMX - 5)
0668: && (srcMY > dstMY))
0669: quad = 1;
0670: else if ((srcMX <= dstMX + 5 && srcMX >= dstMX - 5)
0671: && (srcMY < dstMY))
0672: quad = 5;
0673: else if ((srcMX < dstMX)
0674: && (srcMY <= dstMY + 5 && srcMY >= dstMY - 5))
0675: quad = 3;
0676: else if ((srcMX > dstMX)
0677: && (srcMY <= dstMY + 5 && srcMY >= dstMY - 5))
0678: quad = 7;
0679:
0680: else if ((srcMX < dstMX) && (srcMY > dstMY))
0681: quad = 2;
0682: else if ((srcMX < dstMX) && (srcMY < dstMY))
0683: quad = 4;
0684: else if ((srcMX > dstMX) && (srcMY < dstMY))
0685: quad = 6;
0686: else if ((srcMX > dstMX) && (srcMY > dstMY))
0687: quad = 8;
0688:
0689: int distance = 1 * 20;
0690: if (quad == 1) {
0691: if (Math.abs(src.y - dst.y) > distance * 2) {
0692: /* +-->
0693: * |
0694: * +--
0695: */
0696: int d = 10;
0697: g2.drawLine(src.x, src.y + src.h / 2, src.x - d,
0698: src.y + src.h / 2);
0699: g2.drawLine(src.x - d, src.y + src.h / 2,
0700: src.x - d, dst.y + dst.h / 2);
0701: g2.drawLine(src.x - d, dst.y + dst.h / 2, dst.x,
0702: dst.y + dst.h / 2);
0703: if (!direction)
0704: drawArrowHead(g2, dst.x, dst.y + dst.h / 2, 270);
0705: else
0706: drawArrowHead(g2, src.x, src.y + src.h / 2, 270);
0707: }
0708: } else if (quad == 2) {
0709: int d = 10;
0710: if (src.type.equals("decisionjoin") || dst.conn == 0) {
0711: /* A
0712: * |
0713: * ---+
0714: */
0715: g2.drawLine(src.x + src.w, src.y + src.h / 2, dst.x
0716: + dst.w / 2, src.y + src.h / 2);
0717: g2.drawLine(dst.x + dst.w / 2, src.y + src.h / 2,
0718: dst.x + dst.w / 2, dst.y + dst.h);
0719: if (!direction)
0720: drawArrowHead(g2, dst.x + dst.w / 2, dst.y
0721: + dst.h, 180);
0722: else
0723: drawArrowHead(g2, src.x + src.w, src.y + src.h
0724: / 2, 90);
0725: if (name != null && !name.equals("[]")) { //print if-condition
0726: //int textWidth=Constants.getPixelWidth(g2,name);
0727: Constants.write(g2, name, src.x + src.w
0728: + Constants.getDistTextToLine(), src.y
0729: + src.h / 2
0730: - Constants.getDistTextToLine() - 1,
0731: false);
0732: }
0733: } else {
0734: /* +-->
0735: * |
0736: * --+
0737: */
0738: g2.drawLine(src.x + src.w, src.y + src.h / 2, src.x
0739: + src.w + d, src.y + src.h / 2);
0740: g2.drawLine(src.x + src.w + d, src.y + src.h / 2,
0741: src.x + src.w + d, dst.y + dst.h / 2);
0742: g2.drawLine(src.x + src.w + d, dst.y + dst.h / 2,
0743: dst.x, dst.y + dst.h / 2);
0744: if (!direction)
0745: drawArrowHead(g2, dst.x, dst.y + dst.h / 2, 270);
0746: else
0747: drawArrowHead(g2, src.x + src.w, src.y + src.h
0748: / 2, 90);
0749: }
0750: } else if (quad == 3) {
0751: /*
0752: * --->
0753: */
0754: g2.drawLine(src.x + src.w, src.y + src.h / 2, dst.x,
0755: dst.y + dst.h / 2);
0756: if (!direction)
0757: drawArrowHead(g2, dst.x, dst.y + dst.h / 2, 270);
0758: else
0759: drawArrowHead(g2, src.x + src.w, src.y + src.h / 2,
0760: 90);
0761: if (name != null && !name.equals("[]")) { //print if-condition
0762: //int textWidth=Constants.getPixelWidth(g2,name);
0763: Constants.write(g2, name, src.x + src.w
0764: + Constants.getDistTextToLine(), src.y
0765: + src.h / 2 - Constants.getDistTextToLine()
0766: - 1, false);
0767: }
0768: } else if (quad == 4) {
0769: /* ---+
0770: * |
0771: * +---->
0772: */
0773: //g2.drawLine(src.x+src.w,src.y+src.h/2,src.x+src.w+d1,src.y+src.h/2);
0774: //g2.drawLine(src.x+src.w+d1,src.y+src.h/2,src.x+src.w+d1,dst.y-d1);
0775: //g2.drawLine(src.x+src.w+d1,dst.y-d1,dst.x+dst.w/2,dst.y-d1);
0776: //g2.drawLine(dst.x+dst.w/2,dst.y-d1,dst.x+dst.w/2,dst.y);
0777: if (src.type.equals("forkbar")) {
0778: /* |
0779: * +--+
0780: * v
0781: */
0782: int p = src.w / (amount + 1);
0783: int pos = 0;
0784: pos = src.x + p * (amountPos + 1);
0785: int sd_dist = Math.abs((src.y + src.h) - (dst.y)) / 2;
0786: g2.drawLine(pos, src.y + src.h, pos, src.y + src.h
0787: + sd_dist);
0788: g2.drawLine(pos, src.y + src.h + sd_dist, dst.x
0789: + dst.w / 2, src.y + src.h + sd_dist);
0790: g2.drawLine(dst.x + dst.w / 2, src.y + src.h
0791: + sd_dist, dst.x + dst.w / 2, dst.y);
0792: drawArrowHead(g2, dst.x + dst.w / 2, dst.y, 0);
0793: } else {
0794: if (src.conn == 1) {
0795: if (dst.type.equals("syncbar")
0796: || dst.type.equals("forkbar")
0797: || dst.type.equals("decisionjoin")) {
0798: /* |
0799: * +--+
0800: * |
0801: * v
0802: */
0803: dst.in_amountPos++;
0804: int p = dst.w / (dst.in_amount + 1);
0805: int pos = dst.x + p * (dst.in_amountPos); //vertical position on bar
0806: int mitte = 0;
0807: if (dst.in_amount % 2 == 0)
0808: mitte = dst.in_amount / 2;
0809: else
0810: mitte = (dst.in_amount - 1) / 2 + 1;
0811: int mb = Math.abs(mitte - dst.in_amountPos) * 8; //amount of y-pixels to remove from horizontal part of the arrow
0812: if (dst.type.equals("forkbar")
0813: || dst.type.equals("decisionjoin")) {
0814: pos = dst.x + dst.w / 2;
0815: mb = 0; //if arrow is incoming to a decision or fork, don't modify
0816: }
0817: int sd_dist = Math.abs((src.y + src.h)
0818: - (dst.y))
0819: / 2 + mb; //y-position of the horizontal part of the arrow
0820:
0821: g2.drawLine(src.x + src.w / 2, src.y
0822: + src.h, src.x + src.w / 2, src.y
0823: + src.h + sd_dist);
0824: g2.drawLine(src.x + src.w / 2, src.y
0825: + src.h + sd_dist, pos, src.y
0826: + src.h + sd_dist);
0827: g2.drawLine(pos, src.y + src.h + sd_dist,
0828: pos, dst.y);
0829: if (!direction)
0830: drawArrowHead(g2, pos, dst.y, 0);
0831: else
0832: drawArrowHead(g2, src.x + src.w / 2,
0833: src.y + src.h, 180);
0834: } else {
0835: /* |
0836: * +-->
0837: */
0838: g2.drawLine(src.x + src.w / 2, src.y
0839: + src.h, src.x + src.w / 2, dst.y
0840: + dst.h / 2);
0841: g2.drawLine(src.x + src.w / 2, dst.y
0842: + dst.h / 2, dst.x, dst.y + dst.h
0843: / 2);
0844: if (!direction)
0845: drawArrowHead(g2, dst.x, dst.y + dst.h
0846: / 2, 270);
0847: else
0848: drawArrowHead(g2, src.x + src.w / 2,
0849: src.y + src.h, 180);
0850: }
0851: } else if (src.conn > 1) {
0852: /* --+
0853: * |
0854: * v
0855: */
0856: if (name != null && !name.equals("[]")) { //print if-condition
0857: //int textWidth=Constants.getPixelWidth(g2,name);
0858: Constants
0859: .write(
0860: g2,
0861: name,
0862: src.x
0863: + src.w
0864: + Constants
0865: .getDistTextToLine(),
0866: src.y
0867: + src.h
0868: / 2
0869: - Constants
0870: .getDistTextToLine()
0871: - 1, false);
0872: }
0873: g2.drawLine(src.x + src.w, src.y + src.h / 2,
0874: dst.x + dst.w / 2, src.y + src.h / 2);
0875: g2.drawLine(dst.x + dst.w / 2, src.y + src.h
0876: / 2, dst.x + dst.w / 2, dst.y);
0877: if (!direction)
0878: drawArrowHead(g2, dst.x + dst.w / 2, dst.y,
0879: 0);
0880: else
0881: drawArrowHead(g2, src.x + src.w, src.y
0882: + src.h / 2, 90);
0883: }
0884: }
0885: } else if (quad == 5) {
0886: if (src.type.equals("forkbar") && amount % 2 != 0) {
0887: /* | |
0888: * +--+ oder +--+
0889: * | |
0890: * v v
0891: */
0892: int p = src.w / (amount + 1);
0893: int pos = 0;
0894: pos = src.x + p * (amountPos + 1);
0895: int sd_dist = Math.abs((src.y + src.h) - (dst.y)) / 2;
0896: g2.drawLine(pos, src.y + src.h, pos, src.y + src.h
0897: + sd_dist);
0898: g2.drawLine(pos, src.y + src.h + sd_dist, dst.x
0899: + dst.w / 2, src.y + src.h + sd_dist);
0900: g2.drawLine(dst.x + dst.w / 2, src.y + src.h
0901: + sd_dist, dst.x + dst.w / 2, dst.y);
0902: drawArrowHead(g2, dst.x + dst.w / 2, dst.y, 0);
0903: } else {
0904: if (dst.type.equals("syncbar")) {
0905: /* | |
0906: * +--+ oder +--+
0907: * | |
0908: * v v
0909: */
0910: dst.in_amountPos++;
0911: int p = dst.w / (dst.in_amount + 1);
0912: int pos = dst.x + p * (dst.in_amountPos); //vertical position on bar
0913: int mitte = 0; //center arrow pos
0914: if (dst.in_amount % 2 == 0)
0915: mitte = dst.in_amount / 2;
0916: else
0917: mitte = (dst.in_amount - 1) / 2 + 1;
0918: int mb = Math.abs(mitte - dst.in_amountPos) * 8; //amount of y-pixels to remove from horizontal part of the arrow
0919: int sd_dist = Math.abs((src.y + src.h)
0920: - (dst.y))
0921: / 2 - mb; //y-position of the horizontal part of the arrow
0922: g2.drawLine(src.x + src.w / 2, src.y + src.h,
0923: src.x + src.w / 2, src.y + src.h
0924: + sd_dist);
0925: g2
0926: .drawLine(src.x + src.w / 2, src.y
0927: + src.h + sd_dist, pos, src.y
0928: + src.h + sd_dist);
0929: g2.drawLine(pos, src.y + src.h + sd_dist, pos,
0930: dst.y);
0931: drawArrowHead(g2, pos, dst.y, 0);
0932: } else {
0933: /* |
0934: * v
0935: */
0936: if (amount > 0) {
0937: if (name != null && !name.equals("[]")) { //print if-condition
0938: int textWidth = Constants
0939: .getPixelWidth(g2, name);
0940: Constants
0941: .write(
0942: g2,
0943: name,
0944: src.x
0945: + src.w
0946: / 2
0947: + textWidth
0948: / 2
0949: + Constants
0950: .getDistTextToLine(),
0951: src.y
0952: + src.h
0953: + Constants
0954: .getFontsize()
0955: + Constants
0956: .getDistLineToText(),
0957: true);
0958: }
0959: }
0960: g2.drawLine(src.x + src.w / 2, src.y + src.h,
0961: dst.x + dst.w / 2, dst.y);
0962: if (!direction)
0963: drawArrowHead(g2, dst.x + dst.w / 2, dst.y,
0964: 0);
0965: else
0966: drawArrowHead(g2, src.x + src.w / 2, src.y
0967: + src.h, 180);
0968: }
0969: }
0970: } else if (quad == 6) {
0971: if (amount > 0) {
0972: if (src.type.equals("forkbar")) {
0973: /* |
0974: * +--+
0975: * |
0976: * v
0977: */
0978: int p = src.w / (amount + 1);
0979: int pos = 0;
0980: pos = src.x + p * (amountPos);
0981: int sd_dist = Math.abs((src.y + src.h)
0982: - (dst.y))
0983: / 2 + (amountPos - 1) * 10;
0984: g2.drawLine(pos, src.y + src.h, pos, src.y
0985: + src.h + sd_dist);
0986: g2.drawLine(pos, src.y + src.h + sd_dist, dst.x
0987: + dst.w / 2, src.y + src.h + sd_dist);
0988: g2.drawLine(dst.x + dst.w / 2, src.y + src.h
0989: + sd_dist, dst.x + dst.w / 2, dst.y);
0990: drawArrowHead(g2, dst.x + dst.w / 2, dst.y, 0);
0991: } else {
0992: if (amount > 1 && amountPos == 1) { //erstes if_element
0993: /* +---
0994: * |
0995: * v
0996: */
0997: g2.drawLine(src.x, src.y + src.h / 2, dst.x
0998: + dst.w / 2, src.y + src.h / 2);
0999: g2.drawLine(dst.x + dst.w / 2, src.y
1000: + src.h / 2, dst.x + dst.w / 2,
1001: dst.y);
1002: if (!direction)
1003: drawArrowHead(g2, dst.x + dst.w / 2,
1004: dst.y, 0);
1005: else
1006: drawArrowHead(g2, src.x, src.y + src.h
1007: / 2, 270);
1008: if (name != null && !name.equals("[]")) { //print if-condition
1009: int textWidth = Constants
1010: .getPixelWidth(g2, name);
1011: Constants
1012: .write(
1013: g2,
1014: name,
1015: src.x
1016: - textWidth
1017: - Constants
1018: .getDistTextToLine(),
1019: src.y
1020: + src.h
1021: / 2
1022: - Constants
1023: .getDistTextToLine()
1024: - 1, false);
1025: }
1026: } else {
1027: //this arrow-line shall indicate missing arrow types
1028: //g2.drawLine(src.x+src.w,src.y+src.h,dst.x+dst.w/2,dst.y);
1029: g2.drawLine(src.x + src.w / 2, src.y
1030: + src.h / 2, dst.x + dst.w / 2,
1031: dst.y + dst.h / 2);
1032: //drawArrowHead(g2, dst.x+dst.w/2, dst.y, 0);
1033: }
1034: }
1035: } else {
1036: if (dst.type.equals("syncbar")) {
1037: /* |
1038: * +--+
1039: * |
1040: * v
1041: */
1042: dst.in_amountPos++;
1043: int p = dst.w / (dst.in_amount + 1);
1044: int pos = dst.x + p * (dst.in_amountPos); //vertical position on bar
1045: int mitte = 0; //center arrow pos
1046: if (dst.in_amount % 2 == 0)
1047: mitte = dst.in_amount / 2;
1048: else
1049: mitte = (dst.in_amount - 1) / 2 + 1;
1050: int mb = Math.abs(mitte - dst.in_amountPos) * 8; //amount of y-pixels to remove from horizontal part of the arrow
1051: int sd_dist = Math.abs((src.y + src.h)
1052: - (dst.y))
1053: / 2 + mb; //y-position of the horizontal part of the arrow
1054: g2.drawLine(src.x + src.w / 2, src.y + src.h,
1055: src.x + src.w / 2, src.y + src.h
1056: + sd_dist);
1057: g2
1058: .drawLine(src.x + src.w / 2, src.y
1059: + src.h + sd_dist, pos, src.y
1060: + src.h + sd_dist);
1061: g2.drawLine(pos, src.y + src.h + sd_dist, pos,
1062: dst.y);
1063: if (!direction)
1064: drawArrowHead(g2, pos, dst.y, 0);
1065: else
1066: drawArrowHead(g2, src.x + src.w / 2, src.y
1067: + src.h, 180);
1068: } else {
1069: /* |
1070: * <-+
1071: */
1072: g2.drawLine(src.x + src.w / 2, src.y + src.h,
1073: src.x + src.w / 2, dst.y + dst.h / 2);
1074: g2.drawLine(src.x + src.w / 2, dst.y + dst.h
1075: / 2, dst.x + dst.w, dst.y + dst.h / 2);
1076: if (!direction)
1077: drawArrowHead(g2, dst.x + dst.w, dst.y
1078: + dst.h / 2, 90);
1079: else
1080: drawArrowHead(g2, src.x + src.w / 2, src.y
1081: + src.h, 180);
1082: }
1083: }
1084: } else if (quad == 7) {
1085: /*
1086: * <---
1087: */
1088: g2.drawLine(src.x, src.y + src.h / 2, dst.x + dst.w,
1089: dst.y + dst.h / 2);
1090: drawArrowHead(g2, dst.x + dst.w, dst.y + dst.h / 2, 90);
1091: } else if (quad == 8) {
1092: int d = 10;
1093: /* <--+
1094: * |
1095: * +--
1096: */
1097: g2.drawLine(src.x, src.y + src.h / 2, src.x - d, src.y
1098: + src.h / 2);
1099: g2.drawLine(src.x - d, src.y + src.h / 2, src.x - d,
1100: dst.y + dst.h / 2);
1101: g2.drawLine(src.x - d, dst.y + dst.h / 2,
1102: dst.x + dst.w, dst.y + dst.h / 2);
1103: if (!direction)
1104: drawArrowHead(g2, dst.x + dst.w, dst.y + dst.h / 2,
1105: 90);
1106: else
1107: drawArrowHead(g2, src.x, src.y + src.h / 2, 270);
1108: } else {
1109: System.err.println("QUAD fehlerhaft...");
1110: //should never happen
1111: }
1112: }
1113: }
1114:
1115: class ElementObject {
1116: public String name = "";
1117: public String ident = "";
1118: public int x = 0;
1119: public int y = 0;
1120: public int w = 0;
1121: public int h = 0;
1122: public int conn = 0;
1123: public int colNr = 0;
1124: public String type = null;
1125: public String text = null;
1126: public int in_amount = 0;
1127: public int in_amountPos = 0;
1128:
1129: public void draw(Graphics2D g2) {
1130: if (type == null)
1131: return;
1132: if (type.equals("syncbar") || type.equals("forkbar")) {
1133: x = columnOffset[colNr] - w / 2;
1134: g2.fillRect(x, y, w, h);
1135: } else if (type.equals("decisionjoin")) {
1136: x = columnOffset[colNr] - w / 2;
1137: g2.drawLine(x + w / 2, y, x + w, y + h / 2);
1138: g2.drawLine(x + w / 2, y, x, y + h / 2);
1139: g2.drawLine(x, y + h / 2, x + w / 2, y + h);
1140: g2.drawLine(x + w - 1, y + h / 2, x + w / 2 - 1, y + h);
1141: } else if (type.equals("start")) {
1142: x = columnOffset[colNr] - w / 2;
1143: g2.fillOval(x, y, 20, 20);
1144: } else if (type.equals("end")) {
1145: x = columnOffset[colNr] - w / 2;
1146: g2.drawOval(x, y, 20, 20);
1147: g2.fillOval(x + 4, y + 4, 13, 13);
1148: } else if (type.equals("flowend")) {
1149: x = columnOffset[colNr] - w / 2;
1150: int d = 3;
1151: g2.drawOval(x, y, 20, 20);
1152: g2.drawLine(x + d, y + d, x + w - d, y + h - d);
1153: g2.drawLine(x + w - d, y + d, x + d, y + h - d);
1154: } else if (type.equals("sigTime")) {
1155: g2.drawLine(x - 15, y, x + 15, y + h);
1156: g2.drawLine(x + 15, y, x - 15, y + h);
1157: g2.drawLine(x - 15, y, x + 15, y);
1158: g2.drawLine(x - 15, y + h, x + 15, y + h);
1159:
1160: Vector<String> lines = null;
1161: if (text != null && text.length() > 0)
1162: lines = Constants.decomposeStrings(text, "\\");
1163: int stringY = y + h + Constants.getDistLineToText() * 5;
1164: if (lines != null) {
1165: for (int i = 0; i < lines.size(); i++) {
1166: String line = lines.elementAt(i);
1167: if (line.endsWith(":" + ident))
1168: line = line.substring(0, line.indexOf(":"
1169: + ident)); //truncate identifier string
1170: if (line != null && line.length() > 0)
1171: Constants.write(g2, line, x, stringY, true);
1172: int d = Constants.getFontsize()
1173: + Constants.getDistTextToText();
1174: stringY += d;
1175: }
1176: }
1177:
1178: } else if (type.equals("action") || type.equals("sigSend")
1179: || type.equals("sigRec")) {
1180: int textWidth = 100;
1181:
1182: Vector<String> lines = null;
1183: if (text != null && text.length() > 0)
1184: lines = Constants.decomposeStrings(text, "\\");
1185:
1186: textWidth = getActionTextWidth(g2, text);
1187: x = columnOffset[colNr] - textWidth / 2 - 3;
1188:
1189: //when the action has more than 2 lines of text, resize and move the rectangle by half a line height
1190: int rectHeight = 40; //initial rectheight
1191: if (lines != null) {
1192: int slh = (Constants.getFontsize() + Constants
1193: .getDistTextToText())
1194: * lines.size()
1195: + 2
1196: * Constants.getDistTextToLine();
1197: if (slh > rectHeight) { //correct rechHeight and y-Pos
1198: rectHeight = slh;
1199: y -= (slh - 40) / 2;
1200: }
1201:
1202: //### draw text line(s)
1203: int stringY = y + Constants.getFontsize()
1204: + Constants.getDistTextToLine(); //initial ypos of text
1205:
1206: if (lines.size() == 1)
1207: stringY += (Constants.getFontsize() + Constants
1208: .getDistTextToText()) / 2; //vertical offset, if text has just one line (center)
1209: for (int i = 0; i < lines.size(); i++) {
1210: String line = lines.elementAt(i);
1211: if (line.endsWith(":" + ident))
1212: line = line.substring(0, line.indexOf(":"
1213: + ident)); //truncate identifier string
1214: if (line != null && line.length() > 0)
1215: Constants.write(g2, line,
1216: x + textWidth / 2, stringY, true);
1217: int d = Constants.getFontsize()
1218: + Constants.getDistTextToText();
1219: stringY += d;
1220: }
1221: }
1222:
1223: //rectHeight=(slh>rectHeight)?(slh):rectHeight;
1224: w = textWidth + 2 * Constants.getDistTextToLine();
1225: h = rectHeight;
1226:
1227: if (type.equals("action"))
1228: g2.drawRoundRect(x, y, w, h, 30, 30);
1229: else if (type.equals("sigSend")) {
1230: g2.drawLine(x, y, x + w - Constants.getFontsize(),
1231: y); // ---
1232: g2.drawLine(x, y + h, x + w
1233: - Constants.getFontsize(), y + h); // ---
1234: g2.drawLine(x, y, x, y + h); // |
1235: g2.drawLine(x + w - Constants.getFontsize(), y, x
1236: + w, y + h / 2); // \
1237: g2.drawLine(x + w, y + h / 2, x + w
1238: - Constants.getFontsize(), y + h); // /
1239: } else if (type.equals("sigRec")) {
1240: g2.drawLine(x, y, x + w, y); // ---
1241: g2.drawLine(x, y + h, x + w, y + h); // ---
1242: g2.drawLine(x + w, y, x + w, y + h); // |
1243: g2.drawLine(x, y, x + Constants.getFontsize(), y
1244: + h / 2); // \
1245: g2.drawLine(x + Constants.getFontsize(), y + h / 2,
1246: x, y + h); // /
1247: }
1248: }
1249: }
1250:
1251: public int getActionTextWidth(Graphics2D g2, String text) {
1252: int textWidth = 100;
1253: if (text == null)
1254: return 0;
1255: Vector<String> lines = Constants.decomposeStrings(text,
1256: "\\");
1257:
1258: //### get max text width
1259: for (int i = 0; i < lines.size(); i++) {
1260: String line = lines.elementAt(i);
1261: TextLayout l = new TextLayout(line,
1262: Constants.getFont(), Constants.getFRC(g2));
1263: Rectangle2D r2d = l.getBounds();
1264: textWidth = ((int) r2d.getWidth() > textWidth) ? ((int) r2d
1265: .getWidth())
1266: : (textWidth);
1267: }
1268: return textWidth;
1269: }
1270: }
1271:
1272: class Verb {
1273: ElementObject src, dst;
1274: int amount = 0;
1275: int amountPos = 0;
1276: String name = null;
1277: boolean direction = false;
1278:
1279: public Verb(ElementObject src, ElementObject dst, String name,
1280: int amount, int amountPos, boolean direction) {
1281: this.src = src;
1282: this.dst = dst;
1283: this.name = name;
1284: this.amount = amount;
1285: this.amountPos = amountPos;
1286: this.direction = direction;
1287: }
1288: }
1289:
1290: }
|