Line | Hits | Source |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2005, the JUNG Project and the Regents of the University of | |
3 | * California All rights reserved. | |
4 | * | |
5 | * This software is open-source under the BSD license; see either "license.txt" | |
6 | * or http://jung.sourceforge.net/license.txt for a description. | |
7 | * | |
8 | * Created on Oct 8, 2004 | |
9 | * | |
10 | */ | |
11 | package edu.uci.ics.jung.visualization; | |
12 | ||
13 | import java.awt.Dimension; | |
14 | import java.io.FileInputStream; | |
15 | import java.io.FileOutputStream; | |
16 | import java.io.IOException; | |
17 | import java.io.ObjectInputStream; | |
18 | import java.io.ObjectOutputStream; | |
19 | import java.util.HashMap; | |
20 | import java.util.HashSet; | |
21 | import java.util.Iterator; | |
22 | import java.util.Map; | |
23 | import java.util.Set; | |
24 | ||
25 | import javax.swing.event.ChangeEvent; | |
26 | import javax.swing.event.ChangeListener; | |
27 | ||
28 | import edu.uci.ics.jung.graph.Vertex; | |
29 | import edu.uci.ics.jung.utils.ChangeEventSupport; | |
30 | import edu.uci.ics.jung.utils.DefaultChangeEventSupport; | |
31 | import edu.uci.ics.jung.utils.Pair; | |
32 | import edu.uci.ics.jung.utils.UserData; | |
33 | ||
34 | /** | |
35 | * Implementation of PersistentLayout. | |
36 | * Defers to another layout until 'restore' is called, | |
37 | * then it uses the saved vertex locations | |
38 | * | |
39 | * @author Tom Nelson - RABA Technologies | |
40 | * | |
41 | * | |
42 | */ | |
43 | public class PersistentLayoutImpl extends LayoutDecorator | |
44 | implements PersistentLayout { | |
45 | ||
46 | 0 | protected ChangeEventSupport changeSupport = |
47 | new DefaultChangeEventSupport(this); | |
48 | ||
49 | /** | |
50 | * a container for Vertices | |
51 | */ | |
52 | protected Map map; | |
53 | ||
54 | /** | |
55 | * a key for this class | |
56 | */ | |
57 | protected Object key; | |
58 | ||
59 | /** | |
60 | * a collection of Vertices that should not move | |
61 | */ | |
62 | protected Set dontmove; | |
63 | ||
64 | /** | |
65 | * whether the graph is locked (stops the VisualizationViewer rendering thread) | |
66 | */ | |
67 | protected boolean locked; | |
68 | ||
69 | 0 | private static final Object BASE_KEY = "edu.uci.ics.jung.Base_Visualization_Key"; |
70 | ||
71 | protected RadiusGraphElementAccessor elementAccessor; | |
72 | ||
73 | /** | |
74 | * create an instance with a passed layout | |
75 | * create containers for graph components | |
76 | * @param layout | |
77 | */ | |
78 | public PersistentLayoutImpl(Layout layout) { | |
79 | 0 | super(layout); |
80 | 0 | this.map = new HashMap(); |
81 | 0 | this.dontmove = new HashSet(); |
82 | 0 | this.elementAccessor = new RadiusGraphElementAccessor(layout); |
83 | 0 | if(layout instanceof ChangeEventSupport) { |
84 | 0 | ((ChangeEventSupport)layout).addChangeListener(new ChangeListener() { |
85 | public void stateChanged(ChangeEvent e) { | |
86 | fireStateChanged(); | |
87 | } | |
88 | }); | |
89 | } | |
90 | 0 | } |
91 | ||
92 | /** | |
93 | * This method calls <tt>initialize_local_vertex</tt> for each vertex, and | |
94 | * also adds initial coordinate information for each vertex. (The vertex's | |
95 | * initial location is set by calling <tt>initializeLocation</tt>. | |
96 | */ | |
97 | protected void initializeLocations() { | |
98 | 0 | for (Iterator iter = getGraph().getVertices().iterator(); iter |
99 | 0 | .hasNext();) { |
100 | 0 | Vertex v = (Vertex) iter.next(); |
101 | ||
102 | 0 | Coordinates coord = (Coordinates) v.getUserDatum(getBaseKey()); |
103 | 0 | if (coord == null) { |
104 | 0 | coord = new Coordinates(); |
105 | 0 | v.addUserDatum(getBaseKey(), coord, UserData.REMOVE); |
106 | } | |
107 | 0 | if (!dontmove.contains(v)) |
108 | 0 | initializeLocation(v, coord, getCurrentSize()); |
109 | } | |
110 | 0 | } |
111 | ||
112 | ||
113 | /** | |
114 | * Sets persisted location for a vertex within the dimensions of the space. | |
115 | * If the vertex has not been persisted, sets a random location. If you want | |
116 | * to initialize in some different way, override this method. | |
117 | * | |
118 | * @param v | |
119 | * @param coord | |
120 | * @param d | |
121 | */ | |
122 | protected void initializeLocation(Vertex v, Coordinates coord, Dimension d) { | |
123 | double x; | |
124 | double y; | |
125 | 0 | Point point = (Point) map.get(new Integer(v.hashCode())); |
126 | 0 | if (point == null) { |
127 | 0 | x = Math.random() * d.getWidth(); |
128 | 0 | y = Math.random() * d.getHeight(); |
129 | } else { | |
130 | 0 | x = point.x; |
131 | 0 | y = point.y; |
132 | } | |
133 | 0 | coord.setX(x); |
134 | 0 | coord.setY(y); |
135 | 0 | } |
136 | ||
137 | /** | |
138 | * save the Vertex locations to a file | |
139 | * @param fileName the file to save to | |
140 | * @throws an IOException if the file cannot be used | |
141 | */ | |
142 | public void persist(String fileName) throws IOException { | |
143 | 0 | Set set = getGraph().getVertices(); |
144 | 0 | for (Iterator iterator = set.iterator(); iterator.hasNext();) { |
145 | 0 | Vertex v = (Vertex) iterator.next(); |
146 | 0 | Point p = new Point(getX(v), getY(v)); |
147 | 0 | map.put(new Integer(v.hashCode()), p); |
148 | } | |
149 | 0 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( |
150 | fileName)); | |
151 | 0 | oos.writeObject(map); |
152 | 0 | oos.close(); |
153 | 0 | } |
154 | ||
155 | /** | |
156 | * Restore the graph Vertex locations from a file | |
157 | * @param fileName the file to use | |
158 | * @throws IOException for file problems | |
159 | * @throws ClassNotFoundException for classpath problems | |
160 | */ | |
161 | public void restore(String fileName) throws IOException, | |
162 | ClassNotFoundException { | |
163 | 0 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream( |
164 | fileName)); | |
165 | 0 | map = (Map) ois.readObject(); |
166 | 0 | ois.close(); |
167 | 0 | initializeLocations(); |
168 | 0 | locked = true; |
169 | 0 | } |
170 | ||
171 | public void lock(boolean locked) { | |
172 | 0 | this.locked = locked; |
173 | 0 | } |
174 | ||
175 | /* | |
176 | * (non-Javadoc) | |
177 | * | |
178 | * @see edu.uci.ics.jung.visualization.Layout#incrementsAreDone() | |
179 | */ | |
180 | public boolean incrementsAreDone() { | |
181 | 0 | return locked; |
182 | } | |
183 | ||
184 | /* | |
185 | * (non-Javadoc) | |
186 | * | |
187 | * @see edu.uci.ics.jung.visualization.Layout#lockVertex(edu.uci.ics.jung.graph.Vertex) | |
188 | */ | |
189 | public void lockVertex(Vertex v) { | |
190 | 0 | dontmove.add(v); |
191 | 0 | delegate.lockVertex(v); |
192 | 0 | } |
193 | ||
194 | /* | |
195 | * (non-Javadoc) | |
196 | * | |
197 | * @see edu.uci.ics.jung.visualization.Layout#unlockVertex(edu.uci.ics.jung.graph.Vertex) | |
198 | */ | |
199 | public void unlockVertex(Vertex v) { | |
200 | 0 | dontmove.remove(v); |
201 | 0 | delegate.unlockVertex(v); |
202 | 0 | } |
203 | ||
204 | /** | |
205 | * Returns a visualization-specific key (that is, specific to | |
206 | * the layout in use) that can be used to access | |
207 | * UserData related to the <tt>AbstractLayout</tt>. | |
208 | */ | |
209 | public Object getBaseKey() { | |
210 | 0 | if (key == null) |
211 | 0 | key = new Pair(delegate, BASE_KEY); |
212 | 0 | return key; |
213 | } | |
214 | ||
215 | public void update() { | |
216 | 0 | if(delegate instanceof LayoutMutable) { |
217 | 0 | ((LayoutMutable)delegate).update(); |
218 | } | |
219 | 0 | } |
220 | ||
221 | public void addChangeListener(ChangeListener l) { | |
222 | 0 | if(delegate instanceof ChangeEventSupport) { |
223 | 0 | ((ChangeEventSupport)delegate).addChangeListener(l); |
224 | } | |
225 | 0 | changeSupport.addChangeListener(l); |
226 | 0 | } |
227 | ||
228 | public void removeChangeListener(ChangeListener l) { | |
229 | 0 | if(delegate instanceof ChangeEventSupport) { |
230 | 0 | ((ChangeEventSupport)delegate).removeChangeListener(l); |
231 | } | |
232 | 0 | changeSupport.removeChangeListener(l); |
233 | 0 | } |
234 | ||
235 | public ChangeListener[] getChangeListeners() { | |
236 | 0 | return changeSupport.getChangeListeners(); |
237 | } | |
238 | ||
239 | public void fireStateChanged() { | |
240 | 0 | changeSupport.fireStateChanged(); |
241 | 0 | } |
242 | } |
this report was generated by version 1.0.5 of jcoverage. |
copyright © 2003, jcoverage ltd. all rights reserved. |