View Javadoc
1   package edu.uci.ics.jung.graph;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.LinkedList;
7   import java.util.List;
8   
9   import edu.uci.ics.jung.graph.event.GraphEvent;
10  import edu.uci.ics.jung.graph.event.GraphEventListener;
11  import edu.uci.ics.jung.graph.util.EdgeType;
12  
13  /**
14   * A decorator class for graphs which generates events 
15   * 
16   * @author Joshua O'Madadhain
17   */
18  @SuppressWarnings("serial")
19  public class ObservableGraph<V,E> extends GraphDecorator<V,E> {
20  
21  	List<GraphEventListener<V,E>> listenerList = 
22  		Collections.synchronizedList(new LinkedList<GraphEventListener<V,E>>());
23  
24      /**
25       * Creates a new instance based on the provided {@code delegate}.
26       * 
27       * @param delegate the graph on which this class operates
28       */
29  	public ObservableGraph(Graph<V, E> delegate) {
30  		super(delegate);
31  	}
32  	
33  	/**
34  	 * Adds {@code l} as a listener to this graph.
35  	 * 
36  	 * @param l the listener to add
37  	 */
38  	public void addGraphEventListener(GraphEventListener<V,E> l) {
39  		listenerList.add(l);
40  	}
41  
42      /**
43       * Removes {@code l} as a listener to this graph.
44       * 
45  	 * @param l the listener to remove
46       */
47  	public void removeGraphEventListener(GraphEventListener<V,E> l) {
48  		listenerList.remove(l);
49  	}
50  
51  	protected void fireGraphEvent(GraphEvent<V,E> evt) {
52  		for(GraphEventListener<V,E> listener : listenerList) {
53  			listener.handleGraphEvent(evt);
54  		 }
55  	 }
56  
57  	/**
58  	 * @see edu.uci.ics.jung.graph.Hypergraph#addEdge(java.lang.Object, java.util.Collection)
59  	 */
60  	@Override
61  	public boolean addEdge(E edge, Collection<? extends V> vertices) {
62  		boolean state = super.addEdge(edge, vertices);
63  		if(state) {
64  			GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, edge);
65  			fireGraphEvent(evt);
66  		}
67  		return state;
68  	}
69  
70  	/**
71  	 * @see edu.uci.ics.jung.graph.Graph#addEdge(java.lang.Object, java.lang.Object, java.lang.Object, edu.uci.ics.jung.graph.util.EdgeType)
72  	 */
73  	@Override
74    public boolean addEdge(E e, V v1, V v2, EdgeType edgeType) {
75  		boolean state = super.addEdge(e, v1, v2, edgeType);
76  		if(state) {
77  			GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, e);
78  			fireGraphEvent(evt);
79  		}
80  		return state;
81  	}
82  
83  	/**
84  	 * @see edu.uci.ics.jung.graph.Graph#addEdge(java.lang.Object, java.lang.Object, java.lang.Object)
85  	 */
86  	@Override
87    public boolean addEdge(E e, V v1, V v2) {
88  		boolean state = super.addEdge(e, v1, v2);
89  		if(state) {
90  			GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_ADDED, e);
91  			fireGraphEvent(evt);
92  		}
93  		return state;
94  	}
95  
96  	/**
97  	 * @see edu.uci.ics.jung.graph.Hypergraph#addVertex(java.lang.Object)
98  	 */
99  	@Override
100   public boolean addVertex(V vertex) {
101 		boolean state = super.addVertex(vertex);
102 		if(state) {
103 			GraphEvent<V,E> evt = new GraphEvent.Vertex<V,E>(delegate, GraphEvent.Type.VERTEX_ADDED, vertex);
104 			fireGraphEvent(evt);
105 		}
106 		return state;
107 	}
108 
109 	/**
110 	 * @see edu.uci.ics.jung.graph.Hypergraph#removeEdge(java.lang.Object)
111 	 */
112 	@Override
113   public boolean removeEdge(E edge) {
114 		boolean state = delegate.removeEdge(edge);
115 		if(state) {
116 			GraphEvent<V,E> evt = new GraphEvent.Edge<V,E>(delegate, GraphEvent.Type.EDGE_REMOVED, edge);
117 			fireGraphEvent(evt);
118 		}
119 		return state;
120 	}
121 
122 	/**
123 	 * @see edu.uci.ics.jung.graph.Hypergraph#removeVertex(java.lang.Object)
124 	 */
125 	@Override
126 	public boolean removeVertex(V vertex) {
127 		// remove all incident edges first, so that the appropriate events will
128 		// be fired (otherwise they'll be removed inside {@code delegate.removeVertex}
129 		// and the events will not be fired)
130 		Collection<E> incident_edges = new ArrayList<E>(delegate.getIncidentEdges(vertex));
131 		for (E e : incident_edges) 
132 			this.removeEdge(e);
133 		
134 		boolean state = delegate.removeVertex(vertex);
135 		if(state) {
136 			GraphEvent<V,E> evt = new GraphEvent.Vertex<V,E>(delegate, GraphEvent.Type.VERTEX_REMOVED, vertex);
137 			fireGraphEvent(evt);
138 		}
139 		return state;
140 	}
141 
142 }