0001: package hero.client.grapheditor;
0002:
0003: /**
0004: * WFGraph.java
0005: *
0006: *
0007: * Created: Mon Aug 12 11:23:48 2002
0008: *
0009: * @version 1.0
0010: */
0011:
0012: import hero.interfaces.Constants;
0013: import hero.net.ProjectSession.StrutsNodeValue;
0014: import hero.net.ProjectSession.BnIterationLightValue;
0015:
0016: import java.awt.Color;
0017: import java.awt.Dimension;
0018: import java.awt.Font;
0019: import java.awt.Graphics;
0020: import java.awt.Graphics2D;
0021: import java.awt.Point;
0022: import java.awt.Rectangle;
0023: import java.awt.event.ActionEvent;
0024: import java.awt.event.ActionListener;
0025: import java.awt.event.MouseAdapter;
0026: import java.awt.event.MouseEvent;
0027: import java.util.ArrayList;
0028: import java.util.HashMap;
0029: import java.util.Hashtable;
0030: import java.util.Iterator;
0031: import java.util.Map;
0032: import java.util.Observable;
0033: import java.util.Observer;
0034: import java.util.Set;
0035:
0036: import javax.swing.BorderFactory;
0037: import javax.swing.JPopupMenu;
0038: import javax.swing.JScrollPane;
0039: import javax.swing.JOptionPane;
0040:
0041: import com.jgraph.JGraph;
0042: import com.jgraph.event.GraphModelEvent;
0043: import com.jgraph.event.GraphModelListener;
0044: import com.jgraph.event.GraphSelectionEvent;
0045: import com.jgraph.event.GraphSelectionListener;
0046: import com.jgraph.graph.BasicMarqueeHandler;
0047: import com.jgraph.graph.CellView;
0048: import com.jgraph.graph.ConnectionSet;
0049: import com.jgraph.graph.DefaultEdge;
0050: import com.jgraph.graph.DefaultGraphCell;
0051: import com.jgraph.graph.DefaultGraphModel;
0052: import com.jgraph.graph.DefaultPort;
0053: import com.jgraph.graph.EdgeView;
0054: import com.jgraph.graph.GraphConstants;
0055: import com.jgraph.graph.GraphView;
0056: import com.jgraph.graph.Port;
0057: import com.jgraph.graph.PortView;
0058: import com.jgraph.graph.VertexView;
0059: import java.awt.Toolkit;
0060: import java.awt.Image;
0061: import javax.swing.ImageIcon;
0062: import java.net.URL;
0063:
0064: import java.util.Collection;
0065:
0066: import com.jgraph.graph.CellMapper;
0067:
0068: public class WFGraph extends JGraph {
0069:
0070: static java.util.ResourceBundle resource = java.util.ResourceBundle
0071: .getBundle("resources.Traduction")/*#BundleType=List*/;
0072:
0073: private DefaultGraphModel model;
0074: private WFManager manager;
0075: private WFPersistence persistence;
0076: public Hashtable nodes;
0077: private Hashtable edges;
0078: private DefaultGraphCell sourceCell;
0079: private boolean NEWEDGE = false;
0080: private Touch layout2;
0081: private boolean automaticLayout = false;
0082: private LayoutThread expand;
0083: private Image background;
0084:
0085: public final static String imageBase = "images/";
0086: public final static ImageIcon icon = new ImageIcon(Thread
0087: .currentThread().getContextClassLoader().getResource(
0088: imageBase + "icon.png"));
0089:
0090: public WFGraph(final WFManager manager, WFPersistence persist) {
0091: super ();
0092: this .manager = manager;
0093: this .persistence = persist;
0094: nodes = new Hashtable();
0095: edges = new Hashtable();
0096: setMarqueeHandler(new WFMarqueeHandler());
0097: expand = new LayoutThread(this );
0098: layout2 = new Touch(this );
0099: WFListener listener = new WFListener();
0100: getView().addObserver(listener);
0101: addGraphSelectionListener(listener);
0102: getModel().addGraphModelListener(listener);
0103:
0104: setDragEnabled(false);
0105: setDropEnabled(false);
0106:
0107: // set resizable false
0108: setSizeable(false);
0109: setEditable(false);
0110: setConnectable(false);
0111: setDisconnectable(false);
0112: setBendable(false);
0113: setAntiAliased(true);
0114: setCloneable(false);
0115:
0116: //setBackground(new Color(0,153,204));
0117:
0118: setAutomaticLayout(true);
0119: this .addMouseListener(new MouseAdapter() {
0120: public void mousePressed(MouseEvent e) {
0121: if (e.getClickCount() == 1) {
0122: try {
0123: if (!(persistence.soapclient.getProjectName())
0124: .equals(persistence.getProjectName()))
0125: persistence.openProject(persistence
0126: .getProjectName());
0127: } catch (Exception openProject) {
0128: }
0129: }
0130: if (e.getClickCount() == 2) {
0131: DefaultGraphCell myCell = (DefaultGraphCell) getFirstCellForLocation(
0132: e.getX(), e.getY());
0133: if (myCell != null && isVertex(myCell)) {
0134: Map props = myCell.getAttributes();
0135: String subProcess = (String) props
0136: .get("subProcess");
0137: if (subProcess.equals("no")) {
0138: try {
0139: BrowserControl
0140: .displayURL(java.lang.System
0141: .getProperty("bonita.host")
0142: + "/bonita/protected/Action.jsp?projectname="
0143: + persistence
0144: .getProjectName()
0145: + "&nodename="
0146: + (String) myCell
0147: .getUserObject());
0148: } catch (Exception ex) {
0149: }
0150: } else {
0151: try {
0152: Frame frame = new hero.client.grapheditor.Frame(
0153: (String) props.get("name"),
0154: persistence.soapclient, true);
0155: frame.setSize(new Dimension(500, 400));
0156: frame.setVisible(true);
0157: frame.requestFocus();
0158: } catch (Exception exce) {
0159: exce.printStackTrace();
0160: }
0161: ;
0162: }
0163: }
0164: if (myCell != null && isEdge(myCell)) {
0165: try {
0166: Map props = myCell.getAttributes();
0167: manager.setEdgeCondition((String) props
0168: .get("name"));
0169: } catch (Exception ex) {
0170: ex.printStackTrace();
0171: }
0172: }
0173: }
0174: }
0175: });
0176:
0177: // load background
0178: URL backgroundUrl = Thread.currentThread()
0179: .getContextClassLoader().getResource(
0180: imageBase + "background.png");
0181: this .background = Toolkit.getDefaultToolkit().getImage(
0182: backgroundUrl);
0183: setUI(new BonitaGraphUI());
0184:
0185: // background
0186: setBackground(Color.decode("#F7F7F7"));
0187:
0188: }
0189:
0190: public Image getBackgroundImage() {
0191: return background;
0192: }
0193:
0194: public void setAutomaticLayout(boolean value) {
0195: automaticLayout = value;
0196: if (value) {
0197: layout2.start();
0198: layout2.resetDamper();
0199: } else {
0200: layout2.stop();
0201: }
0202: }
0203:
0204: protected VertexView createVertexView(Object v, CellMapper cm) {
0205: if (v instanceof BonitaActivityCell) {
0206: return new BonitaActivityView(v, this , cm);
0207: }
0208: return super .createVertexView(v, cm);
0209: }
0210:
0211: public void addNewNode(String name, int state, int type) {
0212: Map map;
0213:
0214: if (!nodes.containsKey(name)) {
0215: Hashtable attributes = new Hashtable();
0216: //DefaultGraphCell vertex = new DefaultGraphCell(name);
0217: BonitaActivityCell vertex = new BonitaActivityCell(name);
0218: Map vertexAttrib = GraphConstants.createMap();
0219: Map props = new HashMap();
0220: props.put("type", "node");
0221: props.put("state", new Integer(state).toString());
0222: props.put("name", name);
0223: props.put("iterate", "false");
0224:
0225: if (type != Constants.Nd.SUB_PROCESS_NODE) {
0226: GraphConstants.setBounds(vertexAttrib, new Rectangle(
0227: 20, 100, 85, 27));
0228: props.put("subProcess", "no");
0229: } else {
0230: GraphConstants.setBounds(vertexAttrib, new Rectangle(
0231: 20, 100, 85, 33));
0232: props.put("subProcess", "yes");
0233: }
0234: GraphConstants.setBorder(vertexAttrib, BorderFactory
0235: .createRaisedBevelBorder());
0236: GraphConstants.setForeground(vertexAttrib, Color.white);
0237: GraphConstants.setFontStyle(vertexAttrib, Font.BOLD);
0238: GraphConstants.setFontSize(vertexAttrib, (float) 11);
0239: GraphConstants.setOpaque(vertexAttrib, true);
0240:
0241: // GraphConstants.setAutoSize(vertexAttrib, true);
0242:
0243: vertex.setAttributes(props);
0244:
0245: switch (state) {
0246: case Constants.Nd.INITIAL:
0247: GraphConstants.setBackground(vertexAttrib,
0248: (Color.lightGray).darker());
0249: break;
0250: case Constants.Nd.READY:
0251: GraphConstants.setBackground(vertexAttrib,
0252: (Color.yellow).darker());
0253: break;
0254: case Constants.Nd.ANTICIPABLE:
0255: GraphConstants.setBackground(vertexAttrib,
0256: (Color.green).darker());
0257: break;
0258: case Constants.Nd.ANTICIPATING:
0259: GraphConstants.setBackground(vertexAttrib,
0260: (Color.magenta).darker());
0261: break;
0262: case Constants.Nd.EXECUTING:
0263: GraphConstants.setBackground(vertexAttrib, (Color.red)
0264: .darker());
0265: break;
0266: case Constants.Nd.EXECUTED:
0267: GraphConstants.setBackground(vertexAttrib,
0268: (Color.orange).darker());
0269: break;
0270: case Constants.Nd.TERMINATED:
0271: GraphConstants.setBackground(vertexAttrib, (Color.cyan)
0272: .darker());
0273: break;
0274: case Constants.Nd.ANT_SUSPENDED:
0275: GraphConstants.setBackground(vertexAttrib, (Color.blue)
0276: .darker());
0277: break;
0278: case Constants.Nd.EXEC_SUSPENDED:
0279: GraphConstants.setBackground(vertexAttrib, (Color.gray)
0280: .darker());
0281: break;
0282: case Constants.Nd.DEAD:
0283: GraphConstants.setBackground(vertexAttrib, (Color.blue)
0284: .darker());
0285: break;
0286: }
0287:
0288: GraphConstants.setSizeable(vertexAttrib, false);
0289:
0290: attributes.put(vertex, vertexAttrib);
0291: vertex.add(new DefaultPort());
0292: nodes.put(name, vertex);
0293: Object[] cell = new Object[] { vertex };
0294: model.insert(cell, null, null, attributes);
0295: }
0296: }
0297:
0298: public void updateIterationNodes(String from, String to) {
0299: BonitaActivityCell vertexFrom = (BonitaActivityCell) nodes
0300: .get(from);
0301: if (nodes.containsKey(from)) {
0302: Hashtable attributes = new Hashtable();
0303:
0304: Map propsFrom = vertexFrom.getAttributes();
0305: propsFrom.put("iterate", "from");
0306: attributes.put(nodes.get(from), propsFrom);
0307: model.insert(null, null, null, propsFrom);
0308: repaint();
0309: }
0310: BonitaActivityCell vertexTo = (BonitaActivityCell) nodes
0311: .get(to);
0312: if (nodes.containsKey(to)) {
0313: Hashtable attributes = new Hashtable();
0314:
0315: Map propsTo = vertexTo.getAttributes();
0316: propsTo.put("iterate", "to");
0317: attributes.put(nodes.get(to), propsTo);
0318: model.insert(null, null, null, propsTo);
0319: repaint();
0320: }
0321: }
0322:
0323: public void addNewEdge(DefaultGraphCell in, DefaultGraphCell out,
0324: String name) {
0325: Hashtable attributes = new Hashtable();
0326: DefaultEdge e = new DefaultEdge();
0327:
0328: Map edgeAttrib = GraphConstants.createMap();
0329: GraphConstants.setLineBegin(edgeAttrib,
0330: GraphConstants.TECHNICAL);
0331: GraphConstants.setBeginFill(edgeAttrib, true);
0332: GraphConstants.setBeginSize(edgeAttrib, 8);
0333: GraphConstants.setBendable(edgeAttrib, false);
0334: GraphConstants.setDisconnectable(edgeAttrib, false);
0335: attributes.put(e, edgeAttrib);
0336:
0337: Map inn = in.getAttributes();
0338: Map outn = out.getAttributes();
0339:
0340: Map props = new HashMap();
0341: props.put("type", "edge");
0342: props.put("name", name);
0343: props.put("nodein", inn.get("name"));
0344: props.put("nodeout", outn.get("name"));
0345: e.setAttributes(props);
0346:
0347: ConnectionSet cs = new ConnectionSet();
0348: cs.connect(e, (DefaultPort) in.getChildAt(0), false);
0349: cs.connect(e, (DefaultPort) out.getChildAt(0), true);
0350: edges.put(name, e);
0351: Object[] cell = new Object[] { e };
0352: model.insert(cell, cs, null, attributes);
0353: }
0354:
0355: public void openGraph(String projectName) {
0356: try {
0357: newGraph();
0358: nodes.clear();
0359: edges.clear();
0360:
0361: Object[] nd = persistence.getNodes();
0362: for (int i = 0; i < nd.length; i++) {
0363: String nodeName = (String) nd[i];
0364: int state = persistence.getNodeState(nodeName);
0365: int type = persistence.getNodeType(nodeName);
0366: addNewNode(nodeName, state, type);
0367: }
0368:
0369: Object[] ed = persistence.getEdges();
0370: for (int i = 0; i < ed.length; i++) {
0371: String nEdge = (String) ed[i];
0372: String nodeIn = persistence.getEdgeInNode(nEdge);
0373: String nodeOut = persistence.getEdgeOutNode(nEdge);
0374: addNewEdge((DefaultGraphCell) nodes.get(nodeIn),
0375: (DefaultGraphCell) nodes.get(nodeOut), nEdge);
0376: }
0377:
0378: if (automaticLayout)
0379: layout2.resetDamper();
0380:
0381: Collection iterations = persistence.getIterations();
0382: Iterator ite = iterations.iterator();
0383: while (ite.hasNext()) {
0384: BnIterationLightValue i = (BnIterationLightValue) ite
0385: .next();
0386: this .updateIterationNodes(i.getFromNode(), i
0387: .getToNode());
0388: }
0389:
0390: /* Collection properties = persistence.getProperties();
0391: Iterator prop = properties.iterator();
0392: ArrayList itNodes = new ArrayList();
0393: while (prop.hasNext())
0394: {
0395: String pProp = (String)prop.next();
0396: if (pProp.matches("iterate_"+".*"))
0397: {
0398: itNodes = getItNodes(pProp);
0399: this.updateIterationNodes((String)itNodes.get(0),(String)itNodes.get(1));
0400: }
0401: }*/
0402:
0403: } catch (Exception e1) {
0404: e1.printStackTrace();
0405: }
0406:
0407: }
0408:
0409: /**
0410: * Method that returns iteration nodes of this property
0411: */
0412:
0413: private ArrayList getItNodes(String prop) throws Exception {
0414: ArrayList nodes = new ArrayList();
0415: int index = prop.indexOf("iterate_");
0416: prop = prop.substring(index + 8);
0417: index = prop.indexOf("-");
0418: String to = prop.substring(index + 1);
0419: String from = prop.substring(0, index);
0420: nodes.add(from);
0421: nodes.add(to);
0422: return (nodes);
0423: }
0424:
0425: public void newGraph() {
0426: nodes.clear();
0427: edges.clear();
0428: model = new DefaultGraphModel();
0429: setModel(model);
0430: manager.setStatusBar(" ");
0431: };
0432:
0433: public void setLayout1() {
0434: basicLayout(this );
0435: }
0436:
0437: public void setExpand() {
0438: expand.step();
0439: }
0440:
0441: public void setZoom(int value) {
0442: setScale(1);
0443: }
0444:
0445: public void zoomIn() {
0446: setScale(getScale() * 2);
0447: }
0448:
0449: public void zoomOut() {
0450: if (getScale() > 0.01)
0451: setScale(getScale() / 2);
0452:
0453: }
0454:
0455: public void fitWindow(JScrollPane scrollPane) {
0456: Dimension p = getPreferredSize();
0457: Dimension s = scrollPane.getViewport().getBounds().getSize();
0458: if (Math.abs(s.getWidth() - p.getWidth()) < Math.abs(s
0459: .getHeight()
0460: - p.getHeight()))
0461: setScale((double) s.getWidth() / p.getWidth());
0462: else
0463: setScale((double) s.getHeight() / p.getHeight());
0464: }
0465:
0466: public void selectAll() {
0467: addSelectionCells(getRoots());
0468:
0469: }
0470:
0471: public boolean isGroup(Object cell) {
0472: // Map the Cell to its View
0473: CellView view = getView().getMapping(cell, false);
0474: if (view != null)
0475: return !view.isLeaf();
0476: return false;
0477: }
0478:
0479: public boolean isVertex(Object object) {
0480: if (!(object instanceof Port)
0481: && !(object instanceof com.jgraph.graph.Edge))
0482: return !isGroup(object);
0483: return false;
0484: }
0485:
0486: public boolean isEdge(Object object) {
0487: return (object instanceof com.jgraph.graph.Edge);
0488: }
0489:
0490: public Object[] getSelectionNodes() {
0491: Object[] tmp = getSelectionCells();
0492: Object[] all = DefaultGraphModel
0493: .getDescendants(getModel(), tmp).toArray();
0494: Object[] cells = getVertices(all);
0495: Object[] elems = new Object[cells.length];
0496: for (int i = 0; i < cells.length; i++) {
0497: elems[i] = (String) (((DefaultGraphCell) cells[i])
0498: .getUserObject());
0499: }
0500: return elems;
0501: }
0502:
0503: public boolean isSubProcess(String name) {
0504: Object[] tmp = getSelectionCells();
0505: Object[] all = DefaultGraphModel
0506: .getDescendants(getModel(), tmp).toArray();
0507: Object[] cells = getVertices(all);
0508: Object[] elems = new Object[cells.length];
0509: for (int i = 0; i < cells.length; i++) {
0510: if (name.equals((String) ((DefaultGraphCell) cells[i])
0511: .getUserObject())) {
0512: DefaultGraphCell myCell = (DefaultGraphCell) cells[i];
0513: Map props = myCell.getAttributes();
0514: String subProcess = (String) props.get("subProcess");
0515: if (subProcess.equals("yes"))
0516: return (true);
0517: }
0518: }
0519: return false;
0520: }
0521:
0522: public Object[] getVertices(Object[] cells) {
0523: if (cells != null) {
0524: ArrayList result = new ArrayList();
0525: for (int i = 0; i < cells.length; i++)
0526: if (isVertex(cells[i]))
0527: result.add(cells[i]);
0528: return result.toArray();
0529: }
0530: return null;
0531: }
0532:
0533: public Object[] getSelectionEdges() {
0534: Object[] all = getSelectionCells();
0535: Object[] cells = getEdges(all);
0536: Object[] elems = new Object[cells.length];
0537: for (int i = 0; i < cells.length; i++) {
0538: elems[i] = (String) (((DefaultEdge) cells[i])
0539: .getAttributes().get("name"));
0540: }
0541: return elems;
0542:
0543: }
0544:
0545: public Object[] getEdges(Object[] cells) {
0546: if (cells != null) {
0547: ArrayList result = new ArrayList();
0548: for (int i = 0; i < cells.length; i++)
0549: if (isEdge(cells[i]))
0550: result.add(cells[i]);
0551: return result.toArray();
0552: }
0553: return null;
0554: }
0555:
0556: public Object[] getEdge(Object[] cells, String name) {
0557: if (cells != null) {
0558: ArrayList result = new ArrayList();
0559: for (int i = 0; i < cells.length; i++) {
0560: if (isEdge(cells[i])) {
0561: Map a = ((DefaultEdge) cells[i]).getAttributes();
0562: if (name.equals(a.get("name")))
0563: result.add(cells[i]);
0564: }
0565: }
0566: return result.toArray();
0567: }
0568: return null;
0569: }
0570:
0571: public void removeNodeEdges(Object[] cells, String name) {
0572: if (cells != null) {
0573: for (int i = 0; i < cells.length; i++) {
0574: if (isEdge(cells[i])) {
0575: Map a = ((DefaultEdge) cells[i]).getAttributes();
0576: if (name.equals(a.get("nodein"))
0577: || name.equals(a.get("nodeout")))
0578: deleteEdge((String) a.get("name"));
0579: }
0580: }
0581: }
0582: }
0583:
0584: public void deleteNode(String node) throws Exception {
0585: if (nodes.containsKey(node)) {
0586: Object[] all = getRoots();
0587: removeNodeEdges(all, node);
0588: getModel().remove(new Object[] { nodes.get(node) });
0589: nodes.remove(node);
0590: }
0591: }
0592:
0593: public void deleteEdge(String edge) {
0594: if (edges.containsKey(edge)) {
0595: Object[] all = getRoots();
0596: getModel().remove(getEdge(all, edge));
0597: edges.remove(edge);
0598: }
0599: }
0600:
0601: public boolean existEdge(String name) {
0602: return (edges.containsKey(name));
0603: }
0604:
0605: public void restoreEdges() {
0606: try {
0607: Object[] all = getRoots();
0608: Object[] ed = getEdges(all);
0609:
0610: edges.clear();
0611: if (ed != null) {
0612: getModel().remove(ed);
0613: Object[] edv = persistence.getEdges();
0614: for (int i = 0; i < edv.length; i++) {
0615: String nEdge = (String) ed[i];
0616: String nodeIn = persistence.getEdgeInNode(nEdge);
0617: String nodeOut = persistence.getEdgeOutNode(nEdge);
0618: addNewEdge((DefaultGraphCell) nodes.get(nodeIn),
0619: (DefaultGraphCell) nodes.get(nodeOut),
0620: nEdge);
0621: }
0622: }
0623: } catch (Exception e1) {
0624: JOptionPane.showMessageDialog(null, resource
0625: .getString("wfgraph.edgeerror"));
0626: }
0627:
0628: }
0629:
0630: public void restoreEdge(String nEdge, String nodeIn, String nodeOut) {
0631:
0632: addNewEdge((DefaultGraphCell) nodes.get(nodeIn),
0633: (DefaultGraphCell) nodes.get(nodeOut), nEdge);
0634: }
0635:
0636: public void changeNodeState(String node, int state) {
0637: if (nodes.containsKey(node)) {
0638: Hashtable attributes = new Hashtable();
0639: Map vertexAttrib = GraphConstants.createMap();
0640: switch (state) {
0641: case Constants.Nd.INITIAL:
0642: GraphConstants.setBackground(vertexAttrib,
0643: (Color.lightGray).darker());
0644: break;
0645: case Constants.Nd.READY:
0646: GraphConstants.setBackground(vertexAttrib,
0647: (Color.yellow).darker());
0648: break;
0649: case Constants.Nd.ANTICIPABLE:
0650: GraphConstants.setBackground(vertexAttrib,
0651: (Color.green).darker());
0652: break;
0653: case Constants.Nd.ANTICIPATING:
0654: GraphConstants.setBackground(vertexAttrib,
0655: (Color.magenta).darker());
0656: break;
0657: case Constants.Nd.EXECUTING:
0658: GraphConstants.setBackground(vertexAttrib, (Color.red)
0659: .darker());
0660: break;
0661: case Constants.Nd.EXECUTED:
0662: GraphConstants.setBackground(vertexAttrib,
0663: (Color.orange).darker());
0664: break;
0665: case Constants.Nd.TERMINATED:
0666: GraphConstants.setBackground(vertexAttrib, (Color.cyan)
0667: .darker());
0668: break;
0669: case Constants.Nd.ANT_SUSPENDED:
0670: GraphConstants.setBackground(vertexAttrib, (Color.blue)
0671: .darker());
0672: break;
0673: case Constants.Nd.EXEC_SUSPENDED:
0674: GraphConstants.setBackground(vertexAttrib, (Color.gray)
0675: .darker());
0676: break;
0677: case Constants.Nd.DEAD:
0678: GraphConstants.setBackground(vertexAttrib, (Color.blue)
0679: .darker());
0680: break;
0681: }
0682: attributes.put(nodes.get(node), vertexAttrib);
0683: model.insert(null, null, null, attributes);
0684: repaint();
0685: }
0686: }
0687:
0688: public Object getNeighbour(Object edge, Object vertex) {
0689: Object source = getSourceVertex(edge);
0690: if (vertex == source)
0691: return getTargetVertex(edge);
0692: else
0693: return source;
0694: }
0695:
0696: public Object getSourceVertex(Object edge) {
0697: Object sourcePort = graphModel.getSource(edge);
0698: return graphModel.getParent(sourcePort);
0699: }
0700:
0701: public Object getTargetVertex(Object edge) {
0702: Object targetPort = graphModel.getTarget(edge);
0703: return graphModel.getParent(targetPort);
0704: }
0705:
0706: public CellView getSourceView(Object edge) {
0707: Object source = getSourceVertex(edge);
0708: return getView().getMapping(source, false);
0709: }
0710:
0711: public CellView getTargetView(Object edge) {
0712: Object target = getTargetVertex(edge);
0713: return getView().getMapping(target, false);
0714: }
0715:
0716: public Object[] getEdgesBetween(Object vertex1, Object vertex2) {
0717: ArrayList result = new ArrayList();
0718: Set edges = DefaultGraphModel.getEdges(graphModel,
0719: new Object[] { vertex1 });
0720: Iterator it = edges.iterator();
0721: while (it.hasNext()) {
0722: Object edge = it.next();
0723: Object source = getSourceVertex(edge);
0724: Object target = getTargetVertex(edge);
0725: if ((source == vertex1 && target == vertex2)
0726: || (source == vertex2 && target == vertex1))
0727: result.add(edge);
0728: }
0729: return result.toArray();
0730: }
0731:
0732: //Override JGraph getToolTipText method
0733: public String getToolTipText(MouseEvent e) {
0734: try {
0735:
0736: if (e != null) {
0737: //Fetch Cell under Mousepointer
0738: if (!(persistence.soapclient.getProjectName())
0739: .equals(persistence.getProjectName()))
0740: persistence.openProject(persistence
0741: .getProjectName());
0742: Object c = getFirstCellForLocation(e.getX(), e.getY());
0743: if (c != null && isVertex(c)) {
0744: String nodeName = convertValueToString(c);
0745: StrutsNodeValue nl = persistence
0746: .getProjectNode(nodeName);
0747:
0748: String s = "<html><center><b>" + nodeName
0749: + "</b></center>"
0750: + resource.getString("wfgraph.state")
0751: + nl.getState() + "<br>"
0752: + resource.getString("wfgraph.role")
0753: + nl.getRole() + "<br>"
0754: + resource.getString("wfgraph.type")
0755: + nl.getType() + "<br>"
0756: + resource.getString("wfgraph.deadline")
0757: + nl.getDeadline()
0758: // +"<TEXTAREA cols=30 rows=5 name=description style=overflow:hidden;height:auto>"
0759: // + nl.getDescription()
0760: // +"</TEXTAREA>"
0761: + "<br></html>";
0762:
0763: return s;
0764: }
0765: }
0766: } catch (Exception e1) {
0767: JOptionPane.showMessageDialog(null, resource
0768: .getString("wfgraph.errorgettool"));
0769: }
0770:
0771: return null;
0772: }
0773:
0774: public Object[] getAll() {
0775: return getDescendants(getRoots());
0776: }
0777:
0778: public void setAddEdgeState(boolean b) {
0779: NEWEDGE = b;
0780: }
0781:
0782: public void toFront(String nodeName) {
0783: Object[] cells = new Object[] { nodes.get(nodeName) };
0784: // Object[] cells = graph.getSelectionCells();
0785: if (cells != null) {
0786: GraphView gv = getView();
0787: CellView[] views = gv.getMapping(cells);
0788: gv.toFront(views);
0789: }
0790: }
0791:
0792: public void toBack(String nodeName) {
0793: Object[] cells = new Object[] { nodes.get(nodeName) };
0794: // Object[] cells = graph.getSelectionCells();
0795: if (cells != null) {
0796: GraphView gv = getView();
0797: CellView[] views = gv.getMapping(cells);
0798: gv.toBack(views);
0799: }
0800: }
0801:
0802: public static java.awt.image.BufferedImage toImage(JGraph graph) {
0803: Object[] cells = graph.getRoots();
0804:
0805: if (cells.length > 0) {
0806: Rectangle bounds = graph.getCellBounds(cells);
0807: graph.toScreen(bounds);
0808:
0809: // Create a Buffered Image
0810: Dimension d = bounds.getSize();
0811: java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(
0812: d.width + 10, d.height + 10,
0813: java.awt.image.BufferedImage.TYPE_INT_RGB);
0814: Graphics2D graphics = img.createGraphics();
0815: graphics.translate(-bounds.x + 5, -bounds.y + 5);
0816: graph.paint(graphics);
0817:
0818: return img;
0819: }
0820: return null;
0821: }
0822:
0823: private static String addNodeToVRML(Point p, Color c) {
0824: String vrml = "Transform{\n" + "translation "
0825: + p.getX()
0826: + " "
0827: + p.getY()
0828: + " 0\n"
0829: + " children[\n"
0830: + " Shape{\n"
0831: + " appearance Appearance\n"
0832: + " {\n"
0833: + " material Material\n"
0834: + " {"
0835: + " diffuseColor "
0836: + c.getRed()
0837: + " "
0838: + c.getGreen()
0839: + " "
0840: + c.getBlue()
0841: + "\n"
0842: + " shininess 0.01\n"
0843: + " }"
0844: + " }"
0845: + " geometry Box { size 25 25 25 }\n"
0846: + " }\n" + "]\n" + "}\n";
0847: return vrml;
0848: }
0849:
0850: private static String addEdgeToVRML(Point in, Point out) {
0851: String vrml = "Shape{appearance Appearance { \n"
0852: + "material Material {\n" + " emissiveColor 1 1 1 }\n"
0853: + " }\n" + " geometry IndexedLineSet {\n"
0854: + " coord Coordinate {point [ " + in.getX() + " "
0855: + in.getY() + " 0\n" + " " + out.getX() + " "
0856: + out.getY() + " 0\n" + " ] }\n"
0857: + " coordIndex [0 1 ]\n"
0858: + " color Color { color [1 0 0, 0 1 0, 0 0 1]}\n"
0859: + " colorIndex [0 1 ]\n" + " colorPerVertex TRUE\n"
0860: + " }\n" + "}\n";
0861:
0862: return vrml;
0863: }
0864:
0865: public static String vrmlView(JGraph graph) {
0866: CellView[] views = graph.getView().getRoots();
0867: int max = 0;
0868: String vrml = "#VRML V2.0 utf8\n Background{skyColor 0 0 0.5}\n";
0869: for (int i = 0; i < views.length; i++) {
0870: if (views[i] instanceof VertexView) {
0871: Point p = ((VertexView) views[i]).getCenterPoint();
0872: Color c = (Color) ((Map) ((VertexView) views[i])
0873: .getAttributes()).get("backgroundColor");
0874: vrml = vrml + addNodeToVRML(p, c);
0875: } else if (views[i] instanceof EdgeView) {
0876: Point in = ((EdgeView) views[i]).getPoint(0);
0877: Point out = ((EdgeView) views[i])
0878: .getPoint(((EdgeView) views[i]).getPointCount() - 1);
0879: vrml = vrml + addEdgeToVRML(in, out);
0880: }
0881: }
0882: return vrml;
0883:
0884: }
0885:
0886: //Basic Layout
0887: public static void basicLayout(JGraph graph) {
0888: //fetch all cell views
0889: CellView[] views = graph.getView().getRoots();
0890: //list to store the vertices
0891: java.util.List vertices = new ArrayList();
0892: int max = 0;
0893: //loop through all views
0894: for (int i = 0; i < views.length; i++) {
0895: //Add vertex to list
0896: if (views[i] instanceof VertexView) {
0897: vertices.add(views[i]);
0898: //fetch bounds
0899: Rectangle b = views[i].getBounds();
0900: //update Maximum
0901: if (b != null)
0902: max = Math.max(Math.max(b.width, b.height), max);
0903: }
0904: }
0905: //compute radius
0906: int r = (int) Math.max(vertices.size() * max / Math.PI, 100);
0907: //Compute Radial step
0908: double phi = 2 * Math.PI / vertices.size();
0909: //Arrange vertices in a circle
0910: for (int i = 0; i < vertices.size(); i++) {
0911: //Cast the object to a CellView
0912: CellView view = (CellView) vertices.get(i);
0913: //Fetch the Bounds
0914: Rectangle bounds = view.getBounds();
0915: //Update the Location
0916: if (bounds != null)
0917: bounds.setLocation(r + (int) (r * Math.sin(i * phi)), r
0918: + (int) (r * Math.cos(i * phi)));
0919: }
0920: graph.repaint();
0921: }
0922:
0923: public class WFListener implements Observer, GraphModelListener,
0924: GraphSelectionListener {
0925: public WFListener() {
0926: }
0927:
0928: //
0929: // Listeners
0930: //
0931:
0932: public void update(Observable o, Object obj) {
0933: if (automaticLayout)
0934: layout2.resetDamper();
0935: }
0936:
0937: // GraphSelectionListener
0938: public void valueChanged(GraphSelectionEvent e) {
0939: if (!isSelectionEmpty()) {
0940: if (automaticLayout)
0941: layout2.setDamper(0);
0942: //layout2.resetDamper();
0943: }
0944: manager.updateStatus();
0945:
0946: }
0947:
0948: // GraphModelListener
0949: public void graphChanged(GraphModelEvent e) {
0950: if (automaticLayout)
0951: layout2.resetDamper();
0952: }
0953: }
0954:
0955: /**
0956: * MarqueeHandler that can insert cells.
0957: */
0958: public class WFMarqueeHandler extends BasicMarqueeHandler {
0959:
0960: protected Point start, current;
0961:
0962: protected Rectangle bounds;
0963:
0964: protected PortView port, firstPort, lastPort;
0965:
0966: protected DefaultGraphCell sourceCell, destCell;
0967:
0968: protected boolean exception = false;
0969:
0970: /* Return true if this handler should be preferred over other handlers. */
0971: public boolean isForceMarqueeEvent(MouseEvent e) {
0972: if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) == 0)
0973: return NEWEDGE || super .isForceMarqueeEvent(e);
0974: return true;
0975: }
0976:
0977: public void mousePressed(MouseEvent event) {
0978:
0979: if (NEWEDGE) {
0980: start = snap(event.getPoint());
0981: sourceCell = (DefaultGraphCell) getFirstCellForLocation(
0982: event.getX(), event.getY());
0983: event.consume();
0984: } else {
0985: // Popup Menu
0986: if ((event.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0) {
0987:
0988: Object cell = getFirstCellForLocation(event.getX(),
0989: event.getY());
0990: JPopupMenu menu = WFContextMenu.popupMenu(manager
0991: .getFrame(), event.getPoint(),
0992: convertValueToString(cell), manager);
0993:
0994: // Flip along screen
0995: int x = event.getX();
0996: int y = event.getY();
0997:
0998: menu.show(manager.getGraph(), x, y);
0999: }
1000: }
1001:
1002: super .mousePressed(event);
1003: }
1004:
1005: public void mouseDragged(MouseEvent event) {
1006: if (NEWEDGE) {
1007: Graphics g = getGraphics();
1008: Color bg = getBackground();
1009: Color fg = Color.black;
1010: g.setColor(fg);
1011: g.setXORMode(bg);
1012: current = snap(event.getPoint());
1013: overlay(g);
1014: }
1015: super .mouseDragged(event);
1016: }
1017:
1018: public void mouseReleased(MouseEvent event) {
1019: try {
1020: if (NEWEDGE) {
1021: destCell = (DefaultGraphCell) getFirstCellForLocation(
1022: event.getX(), event.getY());
1023: if ((sourceCell != null) && (destCell != null)) {
1024: String name = persistence.addEdge(
1025: (String) sourceCell.getUserObject(),
1026: (String) destCell.getUserObject());
1027: if (name != null) {
1028: addNewEdge(sourceCell, destCell, name);
1029: } else {
1030: exception = true;
1031: }
1032: }
1033: NEWEDGE = false;
1034: sourceCell = null;
1035: destCell = null;
1036: }
1037:
1038: super .mouseReleased(event);
1039: if (exception) {
1040: exception = false;
1041: }
1042:
1043: } catch (Exception e1) {
1044: }
1045:
1046: }
1047:
1048: public void mouseMoved(MouseEvent event) {
1049: super .mouseMoved(event);
1050: }
1051:
1052: public void overlay(Graphics g) {
1053: try {
1054: super .overlay(g);
1055: if (NEWEDGE) {
1056: repaint();
1057: g.drawLine(start.x, start.y, current.x, current.y);
1058: }
1059: } catch (Exception e) {
1060: }
1061: }
1062: }
1063:
1064: public class LayoutThread extends javax.swing.Timer {
1065:
1066: public LayoutThread(final WFGraph graph) {
1067: super (200, new ActionListener() {
1068: public void actionPerformed(ActionEvent e) {
1069: int n = graph.getModel().getRootCount();
1070: Spring s = new Spring(10 * n);
1071: s.compute(graph);
1072: graph.repaint();
1073: }
1074: });
1075: }
1076:
1077: public void step() {
1078: super .fireActionPerformed(null);
1079: }
1080:
1081: }
1082:
1083: }// WFGraph
|