1 25 46 package org.jgrapht.graph; 47 48 import java.util.*; 49 50 import org.jgrapht.*; 51 import org.jgrapht.event.*; 52 import org.jgrapht.util.*; 53 54 55 71 public class DefaultListenableGraph<V, E> 72 extends GraphDelegator<V, E> 73 implements ListenableGraph<V, E>, Cloneable 74 { 75 76 78 private static final long serialVersionUID = 3977575900898471984L; 79 80 82 private ArrayList<GraphListener<V, E>> graphListeners = 83 new ArrayList<GraphListener<V, E>>(); 84 private ArrayList<VertexSetListener<V>> vertexSetListeners = 85 new ArrayList<VertexSetListener<V>>(); 86 private FlyweightEdgeEvent<V, E> reuseableEdgeEvent; 87 private FlyweightVertexEvent<V> reuseableVertexEvent; 88 private boolean reuseEvents; 89 90 92 97 public DefaultListenableGraph(Graph<V, E> g) 98 { 99 this(g, false); 100 } 101 102 116 public DefaultListenableGraph(Graph<V, E> g, boolean reuseEvents) 117 { 118 super(g); 119 this.reuseEvents = reuseEvents; 120 reuseableEdgeEvent = new FlyweightEdgeEvent<V, E>(this, -1, null); 121 reuseableVertexEvent = new FlyweightVertexEvent<V>(this, -1, null); 122 123 if (g instanceof ListenableGraph) { 125 throw new IllegalArgumentException ( 126 "base graph cannot be listenable"); 127 } 128 } 129 130 132 141 public void setReuseEvents(boolean reuseEvents) 142 { 143 this.reuseEvents = reuseEvents; 144 } 145 146 155 public boolean isReuseEvents() 156 { 157 return reuseEvents; 158 } 159 160 163 public E addEdge(V sourceVertex, V targetVertex) 164 { 165 E e = super.addEdge(sourceVertex, targetVertex); 166 167 if (e != null) { 168 fireEdgeAdded(e); 169 } 170 171 return e; 172 } 173 174 177 public boolean addEdge(V sourceVertex, V targetVertex, E e) 178 { 179 boolean added = super.addEdge(sourceVertex, targetVertex, e); 180 181 if (added) { 182 fireEdgeAdded(e); 183 } 184 185 return added; 186 } 187 188 191 public void addGraphListener(GraphListener<V, E> l) 192 { 193 addToListenerList(graphListeners, l); 194 } 195 196 199 public boolean addVertex(V v) 200 { 201 boolean modified = super.addVertex(v); 202 203 if (modified) { 204 fireVertexAdded(v); 205 } 206 207 return modified; 208 } 209 210 213 public void addVertexSetListener(VertexSetListener<V> l) 214 { 215 addToListenerList(vertexSetListeners, l); 216 } 217 218 221 public Object clone() 222 { 223 try { 224 TypeUtil<DefaultListenableGraph<V, E>> typeDecl = null; 225 226 DefaultListenableGraph<V, E> g = 227 TypeUtil.uncheckedCast(super.clone(), typeDecl); 228 g.graphListeners = new ArrayList<GraphListener<V, E>>(); 229 g.vertexSetListeners = new ArrayList<VertexSetListener<V>>(); 230 231 return g; 232 } catch (CloneNotSupportedException e) { 233 e.printStackTrace(); 235 throw new RuntimeException ("internal error"); 236 } 237 } 238 239 242 public E removeEdge(V sourceVertex, V targetVertex) 243 { 244 E e = super.removeEdge(sourceVertex, targetVertex); 245 246 if (e != null) { 247 fireEdgeRemoved(e); 248 } 249 250 return e; 251 } 252 253 256 public boolean removeEdge(E e) 257 { 258 boolean modified = super.removeEdge(e); 259 260 if (modified) { 261 fireEdgeRemoved(e); 262 } 263 264 return modified; 265 } 266 267 270 public void removeGraphListener(GraphListener<V, E> l) 271 { 272 graphListeners.remove(l); 273 } 274 275 278 public boolean removeVertex(V v) 279 { 280 if (containsVertex(v)) { 281 Set<E> touchingEdgesList = edgesOf(v); 282 283 removeAllEdges(new ArrayList<E>(touchingEdgesList)); 285 286 super.removeVertex(v); 288 fireVertexRemoved(v); 289 290 return true; 291 } else { 292 return false; 293 } 294 } 295 296 299 public void removeVertexSetListener(VertexSetListener<V> l) 300 { 301 vertexSetListeners.remove(l); 302 } 303 304 309 protected void fireEdgeAdded(E edge) 310 { 311 GraphEdgeChangeEvent<V, E> e = 312 createGraphEdgeChangeEvent(GraphEdgeChangeEvent.EDGE_ADDED, edge); 313 314 for (int i = 0; i < graphListeners.size(); i++) { 315 GraphListener<V, E> l = graphListeners.get(i); 316 317 l.edgeAdded(e); 318 } 319 } 320 321 326 protected void fireEdgeRemoved(E edge) 327 { 328 GraphEdgeChangeEvent<V, E> e = 329 createGraphEdgeChangeEvent( 330 GraphEdgeChangeEvent.EDGE_REMOVED, 331 edge); 332 333 for (int i = 0; i < graphListeners.size(); i++) { 334 GraphListener<V, E> l = graphListeners.get(i); 335 336 l.edgeRemoved(e); 337 } 338 } 339 340 345 protected void fireVertexAdded(V vertex) 346 { 347 GraphVertexChangeEvent<V> e = 348 createGraphVertexChangeEvent( 349 GraphVertexChangeEvent.VERTEX_ADDED, 350 vertex); 351 352 for (int i = 0; i < vertexSetListeners.size(); i++) { 353 VertexSetListener<V> l = vertexSetListeners.get(i); 354 355 l.vertexAdded(e); 356 } 357 358 for (int i = 0; i < graphListeners.size(); i++) { 359 GraphListener<V, E> l = graphListeners.get(i); 360 361 l.vertexAdded(e); 362 } 363 } 364 365 370 protected void fireVertexRemoved(V vertex) 371 { 372 GraphVertexChangeEvent<V> e = 373 createGraphVertexChangeEvent( 374 GraphVertexChangeEvent.VERTEX_REMOVED, 375 vertex); 376 377 for (int i = 0; i < vertexSetListeners.size(); i++) { 378 VertexSetListener<V> l = vertexSetListeners.get(i); 379 380 l.vertexRemoved(e); 381 } 382 383 for (int i = 0; i < graphListeners.size(); i++) { 384 GraphListener<V, E> l = graphListeners.get(i); 385 386 l.vertexRemoved(e); 387 } 388 } 389 390 private static <L extends EventListener> void addToListenerList( 391 List<L> list, 392 L l) 393 { 394 if (!list.contains(l)) { 395 list.add(l); 396 } 397 } 398 399 private GraphEdgeChangeEvent<V, E> createGraphEdgeChangeEvent( 400 int eventType, 401 E edge) 402 { 403 if (reuseEvents) { 404 reuseableEdgeEvent.setType(eventType); 405 reuseableEdgeEvent.setEdge(edge); 406 407 return reuseableEdgeEvent; 408 } else { 409 return new GraphEdgeChangeEvent<V, E>(this, eventType, edge); 410 } 411 } 412 413 private GraphVertexChangeEvent<V> createGraphVertexChangeEvent( 414 int eventType, 415 V vertex) 416 { 417 if (reuseEvents) { 418 reuseableVertexEvent.setType(eventType); 419 reuseableVertexEvent.setVertex(vertex); 420 421 return reuseableVertexEvent; 422 } else { 423 return new GraphVertexChangeEvent<V>(this, eventType, vertex); 424 } 425 } 426 427 429 435 private static class FlyweightEdgeEvent<VV, EE> 436 extends GraphEdgeChangeEvent<VV, EE> 437 { 438 private static final long serialVersionUID = 3907207152526636089L; 439 440 443 public FlyweightEdgeEvent(Object eventSource, int type, EE e) 444 { 445 super(eventSource, type, e); 446 } 447 448 453 protected void setEdge(EE e) 454 { 455 this.edge = e; 456 } 457 458 463 protected void setType(int type) 464 { 465 this.type = type; 466 } 467 } 468 469 475 private static class FlyweightVertexEvent<VV> 476 extends GraphVertexChangeEvent<VV> 477 { 478 private static final long serialVersionUID = 3257848787857585716L; 479 480 484 public FlyweightVertexEvent(Object eventSource, int type, VV vertex) 485 { 486 super(eventSource, type, vertex); 487 } 488 489 494 protected void setType(int type) 495 { 496 this.type = type; 497 } 498 499 504 protected void setVertex(VV vertex) 505 { 506 this.vertex = vertex; 507 } 508 } 509 } 510 | Popular Tags |