Attachment 'MultiNetworkNodeSelection.java'
Download 1 import cytoscape.CyNetwork;
2 import cytoscape.Cytoscape;
3 import cytoscape.data.FlagEvent;
4 import cytoscape.data.FlagEventListener;
5 import cytoscape.data.FlagFilter;
6 import cytoscape.plugin.CytoscapePlugin;
7 import cytoscape.util.CytoscapeAction;
8 import giny.model.Edge;
9 import giny.model.GraphPerspectiveChangeEvent;
10 import giny.model.GraphPerspectiveChangeListener;
11 import giny.model.Node;
12
13 import java.awt.event.ActionEvent;
14 import java.beans.PropertyChangeEvent;
15 import java.beans.PropertyChangeListener;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.Set;
19
20 /**
21 * This plugin creates two menu options allowing the user to activate or
22 * inactivate this plugin from the plugins menu of Cytoscape. The plugin
23 * is activated on construction.<P>
24 *
25 * When active, this plugin links all of the networks in a Cytoscape instance.
26 * Whenever a graph object is flagged or unflagged in one network, the object
27 * is set to the same state in all the other networks that contain that object.<P>
28 *
29 * If an object is added to a network, it will be flagged iff the same object
30 * exists and is flagged in another network. When a new network is created,
31 * each graph object will be flagged in that network iff the same object is
32 * flagged in an existing network.
33 *
34 * When deactivated, this plugin does not change the current flagged state of
35 * any networks and no longer responds to any changes.
36 *
37 * When activated, this plugin synchronizes all of the existing networks by
38 * flagging each graph object in every network that contains it if it is flagged
39 * in any of them.
40 */
41 public class MultiNetworkNodeSelection extends CytoscapePlugin
42 implements PropertyChangeListener, GraphPerspectiveChangeListener, FlagEventListener {
43
44 CytoscapeAction activateAction; //turns on this plugin
45 CytoscapeAction deactivateAction; //turns off this plugin
46 boolean working = false; //prevents responding to our own flag requests
47
48 public MultiNetworkNodeSelection() {
49 //creates two menu options for turning this plugin on and off
50 activateAction = new ActivateMultiNetworkNodeSelectionAction();
51 activateAction.setPreferredMenu("Plugins");
52 deactivateAction = new DeactivateMultiNetworkNodeSelectionAction();
53 deactivateAction.setPreferredMenu("Plugins");
54 Cytoscape.getDesktop().getCyMenus().addAction(activateAction);
55 Cytoscape.getDesktop().getCyMenus().addAction(deactivateAction);
56 activateNetworkLinker(); //start with plugin activated
57 }
58
59 /**
60 * Activates this plugin so that all Cytoscape networks are synchronized
61 * in the flagged state of nodes and edges. This method first synchronizes
62 * all the networks by flagging in all networks each object that is flagged
63 * in any of them. It then attaches listeners to handle future changes and
64 * switches which menu item is enabled.
65 */
66 public void activateNetworkLinker() {
67 Set flaggedNodes = getAllFlaggedNodes(); //all nodes flagged in any network
68 Set flaggedEdges = getAllFlaggedEdges(); //all edges flagged in any network
69 //iterate over all networks, flagging the sets built above that hold
70 //all graph objects flagged in any network (objects that aren't in a
71 //particular network just get skipped)
72 //also add our listeners to these objects to catch future changes
73 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
74 CyNetwork network = (CyNetwork) iter.next();
75 network.setFlaggedNodes(flaggedNodes, true);
76 network.setFlaggedEdges(flaggedEdges, true);
77 //attach listeners
78 network.addGraphPerspectiveChangeListener(this);
79 network.addFlagEventListener(this);
80 }
81 //this catches network creation and destruction events
82 Cytoscape.getSwingPropertyChangeSupport().addPropertyChangeListener(this);
83 //swap which UI menu is enabled
84 activateAction.setEnabled(false);
85 deactivateAction.setEnabled(true);
86 }
87
88 /**
89 * Deactivates this plugin so that future changes to one network will not be
90 * propagated to all other networks. The current flagged state of graph objects
91 * is not changed, and all listeners are detached. Also switches which menu item
92 * is enabled.
93 */
94 public void deactivateNetworkLinker() {
95 //detach all the listeners from the networks
96 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
97 CyNetwork network = (CyNetwork) iter.next();
98 network.removeGraphPerspectiveChangeListener(this);
99 network.removeFlagEventListener(this);
100 }
101 //don't pay attention to network creation/destruction events anymore
102 Cytoscape.getSwingPropertyChangeSupport().removePropertyChangeListener(this);
103 //swap which UI menu is enabled
104 activateAction.setEnabled(true);
105 deactivateAction.setEnabled(false);
106 }
107
108 /**
109 * Returns a Set containing all the nodes that are flagged in any network.
110 * Works properly even if this plugin is currently disabled.
111 */
112 public Set getAllFlaggedNodes() {
113 Set flaggedNodes = new HashSet(); //all nodes flagged in any network
114 //iterate over all networks, saving the flagged objects in each network
115 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
116 CyNetwork network = (CyNetwork) iter.next();
117 Set nodes = network.getFlaggedNodes();
118 flaggedNodes.addAll(nodes);
119 }
120 return flaggedNodes;
121 }
122
123 /**
124 * Returns a Set containing all the edges that are flagged in any network.
125 * Works properly even if this plugin is currently disabled.
126 */
127 public Set getAllFlaggedEdges() {
128 Set flaggedEdges = new HashSet(); //all nodes flagged in any network
129 //iterate over all networks, saving the flagged objects in each network
130 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
131 CyNetwork network = (CyNetwork) iter.next();
132 Set edges = network.getFlaggedEdges();
133 flaggedEdges.addAll(edges);
134 }
135 return flaggedEdges;
136 }
137
138 /**
139 * When a CyNetwork is created, this method catches the event and flags
140 * any graph objects that are flagged in another network. Does nothing
141 * when a CyNetwork is destroyed, since it'll automatically discard its
142 * set of listeners.<P>
143 *
144 * This method will not be called if this plugin is disabled, since the
145 * listeners get detached.
146 */
147 public void propertyChange(PropertyChangeEvent event) {
148 if (event.getPropertyName() == Cytoscape.NETWORK_CREATED) {
149 //get a reference to the network that was created
150 String net_id = (String)event.getNewValue();
151 CyNetwork network = Cytoscape.getNetwork(net_id);
152 if (network != null) {
153 //flag objects in this network if they are flagged elsewhere
154 Set flaggedNodes = getAllFlaggedNodes(); //flagged in any network
155 network.setFlaggedNodes(flaggedNodes, true);
156 Set flaggedEdges = getAllFlaggedEdges(); //flagged in any network
157 network.setFlaggedEdges(flaggedEdges, true);
158 //add listeners to catch future changes
159 network.addGraphPerspectiveChangeListener(this);
160 network.addFlagEventListener(this);
161 } else {
162 String lineSep = System.getProperty("line.separator");
163 String errString = "In MultiNetworkNodeSelection.propertyChange: " + lineSep
164 + " unexpected null network processing NETWORK_CREATED event";
165 System.err.println(errString);
166 }
167 }
168 }
169
170 /**
171 * Responds to flag events from a network's flagger by setting the same
172 * state for the graph objects in all other networks. Does nothing if
173 * the event was triggered by another method in this object.<P>
174 *
175 * This method will not be called if this plugin is disabled, since the
176 * listeners get detached.
177 */
178 public void onFlagEvent(FlagEvent event) {
179 if (working) {return;} //don't respond to our own flag requests
180 working = true; //set this variable to prevent responding to our flag requests
181 FlagFilter source = event.getSource();
182 //iterate over all linked networks to set the same flagged state
183 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
184 CyNetwork network = (CyNetwork) iter.next();
185 FlagFilter filter = network.getFlagger();
186 //if this filter is the source of the event, skip it
187 if (source == filter) {continue;}
188 handleFlagEvent(event, network);
189 }
190 working = false; //listen to flag events again
191 }
192
193 /**
194 * Given a FlagEvent representing flagging in one network, sets the
195 * same flagged state in the supplied filter from another network.
196 * Note that the FlagFilter makes sure the graph object actually exists
197 * in the attached graph before flagging it.
198 */
199 private void handleFlagEvent(FlagEvent event, CyNetwork network) {
200 boolean flagOn = event.getEventType(); //true=flag on, false = flag off
201 if (event.getTargetType() == FlagEvent.SINGLE_NODE) {
202 network.setFlagged( (Node)event.getTarget(), flagOn );
203 } else if (event.getTargetType() == FlagEvent.SINGLE_EDGE) {
204 network.setFlagged( (Edge)event.getTarget(), flagOn );
205 } else if (event.getTargetType() == FlagEvent.NODE_SET) {
206 network.setFlaggedNodes( (Set)event.getTarget(), flagOn );
207 } else if (event.getTargetType() == FlagEvent.EDGE_SET) {
208 network.setFlaggedEdges( (Set)event.getTarget(), flagOn );
209 } else {//huh? unknown target type
210 //ignore for now
211 }
212 }
213
214 /**
215 * When nodes or edges are added to a linked CyNetwork, this method flags
216 * those objects in the network that was changed if any linked network
217 * currently flags those objects.
218 */
219 public void graphPerspectiveChanged(GraphPerspectiveChangeEvent event) {
220 working = true; //don't respond to our own flag requests
221 CyNetwork source = (CyNetwork)event.getSource();
222 if (event.isNodesRestoredType()) {//nodes added to a graph
223 Node[] newNodes = event.getRestoredNodes();//all restored nodes
224 for (int n = 0; n < newNodes.length; n++) {
225 Node nodeToCheck = newNodes[n];
226 //see if any linked network currently flags this node
227 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
228 CyNetwork network = (CyNetwork) iter.next();
229 if (network == source) {continue;}//skip the source network
230 if ( network.isFlagged(nodeToCheck) ) {
231 //it's flagged in another network, so flag it in the source
232 source.setFlagged(nodeToCheck, true);
233 break; //no point in checking other networks
234 }
235 }
236 }
237 }
238 //the event can reference both restored nodes and edges
239 if (event.isEdgesRestoredType()) {//edges added to a graph
240 Edge[] newEdges = event.getRestoredEdges();//all restored edges
241 for (int n = 0; n < newEdges.length; n++) {
242 Edge edgeToCheck = newEdges[n];
243 //see if any linked network currently flags this edge
244 for (Iterator iter = Cytoscape.getNetworkSet().iterator(); iter.hasNext(); ) {
245 CyNetwork network = (CyNetwork) iter.next();
246 if (network == source) {continue;}//skip the source network
247 if ( network.isFlagged(edgeToCheck) ) {
248 //it's flagged in another network, so flag it in the source
249 source.setFlagged(edgeToCheck, true);
250 break; //no point in checking other networks
251 }
252 }
253 }
254 }
255 working = false;//listen to flag events again
256 }
257
258 /**
259 * Menu item that activates this plugin.
260 */
261 private class ActivateMultiNetworkNodeSelectionAction extends CytoscapeAction {
262
263 public ActivateMultiNetworkNodeSelectionAction() {super("Activate Multi-Network Selection");}
264 public void actionPerformed(ActionEvent ae) {activateNetworkLinker();}
265 }
266
267 /**
268 * Menu item that deactivates this plugin.
269 */
270 private class DeactivateMultiNetworkNodeSelectionAction extends CytoscapeAction {
271
272 public DeactivateMultiNetworkNodeSelectionAction() {super("Deactivate Multi-Network Selection");}
273 public void actionPerformed(ActionEvent ae) {deactivateNetworkLinker();}
274 }
275 }
276
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.- [get | view] (2011-10-20 20:44:33, 3.9 KB) [[attachment:MultiNetworkNodeSelection.jar]]
- [get | view] (2011-10-20 20:44:33, 13.0 KB) [[attachment:MultiNetworkNodeSelection.java]]
You are not allowed to attach a file to this page.