1 25 47 package org.jgrapht.ext; 48 49 import java.awt.Color ; 50 import java.awt.Font ; 51 import java.awt.geom.*; 52 53 import java.io.*; 54 55 import java.util.ArrayList ; 56 import java.util.Collection ; 57 import java.util.HashMap ; 58 import java.util.HashSet ; 59 import java.util.Iterator ; 60 import java.util.List ; 61 import java.util.Map ; 62 import java.util.Set ; 63 64 import javax.swing.*; 65 66 import org.jgraph.event.*; 67 import org.jgraph.event.GraphModelEvent.*; 68 import org.jgraph.graph.*; 69 70 import org.jgrapht.*; 71 import org.jgrapht.event.*; 72 73 74 103 104 110 public class JGraphModelAdapter<V, E> 111 extends DefaultGraphModel 112 { 113 114 116 private static final long serialVersionUID = 3256722883706302515L; 117 118 120 150 final Set <GraphCell> jCellsBeingAdded = new HashSet <GraphCell>(); 151 final Set <GraphCell> jCellsBeingRemoved = new HashSet <GraphCell>(); 152 final Set <Object > jtElementsBeingAdded = new HashSet <Object >(); 153 final Set <Object > jtElementsBeingRemoved = new HashSet <Object >(); 154 private final CellFactory<V, E> cellFactory; 155 156 159 private final Map <org.jgraph.graph.Edge, E> cellToEdge = 160 new HashMap <org.jgraph.graph.Edge, E>(); 161 162 165 private final Map <GraphCell, V> cellToVertex = new HashMap <GraphCell, V>(); 166 private AttributeMap defaultEdgeAttributes; 167 private AttributeMap defaultVertexAttributes; 168 169 172 private final Map <E, org.jgraph.graph.Edge> edgeToCell = 173 new HashMap <E, org.jgraph.graph.Edge>(); 174 175 178 private final Map <V, GraphCell> vertexToCell = new HashMap <V, GraphCell>(); 179 private final ShieldedGraph jtGraph; 180 181 183 189 public JGraphModelAdapter(Graph<V, E> jGraphTGraph) 190 { 191 this( 192 jGraphTGraph, 193 createDefaultVertexAttributes(), 194 createDefaultEdgeAttributes(jGraphTGraph)); 195 } 196 197 208 public JGraphModelAdapter( 209 Graph<V, E> jGraphTGraph, 210 AttributeMap defaultVertexAttributes, 211 AttributeMap defaultEdgeAttributes) 212 { 213 this( 214 jGraphTGraph, 215 defaultVertexAttributes, 216 defaultEdgeAttributes, 217 new DefaultCellFactory<V, E>()); 218 } 219 220 235 public JGraphModelAdapter( 236 Graph<V, E> jGraphTGraph, 237 AttributeMap defaultVertexAttributes, 238 AttributeMap defaultEdgeAttributes, 239 CellFactory<V, E> cellFactory) 240 { 241 super(); 242 243 if ( 244 (jGraphTGraph == null) 245 || (defaultVertexAttributes == null) 246 || (defaultEdgeAttributes == null) 247 || (cellFactory == null)) { 248 throw new IllegalArgumentException ("null is NOT permitted"); 249 } 250 251 jtGraph = new ShieldedGraph(jGraphTGraph); 252 setDefaultVertexAttributes(defaultVertexAttributes); 253 setDefaultEdgeAttributes(defaultEdgeAttributes); 254 this.cellFactory = cellFactory; 255 256 if (jGraphTGraph instanceof ListenableGraph) { 257 ListenableGraph<V, E> g = (ListenableGraph<V, E>) jGraphTGraph; 258 g.addGraphListener(new JGraphTListener()); 259 } 260 261 for (Iterator <V> i = jGraphTGraph.vertexSet().iterator(); 262 i.hasNext();) { 263 handleJGraphTAddedVertex(i.next()); 264 } 265 266 for (Iterator <E> i = jGraphTGraph.edgeSet().iterator(); i.hasNext();) { 267 handleJGraphTAddedEdge(i.next()); 268 } 269 270 this.addGraphModelListener(new JGraphListener()); 271 } 272 273 275 284 public static <V, E> AttributeMap createDefaultEdgeAttributes( 285 Graph<V, E> jGraphTGraph) 286 { 287 AttributeMap map = new AttributeMap(); 288 289 if (jGraphTGraph instanceof DirectedGraph) { 290 GraphConstants.setLineEnd(map, GraphConstants.ARROW_TECHNICAL); 291 GraphConstants.setEndFill(map, true); 292 GraphConstants.setEndSize(map, 10); 293 } 294 295 GraphConstants.setForeground(map, Color.decode("#25507C")); 296 GraphConstants.setFont( 297 map, 298 GraphConstants.DEFAULTFONT.deriveFont(Font.BOLD, 12)); 299 GraphConstants.setLineColor(map, Color.decode("#7AA1E6")); 300 301 return map; 302 } 303 304 310 public static AttributeMap createDefaultVertexAttributes() 311 { 312 AttributeMap map = new AttributeMap(); 313 Color c = Color.decode("#FF9900"); 314 315 GraphConstants.setBounds(map, new Rectangle2D.Double(50, 50, 90, 30)); 316 GraphConstants.setBorder(map, BorderFactory.createRaisedBevelBorder()); 317 GraphConstants.setBackground(map, c); 318 GraphConstants.setForeground(map, Color.white); 319 GraphConstants.setFont( 320 map, 321 GraphConstants.DEFAULTFONT.deriveFont(Font.BOLD, 12)); 322 GraphConstants.setOpaque(map, true); 323 324 return map; 325 } 326 327 332 public CellFactory<V, E> getCellFactory() 333 { 334 return cellFactory; 335 } 336 337 342 public void setDefaultEdgeAttributes(AttributeMap defaultEdgeAttributes) 343 { 344 this.defaultEdgeAttributes = defaultEdgeAttributes; 345 } 346 347 352 public AttributeMap getDefaultEdgeAttributes() 353 { 354 return defaultEdgeAttributes; 355 } 356 357 362 public void setDefaultVertexAttributes( 363 AttributeMap defaultVertexAttributes) 364 { 365 this.defaultVertexAttributes = defaultVertexAttributes; 366 } 367 368 375 public AttributeMap getDefaultVertexAttributes() 376 { 377 return defaultVertexAttributes; 378 } 379 380 389 public DefaultEdge getEdgeCell(E jGraphTEdge) 390 { 391 return (DefaultEdge) edgeToCell.get(jGraphTEdge); 392 } 393 394 403 public DefaultGraphCell getVertexCell(Object jGraphTVertex) 404 { 405 return (DefaultGraphCell) vertexToCell.get(jGraphTVertex); 406 } 407 408 417 public DefaultPort getVertexPort(Object jGraphTVertex) 418 { 419 DefaultGraphCell vertexCell = getVertexCell(jGraphTVertex); 420 421 if (vertexCell == null) { 422 return null; 423 } else { 424 return (DefaultPort) vertexCell.getChildAt(0); 425 } 426 } 427 428 439 void handleJGraphChangedEdge(org.jgraph.graph.Edge jEdge) 440 { 441 if (isDangling(jEdge)) { 442 if (cellToEdge.containsKey(jEdge)) { 443 handleJGraphRemovedEdge(jEdge); 448 } else { 449 } 451 } else { 452 if (cellToEdge.containsKey(jEdge)) { 454 E jtEdge = cellToEdge.get(jEdge); 457 458 Object jSource = getSourceVertex(this, jEdge); 459 Object jTarget = getTargetVertex(this, jEdge); 460 461 Object jtSource = cellToVertex.get(jSource); 462 Object jtTarget = cellToVertex.get(jTarget); 463 464 if ( 465 (jtGraph.getEdgeSource(jtEdge) == jtSource) 466 && (jtGraph.getEdgeTarget(jtEdge) == jtTarget)) { 467 } else { 469 handleJGraphRemovedEdge(jEdge); 475 handleJGraphInsertedEdge(jEdge); 476 } 477 } else { 478 handleJGraphInsertedEdge(jEdge); 480 } 481 } 482 } 483 484 494 void handleJGraphInsertedEdge(org.jgraph.graph.Edge jEdge) 495 { 496 if (isDangling(jEdge)) { 497 } else { 500 Object jSource = getSourceVertex(this, jEdge); 502 Object jTarget = getTargetVertex(this, jEdge); 503 504 V jtSource = cellToVertex.get(jSource); 505 V jtTarget = cellToVertex.get(jTarget); 506 507 E jtEdge = jtGraph.addEdge(jtSource, jtTarget); 508 509 if (jtEdge != null) { 510 cellToEdge.put(jEdge, jtEdge); 511 edgeToCell.put(jtEdge, jEdge); 512 } else { 513 internalRemoveCell(jEdge); 517 System.err.println( 518 "Warning: an edge was deleted because the underlying " 519 + "JGraphT graph refused to create it. " 520 + "This situation can happen when a constraint of the " 521 + "underlying graph is violated, e.g., an attempt to add " 522 + "a parallel edge or a self-loop to a graph that forbids " 523 + "them. To avoid this message, make sure to use a " 524 + "suitable underlying JGraphT graph."); 525 } 526 } 527 } 528 529 542 @SuppressWarnings ("unchecked") 543 void handleJGraphInsertedVertex(GraphCell jVertex) 544 { 545 V jtVertex; 546 547 if (jVertex instanceof DefaultGraphCell) { 548 jtVertex = (V) ((DefaultGraphCell) jVertex).getUserObject(); 550 } else { 551 jtVertex = (V) jVertex.toString(); 553 } 554 555 if (vertexToCell.containsKey(jtVertex)) { 556 System.err.println( 560 "Warning: detected two JGraph vertices with " 561 + "the same JGraphT vertex as user object. It is an " 562 + "indication for a faulty situation that should NOT happen." 563 + "Removing vertex: " + jVertex); 564 internalRemoveCell(jVertex); 565 } else { 566 jtGraph.addVertex(jtVertex); 567 568 cellToVertex.put(jVertex, jtVertex); 569 vertexToCell.put(jtVertex, jVertex); 570 } 571 } 572 573 583 void handleJGraphRemovedEdge(org.jgraph.graph.Edge jEdge) 584 { 585 if (cellToEdge.containsKey(jEdge)) { 586 E jtEdge = cellToEdge.get(jEdge); 587 588 jtGraph.removeEdge(jtEdge); 589 590 cellToEdge.remove(jEdge); 591 edgeToCell.remove(jtEdge); 592 } 593 } 594 595 612 void handleJGraphRemovedVertex(GraphCell jVertex) 613 { 614 if (cellToVertex.containsKey(jVertex)) { 615 V jtVertex = cellToVertex.get(jVertex); 616 Set <E> jtIncidentEdges = jtGraph.edgesOf(jtVertex); 617 618 if (!jtIncidentEdges.isEmpty()) { 619 jtGraph.removeAllEdges(new ArrayList <E>(jtIncidentEdges)); 625 } 626 627 jtGraph.removeVertex(jtVertex); 628 629 cellToVertex.remove(jVertex); 630 vertexToCell.remove(jtVertex); 631 } 632 } 633 634 640 void handleJGraphTAddedEdge(E jtEdge) 641 { 642 DefaultEdge edgeCell = cellFactory.createEdgeCell(jtEdge); 643 edgeToCell.put(jtEdge, edgeCell); 644 cellToEdge.put(edgeCell, jtEdge); 645 646 ConnectionSet cs = new ConnectionSet(); 647 cs.connect( 648 edgeCell, 649 getVertexPort(jtGraph.getEdgeSource(jtEdge)), 650 getVertexPort(jtGraph.getEdgeTarget(jtEdge))); 651 652 internalInsertCell(edgeCell, createEdgeAttributeMap(edgeCell), cs); 653 } 654 655 661 void handleJGraphTAddedVertex(V jtVertex) 662 { 663 DefaultGraphCell vertexCell = cellFactory.createVertexCell(jtVertex); 664 vertexCell.add(new DefaultPort()); 665 666 vertexToCell.put(jtVertex, vertexCell); 667 cellToVertex.put(vertexCell, jtVertex); 668 669 internalInsertCell( 670 vertexCell, 671 createVertexAttributeMap(vertexCell), 672 null); 673 } 674 675 683 void handleJGraphTRemoveVertex(Object jtVertex) 684 { 685 DefaultGraphCell vertexCell = 686 (DefaultGraphCell) vertexToCell.remove(jtVertex); 687 cellToVertex.remove(vertexCell); 688 689 internalRemoveCell(vertexCell); 690 691 if (vertexCell.getChildCount() > 0) { 693 remove(new Object [] { vertexCell.getChildAt(0) }); 694 } 695 } 696 697 705 void handleJGraphTRemovedEdge(E jtEdge) 706 { 707 DefaultEdge edgeCell = (DefaultEdge) edgeToCell.remove(jtEdge); 708 cellToEdge.remove(edgeCell); 709 internalRemoveCell(edgeCell); 710 } 711 712 721 private boolean isDangling(org.jgraph.graph.Edge jEdge) 722 { 723 Object jSource = getSourceVertex(this, jEdge); 724 Object jTarget = getTargetVertex(this, jEdge); 725 726 return 727 !cellToVertex.containsKey(jSource) 728 || !cellToVertex.containsKey(jTarget); 729 } 730 731 @SuppressWarnings ("unchecked") 732 private AttributeMap createEdgeAttributeMap(DefaultEdge edgeCell) 733 { 734 AttributeMap attrs = new AttributeMap(); 735 736 attrs.put(edgeCell, getDefaultEdgeAttributes().clone()); 738 739 return attrs; 740 } 741 742 @SuppressWarnings ("unchecked") 743 private AttributeMap createVertexAttributeMap(GraphCell vertexCell) 744 { 745 AttributeMap attrs = new AttributeMap(); 746 747 attrs.put(vertexCell, getDefaultVertexAttributes().clone()); 749 750 return attrs; 751 } 752 753 760 private void internalInsertCell( 762 GraphCell cell, 763 AttributeMap attrs, 764 ConnectionSet cs) 765 { 766 jCellsBeingAdded.add(cell); 767 insert(new Object [] { cell }, attrs, cs, null, null); 768 jCellsBeingAdded.remove(cell); 769 } 770 771 776 private void internalRemoveCell(GraphCell cell) 777 { 778 jCellsBeingRemoved.add(cell); 779 remove(new Object [] { cell }); 780 jCellsBeingRemoved.remove(cell); 781 } 782 783 785 791 public static interface CellFactory<VV, EE> 792 { 793 800 public DefaultEdge createEdgeCell(EE jGraphTEdge); 801 802 809 public DefaultGraphCell createVertexCell(VV jGraphTVertex); 810 } 811 812 814 820 public static class DefaultCellFactory<VV, EE> 821 implements CellFactory<VV, EE>, Serializable 822 { 823 private static final long serialVersionUID = 3690194343461861173L; 824 825 828 public DefaultEdge createEdgeCell(EE jGraphTEdge) 829 { 830 return new DefaultEdge(jGraphTEdge); 831 } 832 833 836 public DefaultGraphCell createVertexCell(VV jGraphTVertex) 837 { 838 return new DefaultGraphCell(jGraphTVertex); 839 } 840 } 841 842 851 private class JGraphListener 852 implements GraphModelListener, Serializable 853 { 854 private static final long serialVersionUID = 3544673988098865209L; 855 856 861 public void graphChanged(GraphModelEvent e) 862 { 863 GraphModelChange change = e.getChange(); 870 871 Object [] removedCells = change.getRemoved(); 872 873 if (removedCells != null) { 874 handleRemovedEdges(filterEdges(removedCells)); 875 handleRemovedVertices(filterVertices(removedCells)); 876 } 877 878 Object [] insertedCells = change.getInserted(); 879 880 if (insertedCells != null) { 881 handleInsertedVertices(filterVertices(insertedCells)); 882 handleInsertedEdges(filterEdges(insertedCells)); 883 } 884 885 Object [] changedCells = change.getChanged(); 887 888 if (changedCells != null) { 889 handleChangedEdges(filterEdges(changedCells)); 890 } 891 } 892 893 901 private List <Object > filterEdges(Object [] cells) 902 { 903 List <Object > jEdges = new ArrayList <Object >(); 904 905 for (int i = 0; i < cells.length; i++) { 906 if (cells[i] instanceof org.jgraph.graph.Edge) { 907 jEdges.add(cells[i]); 908 } 909 } 910 911 return jEdges; 912 } 913 914 922 private List <Object > filterVertices(Object [] cells) 923 { 924 List <Object > jVertices = new ArrayList <Object >(); 925 926 for (int i = 0; i < cells.length; i++) { 927 Object cell = cells[i]; 928 929 if (cell instanceof org.jgraph.graph.Edge) { 930 } else if (cell instanceof Port) { 932 } else if (cell instanceof DefaultGraphCell) { 934 DefaultGraphCell graphCell = (DefaultGraphCell) cell; 935 936 if ( 941 graphCell.isLeaf() 942 || (graphCell.getFirstChild() instanceof Port)) { 943 jVertices.add(cell); 944 } 945 } else if (cell instanceof GraphCell) { 946 jVertices.add(cell); 949 } 950 } 951 952 return jVertices; 953 } 954 955 private void handleChangedEdges(List <Object > jEdges) 956 { 957 for (Iterator <Object > i = jEdges.iterator(); i.hasNext();) { 958 org.jgraph.graph.Edge jEdge = (org.jgraph.graph.Edge) i.next(); 959 960 handleJGraphChangedEdge(jEdge); 961 } 962 } 963 964 private void handleInsertedEdges(List <Object > jEdges) 965 { 966 for (Iterator <Object > i = jEdges.iterator(); i.hasNext();) { 967 org.jgraph.graph.Edge jEdge = (org.jgraph.graph.Edge) i.next(); 968 969 if (!jCellsBeingAdded.remove(jEdge)) { 970 handleJGraphInsertedEdge(jEdge); 971 } 972 } 973 } 974 975 private void handleInsertedVertices(List <Object > jVertices) 976 { 977 for (Iterator <Object > i = jVertices.iterator(); i.hasNext();) { 978 GraphCell jVertex = (GraphCell) i.next(); 979 980 if (!jCellsBeingAdded.remove(jVertex)) { 981 handleJGraphInsertedVertex(jVertex); 982 } 983 } 984 } 985 986 private void handleRemovedEdges(List <Object > jEdges) 987 { 988 for (Iterator <Object > i = jEdges.iterator(); i.hasNext();) { 989 org.jgraph.graph.Edge jEdge = (org.jgraph.graph.Edge) i.next(); 990 991 if (!jCellsBeingRemoved.remove(jEdge)) { 992 handleJGraphRemovedEdge(jEdge); 993 } 994 } 995 } 996 997 private void handleRemovedVertices(List <Object > jVertices) 998 { 999 for (Iterator <Object > i = jVertices.iterator(); i.hasNext();) { 1000 GraphCell jVertex = (GraphCell) i.next(); 1001 1002 if (!jCellsBeingRemoved.remove(jVertex)) { 1003 handleJGraphRemovedVertex(jVertex); 1004 } 1005 } 1006 } 1007 } 1008 1009 1018 private class JGraphTListener 1019 implements GraphListener<V, E>, Serializable 1020 { 1021 private static final long serialVersionUID = 3616724963609360440L; 1022 1023 1026 public void edgeAdded(GraphEdgeChangeEvent<V, E> e) 1027 { 1028 E jtEdge = e.getEdge(); 1029 1030 if (!jtElementsBeingAdded.remove(jtEdge)) { 1031 handleJGraphTAddedEdge(jtEdge); 1032 } 1033 } 1034 1035 1038 public void edgeRemoved(GraphEdgeChangeEvent<V, E> e) 1039 { 1040 E jtEdge = e.getEdge(); 1041 1042 if (!jtElementsBeingRemoved.remove(jtEdge)) { 1043 handleJGraphTRemovedEdge(jtEdge); 1044 } 1045 } 1046 1047 1050 public void vertexAdded(GraphVertexChangeEvent<V> e) 1051 { 1052 V jtVertex = e.getVertex(); 1053 1054 if (!jtElementsBeingAdded.remove(jtVertex)) { 1055 handleJGraphTAddedVertex(jtVertex); 1056 } 1057 } 1058 1059 1062 public void vertexRemoved(GraphVertexChangeEvent<V> e) 1063 { 1064 V jtVertex = e.getVertex(); 1065 1066 if (!jtElementsBeingRemoved.remove(jtVertex)) { 1067 handleJGraphTRemoveVertex(jtVertex); 1068 } 1069 } 1070 } 1071 1072 1075 private class ShieldedGraph 1076 { 1077 private final Graph<V, E> graph; 1078 1079 ShieldedGraph(Graph<V, E> graph) 1080 { 1081 this.graph = graph; 1082 } 1083 1084 EdgeFactory<V, E> getEdgeFactory() 1085 { 1086 return graph.getEdgeFactory(); 1087 } 1088 1089 E addEdge(V jtSource, V jtTarget) 1090 { 1091 E jtEdge = graph.getEdgeFactory().createEdge(jtSource, jtTarget); 1092 jtElementsBeingAdded.add(jtEdge); 1093 1094 boolean added = graph.addEdge(jtSource, jtTarget, jtEdge); 1095 jtElementsBeingAdded.remove(jtEdge); 1096 1097 return added ? jtEdge : null; 1098 } 1099 1100 V getEdgeSource(E e) 1101 { 1102 return graph.getEdgeSource(e); 1103 } 1104 1105 V getEdgeTarget(E e) 1106 { 1107 return graph.getEdgeTarget(e); 1108 } 1109 1110 void addVertex(V jtVertex) 1111 { 1112 jtElementsBeingAdded.add(jtVertex); 1113 graph.addVertex(jtVertex); 1114 jtElementsBeingAdded.remove(jtVertex); 1115 } 1116 1117 Set <E> edgesOf(V vertex) 1118 { 1119 return graph.edgesOf(vertex); 1120 } 1121 1122 boolean removeAllEdges(Collection <E> edges) 1123 { 1124 return graph.removeAllEdges(edges); 1125 } 1126 1127 void removeEdge(E jtEdge) 1128 { 1129 jtElementsBeingRemoved.add(jtEdge); 1130 graph.removeEdge(jtEdge); 1131 jtElementsBeingRemoved.remove(jtEdge); 1132 } 1133 1134 void removeVertex(V jtVertex) 1135 { 1136 jtElementsBeingRemoved.add(jtVertex); 1137 graph.removeVertex(jtVertex); 1138 jtElementsBeingRemoved.remove(jtVertex); 1139 } 1140 } 1141} 1142 | Popular Tags |