1package com.mxgraph.examples.swing; 2 3import java.awt.Color; 4import java.awt.Point; 5import java.net.URL; 6import java.text.NumberFormat; 7import java.util.Iterator; 8import java.util.List; 9import java.util.ServiceLoader; 10 11import javax.swing.ImageIcon; 12import javax.swing.UIManager; 13 14import org.w3c.dom.Document; 15 16import com.mxgraph.examples.swing.editor.BasicGraphEditor; 17import com.mxgraph.examples.swing.editor.EditorMenuBar; 18import com.mxgraph.examples.swing.editor.EditorPalette; 19import com.mxgraph.examples.swing.editor.EditorPaletteFactory; 20import com.mxgraph.io.mxCodec; 21import com.mxgraph.model.mxCell; 22import com.mxgraph.model.mxGeometry; 23import com.mxgraph.model.mxICell; 24import com.mxgraph.model.mxIGraphModel; 25import com.mxgraph.swing.mxGraphComponent; 26import com.mxgraph.swing.util.mxGraphTransferable; 27import com.mxgraph.util.mxConstants; 28import com.mxgraph.util.mxEvent; 29import com.mxgraph.util.mxEventObject; 30import com.mxgraph.util.mxPoint; 31import com.mxgraph.util.mxResources; 32import com.mxgraph.util.mxUtils; 33import com.mxgraph.util.mxEventSource.mxIEventListener; 34import com.mxgraph.view.mxCellState; 35import com.mxgraph.view.mxGraph; 36 37public class GraphEditor extends BasicGraphEditor 38{ 39 40 /** 41 * 42 */ 43 private static final long serialVersionUID = -4601740824088314699L; 44 45 /** 46 * Holds the shared number formatter. 47 * 48 * @see NumberFormat#getInstance() 49 */ 50 public static final NumberFormat numberFormat = NumberFormat.getInstance(); 51 52 /** 53 * Holds the URL for the icon to be used as a handle for creating new 54 * connections. This is currently unused. 55 */ 56 public static URL url = null; 57 58 //GraphEditor.class.getResource("/com/mxgraph/examples/swing/images/connector.gif"); 59 60 public GraphEditor() 61 { 62 this("mxGraph Editor", new CustomGraphComponent(new CustomGraph())); 63 } 64 65 /** 66 * 67 */ 68 public GraphEditor(String appTitle, mxGraphComponent component) 69 { 70 super(appTitle, component); 71 final mxGraph graph = graphComponent.getGraph(); 72 73 // Creates the shapes palette 74 EditorPalette shapesPalette = insertPalette(mxResources.get("shapes")); 75 EditorPalette imagesPalette = insertPalette(mxResources.get("images")); 76 EditorPalette symbolsPalette = insertPalette(mxResources.get("symbols")); 77 78 ServiceLoader<EditorPaletteFactory> sl = ServiceLoader.load(EditorPaletteFactory.class, this.getClass().getClassLoader()); 79 Iterator<EditorPaletteFactory> epfit = sl.iterator(); 80 while (epfit.hasNext()) { 81 EditorPaletteFactory epf = epfit.next(); 82 EditorPalette customPalette = insertPalette(epf.getTitle()); 83 epf.populate(customPalette); 84 } 85 86 // Sets the edge template to be used for creating new edges if an edge 87 // is clicked in the shape palette 88 shapesPalette.addListener(mxEvent.SELECT, new mxIEventListener() 89 { 90 public void invoke(Object sender, mxEventObject evt) 91 { 92 Object tmp = evt.getProperty("transferable"); 93 94 if (tmp instanceof mxGraphTransferable) 95 { 96 mxGraphTransferable t = (mxGraphTransferable) tmp; 97 Object cell = t.getCells()[0]; 98 99 if (graph.getModel().isEdge(cell)) 100 { 101 ((CustomGraph) graph).setEdgeTemplate(cell); 102 } 103 } 104 } 105 106 }); 107 108 // Adds some template cells for dropping into the graph 109 shapesPalette 110 .addTemplate( 111 "Container", 112 new ImageIcon( 113 GraphEditor.class 114 .getResource("/com/mxgraph/examples/swing/images/swimlane.png")), 115 "swimlane", 280, 280, "Container"); 116 shapesPalette 117 .addTemplate( 118 "Rectangle", 119 new ImageIcon( 120 GraphEditor.class 121 .getResource("/com/mxgraph/examples/swing/images/rectangle.png")), 122 null, 160, 120, ""); 123 shapesPalette 124 .addTemplate( 125 "Rounded Rectangle", 126 new ImageIcon( 127 GraphEditor.class 128 .getResource("/com/mxgraph/examples/swing/images/rounded.png")), 129 "rounded=1", 160, 120, ""); 130 shapesPalette 131 .addTemplate( 132 "Ellipse", 133 new ImageIcon( 134 GraphEditor.class 135 .getResource("/com/mxgraph/examples/swing/images/ellipse.png")), 136 "ellipse", 160, 160, ""); 137 shapesPalette 138 .addTemplate( 139 "Double Ellipse", 140 new ImageIcon( 141 GraphEditor.class 142 .getResource("/com/mxgraph/examples/swing/images/doubleellipse.png")), 143 "ellipse;shape=doubleEllipse", 160, 160, ""); 144 shapesPalette 145 .addTemplate( 146 "Triangle", 147 new ImageIcon( 148 GraphEditor.class 149 .getResource("/com/mxgraph/examples/swing/images/triangle.png")), 150 "triangle", 120, 160, ""); 151 shapesPalette 152 .addTemplate( 153 "Rhombus", 154 new ImageIcon( 155 GraphEditor.class 156 .getResource("/com/mxgraph/examples/swing/images/rhombus.png")), 157 "rhombus", 160, 160, ""); 158 shapesPalette 159 .addTemplate( 160 "Horizontal Line", 161 new ImageIcon( 162 GraphEditor.class 163 .getResource("/com/mxgraph/examples/swing/images/hline.png")), 164 "line", 160, 10, ""); 165 shapesPalette 166 .addTemplate( 167 "Hexagon", 168 new ImageIcon( 169 GraphEditor.class 170 .getResource("/com/mxgraph/examples/swing/images/hexagon.png")), 171 "shape=hexagon", 160, 120, ""); 172 shapesPalette 173 .addTemplate( 174 "Cylinder", 175 new ImageIcon( 176 GraphEditor.class 177 .getResource("/com/mxgraph/examples/swing/images/cylinder.png")), 178 "shape=cylinder", 120, 160, ""); 179 shapesPalette.addTemplate("Actor", new ImageIcon(GraphEditor.class 180 .getResource("/com/mxgraph/examples/swing/images/actor.png")), 181 "shape=actor", 120, 160, ""); 182 shapesPalette.addTemplate("Cloud", new ImageIcon(GraphEditor.class 183 .getResource("/com/mxgraph/examples/swing/images/cloud.png")), 184 "ellipse;shape=cloud", 160, 120, ""); 185 186 shapesPalette 187 .addEdgeTemplate( 188 "Straight", 189 new ImageIcon( 190 GraphEditor.class 191 .getResource("/com/mxgraph/examples/swing/images/straight.png")), 192 "straight", 120, 120, ""); 193 shapesPalette 194 .addEdgeTemplate( 195 "Horizontal Connector", 196 new ImageIcon( 197 GraphEditor.class 198 .getResource("/com/mxgraph/examples/swing/images/connect.png")), 199 null, 100, 100, ""); 200 shapesPalette 201 .addEdgeTemplate( 202 "Vertical Connector", 203 new ImageIcon( 204 GraphEditor.class 205 .getResource("/com/mxgraph/examples/swing/images/vertical.png")), 206 "vertical", 100, 100, ""); 207 shapesPalette 208 .addEdgeTemplate( 209 "Entity Relation", 210 new ImageIcon( 211 GraphEditor.class 212 .getResource("/com/mxgraph/examples/swing/images/entity.png")), 213 "entity", 100, 100, ""); 214 shapesPalette.addEdgeTemplate("Arrow", new ImageIcon(GraphEditor.class 215 .getResource("/com/mxgraph/examples/swing/images/arrow.png")), 216 "arrow", 120, 120, ""); 217 218 imagesPalette.addTemplate("Bell", new ImageIcon(GraphEditor.class 219 .getResource("/com/mxgraph/examples/swing/images/bell.png")), 220 "image;image=/com/mxgraph/examples/swing/images/bell.png", 50, 221 50, "Bell"); 222 imagesPalette.addTemplate("Box", new ImageIcon(GraphEditor.class 223 .getResource("/com/mxgraph/examples/swing/images/box.png")), 224 "image;image=/com/mxgraph/examples/swing/images/box.png", 50, 225 50, "Box"); 226 imagesPalette 227 .addTemplate( 228 "Cube", 229 new ImageIcon( 230 GraphEditor.class 231 .getResource("/com/mxgraph/examples/swing/images/cube_green.png")), 232 "image;image=/com/mxgraph/examples/swing/images/cube_green.png", 233 50, 50, "Cube"); 234 imagesPalette 235 .addTemplate( 236 "User", 237 new ImageIcon( 238 GraphEditor.class 239 .getResource("/com/mxgraph/examples/swing/images/dude3.png")), 240 "roundImage;image=/com/mxgraph/examples/swing/images/dude3.png", 241 50, 50, "User"); 242 imagesPalette 243 .addTemplate( 244 "Earth", 245 new ImageIcon( 246 GraphEditor.class 247 .getResource("/com/mxgraph/examples/swing/images/earth.png")), 248 "roundImage;image=/com/mxgraph/examples/swing/images/earth.png", 249 50, 50, "Earth"); 250 imagesPalette.addTemplate("Gear", new ImageIcon(GraphEditor.class 251 .getResource("/com/mxgraph/examples/swing/images/gear.png")), 252 "roundImage;image=/com/mxgraph/examples/swing/images/gear.png", 253 50, 50, "Gear"); 254 imagesPalette.addTemplate("Home", new ImageIcon(GraphEditor.class 255 .getResource("/com/mxgraph/examples/swing/images/house.png")), 256 "image;image=/com/mxgraph/examples/swing/images/house.png", 50, 257 50, "Home"); 258 imagesPalette 259 .addTemplate( 260 "Package", 261 new ImageIcon( 262 GraphEditor.class 263 .getResource("/com/mxgraph/examples/swing/images/package.png")), 264 "image;image=/com/mxgraph/examples/swing/images/package.png", 265 50, 50, "Package"); 266 imagesPalette 267 .addTemplate( 268 "Printer", 269 new ImageIcon( 270 GraphEditor.class 271 .getResource("/com/mxgraph/examples/swing/images/printer.png")), 272 "image;image=/com/mxgraph/examples/swing/images/printer.png", 273 50, 50, "Printer"); 274 imagesPalette.addTemplate("Server", new ImageIcon(GraphEditor.class 275 .getResource("/com/mxgraph/examples/swing/images/server.png")), 276 "image;image=/com/mxgraph/examples/swing/images/server.png", 277 50, 50, "Server"); 278 imagesPalette 279 .addTemplate( 280 "Workplace", 281 new ImageIcon( 282 GraphEditor.class 283 .getResource("/com/mxgraph/examples/swing/images/workplace.png")), 284 "image;image=/com/mxgraph/examples/swing/images/workplace.png", 285 50, 50, "Workplace"); 286 imagesPalette 287 .addTemplate( 288 "Wrench", 289 new ImageIcon( 290 GraphEditor.class 291 .getResource("/com/mxgraph/examples/swing/images/wrench.png")), 292 "roundImage;image=/com/mxgraph/examples/swing/images/wrench.png", 293 50, 50, "Wrench"); 294 295 symbolsPalette 296 .addTemplate( 297 "Cancel", 298 new ImageIcon( 299 GraphEditor.class 300 .getResource("/com/mxgraph/examples/swing/images/cancel_end.png")), 301 "roundImage;image=/com/mxgraph/examples/swing/images/cancel_end.png", 302 80, 80, "Cancel"); 303 symbolsPalette 304 .addTemplate( 305 "Error", 306 new ImageIcon( 307 GraphEditor.class 308 .getResource("/com/mxgraph/examples/swing/images/error.png")), 309 "roundImage;image=/com/mxgraph/examples/swing/images/error.png", 310 80, 80, "Error"); 311 symbolsPalette 312 .addTemplate( 313 "Event", 314 new ImageIcon( 315 GraphEditor.class 316 .getResource("/com/mxgraph/examples/swing/images/event.png")), 317 "roundImage;image=/com/mxgraph/examples/swing/images/event.png", 318 80, 80, "Event"); 319 symbolsPalette 320 .addTemplate( 321 "Fork", 322 new ImageIcon( 323 GraphEditor.class 324 .getResource("/com/mxgraph/examples/swing/images/fork.png")), 325 "rhombusImage;image=/com/mxgraph/examples/swing/images/fork.png", 326 80, 80, "Fork"); 327 symbolsPalette 328 .addTemplate( 329 "Inclusive", 330 new ImageIcon( 331 GraphEditor.class 332 .getResource("/com/mxgraph/examples/swing/images/inclusive.png")), 333 "rhombusImage;image=/com/mxgraph/examples/swing/images/inclusive.png", 334 80, 80, "Inclusive"); 335 symbolsPalette.addTemplate("Link", new ImageIcon(GraphEditor.class 336 .getResource("/com/mxgraph/examples/swing/images/link.png")), 337 "roundImage;image=/com/mxgraph/examples/swing/images/link.png", 338 80, 80, "Link"); 339 symbolsPalette 340 .addTemplate( 341 "Merge", 342 new ImageIcon( 343 GraphEditor.class 344 .getResource("/com/mxgraph/examples/swing/images/merge.png")), 345 "rhombusImage;image=/com/mxgraph/examples/swing/images/merge.png", 346 80, 80, "Merge"); 347 symbolsPalette 348 .addTemplate( 349 "Message", 350 new ImageIcon( 351 GraphEditor.class 352 .getResource("/com/mxgraph/examples/swing/images/message.png")), 353 "roundImage;image=/com/mxgraph/examples/swing/images/message.png", 354 80, 80, "Message"); 355 symbolsPalette 356 .addTemplate( 357 "Multiple", 358 new ImageIcon( 359 GraphEditor.class 360 .getResource("/com/mxgraph/examples/swing/images/multiple.png")), 361 "roundImage;image=/com/mxgraph/examples/swing/images/multiple.png", 362 80, 80, "Multiple"); 363 symbolsPalette.addTemplate("Rule", new ImageIcon(GraphEditor.class 364 .getResource("/com/mxgraph/examples/swing/images/rule.png")), 365 "roundImage;image=/com/mxgraph/examples/swing/images/rule.png", 366 80, 80, "Rule"); 367 symbolsPalette 368 .addTemplate( 369 "Terminate", 370 new ImageIcon( 371 GraphEditor.class 372 .getResource("/com/mxgraph/examples/swing/images/terminate.png")), 373 "roundImage;image=/com/mxgraph/examples/swing/images/terminate.png", 374 80, 80, "Terminate"); 375 symbolsPalette 376 .addTemplate( 377 "Timer", 378 new ImageIcon( 379 GraphEditor.class 380 .getResource("/com/mxgraph/examples/swing/images/timer.png")), 381 "roundImage;image=/com/mxgraph/examples/swing/images/timer.png", 382 80, 80, "Timer"); 383 } 384 385 /** 386 * 387 */ 388 public static class CustomGraphComponent extends mxGraphComponent 389 { 390 391 /** 392 * 393 */ 394 private static final long serialVersionUID = -6833603133512882012L; 395 396 /** 397 * 398 * @param graph 399 */ 400 public CustomGraphComponent(mxGraph graph) 401 { 402 super(graph); 403 404 // Sets switches typically used in an editor 405 setPageVisible(true); 406 setGridVisible(true); 407 setToolTips(true); 408 getConnectionHandler().setCreateTarget(true); 409 410 // Loads the defalt stylesheet from an external file 411 mxCodec codec = new mxCodec(); 412 Document doc = mxUtils.loadDocument(GraphEditor.class.getResource( 413 "/com/mxgraph/examples/swing/resources/default-style.xml") 414 .toString()); 415 codec.decode(doc.getDocumentElement(), graph.getStylesheet()); 416 417 // Sets the background to white 418 getViewport().setOpaque(false); 419 setBackground(Color.WHITE); 420 } 421 422 /** 423 * Overrides drop behaviour to set the cell style if the target 424 * is not a valid drop target and the cells are of the same 425 * type (eg. both vertices or both edges). 426 */ 427 public Object[] importCells(Object[] cells, double dx, double dy, 428 Object target, Point location) 429 { 430 if (target == null && cells.length == 1 && location != null) 431 { 432 target = getCellAt(location.x, location.y); 433 434 if (target instanceof mxICell && cells[0] instanceof mxICell) 435 { 436 mxICell targetCell = (mxICell) target; 437 mxICell dropCell = (mxICell) cells[0]; 438 439 if (targetCell.isVertex() == dropCell.isVertex() 440 || targetCell.isEdge() == dropCell.isEdge()) 441 { 442 mxIGraphModel model = graph.getModel(); 443 model.setStyle(target, model.getStyle(cells[0])); 444 graph.setSelectionCell(target); 445 446 return null; 447 } 448 } 449 } 450 451 return super.importCells(cells, dx, dy, target, location); 452 } 453 454 } 455 456 /** 457 * A graph that creates new edges from a given template edge. 458 */ 459 public static class CustomGraph extends mxGraph 460 { 461 /** 462 * Holds the edge to be used as a template for inserting new edges. 463 */ 464 protected Object edgeTemplate; 465 466 /** 467 * Custom graph that defines the alternate edge style to be used when 468 * the middle control point of edges is double clicked (flipped). 469 */ 470 public CustomGraph() 471 { 472 setAlternateEdgeStyle("edgeStyle=mxEdgeStyle.ElbowConnector;elbow=vertical"); 473 } 474 475 /** 476 * Sets the edge template to be used to inserting edges. 477 */ 478 public void setEdgeTemplate(Object template) 479 { 480 edgeTemplate = template; 481 } 482 483 /** 484 * Prints out some useful information about the cell in the tooltip. 485 */ 486 public String getToolTipForCell(Object cell) 487 { 488 String tip = "<html>"; 489 mxGeometry geo = getModel().getGeometry(cell); 490 mxCellState state = getView().getState(cell); 491 492 if (getModel().isEdge(cell)) 493 { 494 tip += "points={"; 495 496 if (geo != null) 497 { 498 List<mxPoint> points = geo.getPoints(); 499 500 if (points != null) 501 { 502 Iterator<mxPoint> it = points.iterator(); 503 504 while (it.hasNext()) 505 { 506 mxPoint point = it.next(); 507 tip += "[x=" + numberFormat.format(point.getX()) 508 + ",y=" + numberFormat.format(point.getY()) 509 + "],"; 510 } 511 512 tip = tip.substring(0, tip.length() - 1); 513 } 514 } 515 516 tip += "}<br>"; 517 tip += "absPoints={"; 518 519 if (state != null) 520 { 521 522 for (int i = 0; i < state.getAbsolutePointCount(); i++) 523 { 524 mxPoint point = state.getAbsolutePoint(i); 525 tip += "[x=" + numberFormat.format(point.getX()) 526 + ",y=" + numberFormat.format(point.getY()) 527 + "],"; 528 } 529 530 tip = tip.substring(0, tip.length() - 1); 531 } 532 533 tip += "}"; 534 } 535 else 536 { 537 tip += "geo=["; 538 539 if (geo != null) 540 { 541 tip += "x=" + numberFormat.format(geo.getX()) + ",y=" 542 + numberFormat.format(geo.getY()) + ",width=" 543 + numberFormat.format(geo.getWidth()) + ",height=" 544 + numberFormat.format(geo.getHeight()); 545 } 546 547 tip += "]<br>"; 548 tip += "state=["; 549 550 if (state != null) 551 { 552 tip += "x=" + numberFormat.format(state.getX()) + ",y=" 553 + numberFormat.format(state.getY()) + ",width=" 554 + numberFormat.format(state.getWidth()) 555 + ",height=" 556 + numberFormat.format(state.getHeight()); 557 } 558 559 tip += "]"; 560 } 561 562 mxPoint trans = getView().getTranslate(); 563 564 tip += "<br>scale=" + numberFormat.format(getView().getScale()) 565 + ", translate=[x=" + numberFormat.format(trans.getX()) 566 + ",y=" + numberFormat.format(trans.getY()) + "]"; 567 tip += "</html>"; 568 569 return tip; 570 } 571 572 /** 573 * Overrides the method to use the currently selected edge template for 574 * new edges. 575 * 576 * @param graph 577 * @param parent 578 * @param id 579 * @param value 580 * @param source 581 * @param target 582 * @param style 583 * @return 584 */ 585 public Object createEdge(Object parent, String id, Object value, 586 Object source, Object target, String style) 587 { 588 if (edgeTemplate != null) 589 { 590 mxCell edge = (mxCell) cloneCells(new Object[] { edgeTemplate })[0]; 591 edge.setId(id); 592 593 return edge; 594 } 595 596 return super.createEdge(parent, id, value, source, target, style); 597 } 598 599 } 600 601 /** 602 * 603 * @param args 604 */ 605 public static void main(String[] args) 606 { 607 try 608 { 609 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 610 } 611 catch (Exception e1) 612 { 613 e1.printStackTrace(); 614 } 615 616 mxConstants.SHADOW_COLOR = Color.LIGHT_GRAY; 617 GraphEditor editor = new GraphEditor(); 618 editor.createFrame(new EditorMenuBar(editor)).setVisible(true); 619 } 620} 621