# Coverage details for edu.uci.ics.jung.visualization.DefaultVisualizationModel

Line | Hits | Source
--- | --- | ---
1 |  | `/*`
2 |  | `* Copyright (c) 2003, the JUNG Project and the Regents of the University`
3 |  | `* of California`
4 |  | `* All rights reserved.`
5 |  | `*`
6 |  | `* This software is open-source under the BSD license; see either`
7 |  | `* "license.txt" or`
8 |  | `* http://jung.sourceforge.net/license.txt for a description.`
9 |  | `*/`
10 |  | `package edu.uci.ics.jung.visualization;`
11 |  | ``
12 |  | `import java.awt.Dimension;`
13 |  | ``
14 |  | `import javax.swing.event.ChangeEvent;`
15 |  | `import javax.swing.event.ChangeListener;`
16 |  | `import javax.swing.event.EventListenerList;`
17 |  | ``
18 |  | `import edu.uci.ics.jung.utils.ChangeEventSupport;`
19 |  | `import edu.uci.ics.jung.utils.DefaultChangeEventSupport;`
20 |  | ``
21 |  | `/**`
22 |  | `* The model containing state values for`
23 |  | `* visualizations of graphs.`
24 |  | `* Refactored and extracted from the 1.6.0 version of VisualizationViewer`
25 |  | `*`
26 |  | `* @author Tom Nelson`
27 |  | `*/`
28 |  | `public class DefaultVisualizationModel implements VisualizationModel, ChangeEventSupport {`
29 |  | ``
30 | 0 | `ChangeEventSupport changeSupport =`
31 |  | `new DefaultChangeEventSupport(this);`
32 |  | ``
33 |  | `/**`
34 |  | `* a callback called during relaxer iteration`
35 |  | `*/`
36 |  | `protected StatusCallback statusCallback;`
37 |  | ``
38 |  | `/**`
39 |  | `* the thread that applies the current layout algorithm`
40 |  | `*/`
41 |  | `Thread relaxer;`
42 |  | ``
43 |  | `/**`
44 |  | `* when <code>true</code>, the relaxer thread will enter a wait state`
45 |  | `* until unsuspend is called`
46 |  | `*/`
47 |  | `boolean manualSuspend;`
48 |  | ``
49 |  | `/**`
50 |  | `* the layout algorithm currently in use`
51 |  | `*/`
52 |  | `protected Layout layout;`
53 |  | ``
54 |  | `/**`
55 |  | `* how long the relaxer thread pauses between iteration loops.`
56 |  | `*/`
57 | 0 | `protected long relaxerThreadSleepTime = 100L;`
58 |  | ``
59 |  | `protected ChangeListener changeListener;`
60 |  | ``
61 |  | `/**`
62 |  | `*`
63 |  | `* @param layout The Layout to apply, with its associated Graph`
64 |  | `*/`
65 |  | `public DefaultVisualizationModel(Layout layout) {`
66 | 0 | `this(layout, null);`
67 | 0 | `}`
68 |  | ``
69 |  | `/**`
70 |  | `*`
71 |  | `* @param layout`
72 |  | `* @param d The preferred size of the View that will display this graph`
73 |  | `*/`
74 | 0 | `public DefaultVisualizationModel(Layout layout, Dimension d) {`
75 | 0 | `if(changeListener == null) {`
76 | 0 | `changeListener = new ChangeListener() {`
77 |  | `public void stateChanged(ChangeEvent e) {`
78 |  | `fireStateChanged();`
79 |  | `}`
80 |  | `};`
81 |  | `}`
82 | 0 | `setGraphLayout(layout, d);`
83 | 0 | `init();`
84 | 0 | `}`
85 |  | ``
86 |  | `/**`
87 |  | `* Returns the time between iterations of the`
88 |  | `* Relaxer thread. The Relaxer thread sleeps for`
89 |  | `* a moment before calling the Layout to update`
90 |  | `* again. This tells`
91 |  | `* how long the current delay is.`
92 |  | `* The default, 20 milliseconds, essentially`
93 |  | `* causes the system to run the next iteration`
94 |  | `* with virtually no pause.`
95 |  | `* @return Returns the relaxerThreadSleepTime.`
96 |  | `*/`
97 |  | `public long getRelaxerThreadSleepTime() {`
98 | 0 | `return relaxerThreadSleepTime;`
99 |  | `}`
100 |  | ``
101 |  | `/**`
102 |  | `* Sets the relaxerThreadSleepTime.`
103 |  | `* @see #getRelaxerThreadSleepTime()`
104 |  | `* @param relaxerThreadSleepTime The relaxerThreadSleepTime to set.`
105 |  | `*/`
106 |  | `public void setRelaxerThreadSleepTime(long relaxerThreadSleepTime) {`
107 | 0 | `this.relaxerThreadSleepTime = relaxerThreadSleepTime;`
108 | 0 | `}`
109 |  | ``
110 |  | `/**`
111 |  | `* Removes the current graph layout, and adds a new one.`
112 |  | `* @param layout the new layout to use`
113 |  | `* @param viewSize the size of the View that will display this layout`
114 |  | `*/`
115 |  | `public void setGraphLayout(Layout layout, Dimension viewSize) {`
116 | 0 | `if(this.layout != null && this.layout instanceof ChangeEventSupport) {`
117 | 0 | `((ChangeEventSupport)this.layout).removeChangeListener(changeListener);`
118 |  | `}`
119 | 0 | `if(viewSize == null) {`
120 | 0 | `viewSize = new Dimension(600,600);`
121 |  | `}`
122 | 0 | `suspend();`
123 | 0 | `Dimension layoutSize = layout.getCurrentSize();`
124 |  | `// if the layout has NOT been initialized yet, initialize it`
125 |  | `// now to the size of the VisualizationViewer window`
126 | 0 | `if(layoutSize == null) {`
127 | 0 | `layout.initialize(viewSize);`
128 |  | `} else {`
129 | 0 | `layout.restart();`
130 |  | `}`
131 | 0 | `layoutSize = layout.getCurrentSize();`
132 |  | ``
133 | 0 | `this.layout = layout;`
134 | 0 | `if(this.layout instanceof ChangeEventSupport) {`
135 | 0 | `((ChangeEventSupport)this.layout).addChangeListener(changeListener);`
136 |  | `}`
137 | 0 | `prerelax();`
138 | 0 | `unsuspend();`
139 | 0 | `}`
140 |  | ``
141 |  | `/**`
142 |  | `* set the graph Layout and if it is not already initialized, initialize`
143 |  | `* it to the default VisualizationViewer preferred size of 600x600`
144 |  | `*/`
145 |  | `public void setGraphLayout(Layout layout) {`
146 | 0 | `setGraphLayout(layout, null);`
147 | 0 | `}`
148 |  | ``
149 |  | `/**`
150 |  | `* Returns the current graph layout.`
151 |  | `*/`
152 |  | `public Layout getGraphLayout() {`
153 | 0 | `return layout;`
154 |  | `}`
155 |  | ``
156 |  | `/**`
157 |  | `* starts a visRunner thread without prerelaxing`
158 |  | `*/`
159 |  | `public synchronized void restartThreadOnly() {`
160 | 0 | `if (visRunnerIsRunning ) {`
161 | 0 | `stop();`
162 |  | `//throw new FatalException("Can't init while a visrunner is running");`
163 |  | `}`
164 | 0 | `relaxer = new VisRunner();`
165 | 0 | `relaxer.setPriority(Thread.MIN_PRIORITY);`
166 | 0 | `relaxer.start();`
167 | 0 | `}`
168 |  | ``
169 |  | `/**`
170 |  | `* Pre-relaxes and starts a visRunner thread`
171 |  | `*/`
172 |  | `public synchronized void init() {`
173 | 0 | `if (visRunnerIsRunning ) {`
174 | 0 | `stop();`
175 |  | `// throw new FatalException("Can't init while a visrunner is running");`
176 |  | `}`
177 | 0 | `prerelax();`
178 | 0 | `relaxer = new VisRunner();`
179 | 0 | `relaxer.start();`
180 | 0 | `}`
181 |  | ``
182 |  | `/**`
183 |  | `* Restarts layout, then calls init();`
184 |  | `*/`
185 |  | `public synchronized void restart() {`
186 | 0 | `if (visRunnerIsRunning ) {`
187 | 0 | `stop();`
188 |  | `//throw new FatalException("Can't restart while a visrunner is running");`
189 |  | `}`
190 | 0 | `stop = false;`
191 | 0 | `layout.restart();`
192 | 0 | `init();`
193 | 0 | `fireStateChanged();`
194 | 0 | `}`
195 |  | ``
196 |  | `/**`
197 |  | `* Runs the visualization forward a few hundred iterations (for half a`
198 |  | `* second)`
199 |  | `*/`
200 |  | `public void prerelax() {`
201 | 0 | `suspend();`
202 |  | ``
203 | 0 | `int i = 0;`
204 | 0 | `if (layout.isIncremental()) {`
205 |  | `// then increment layout for half a second`
206 | 0 | `long timeNow = System.currentTimeMillis();`
207 | 0 | `while (System.currentTimeMillis() - timeNow < 500 && !layout.incrementsAreDone()) {`
208 | 0 | `i++;`
209 | 0 | `layout.advancePositions();`
210 |  | `}`
211 |  | `}`
212 | 0 | `unsuspend();`
213 | 0 | `}`
214 |  | ``
215 |  | `/**`
216 |  | `* If the visualization runner is not yet running, kick it off.`
217 |  | `*/`
218 |  | `public synchronized void start() {`
219 | 0 | `synchronized (pauseObject) {`
220 | 0 | `pauseObject.notifyAll();`
221 | 0 | `}`
222 | 0 | `}`
223 |  | ``
224 |  | `/**`
225 |  | `* set a flag to suspend the relaxer thread`
226 |  | `*/`
227 |  | `public synchronized void suspend() {`
228 | 0 | `manualSuspend = true;`
229 | 0 | `}`
230 |  | ``
231 |  | `/**`
232 |  | `* un-set the suspend flag for the relaxer thead`
233 |  | `*/`
234 |  | `public synchronized void unsuspend() {`
235 | 0 | `manualSuspend = false;`
236 | 0 | `synchronized (pauseObject) {`
237 | 0 | `pauseObject.notifyAll();`
238 | 0 | `}`
239 | 0 | `}`
240 |  | ``
241 | 0 | `public Object pauseObject = new String("PAUSE OBJECT");`
242 |  | ``
243 | 0 | `long[] relaxTimes = new long[5];`
244 | 0 | `long[] paintTimes = new long[5];`
245 | 0 | `int relaxIndex = 0;`
246 | 0 | `int paintIndex = 0;`
247 |  | `double paintfps, relaxfps;`
248 |  | ``
249 |  | ``
250 | 0 | `boolean stop = false;`
251 |  | ``
252 | 0 | `boolean visRunnerIsRunning = false;`
253 |  | ``
254 |  | `/**`
255 |  | `* the relaxer thread that applies the Layout algorithm to the graph`
256 |  | `*`
257 |  | `*/`
258 |  | `protected class VisRunner extends Thread {`
259 |  | `public VisRunner() {`
260 |  | `super("Relaxer Thread");`
261 |  | `}`
262 |  | ``
263 |  | `public void run() {`
264 |  | `visRunnerIsRunning = true;`
265 |  | `try {`
266 |  | `while (!layout.incrementsAreDone() && !stop) {`
267 |  | `synchronized (pauseObject) {`
268 |  | `while (manualSuspend && !stop) {`
269 |  | `try {`
270 |  | `pauseObject.wait();`
271 |  | `} catch (InterruptedException e) {`
272 |  | `// System.err.println("vis runner wait interrupted");`
273 |  | `}`
274 |  | `}`
275 |  | `}`
276 |  | `long start = System.currentTimeMillis();`
277 |  | `layout.advancePositions();`
278 |  | `long delta = System.currentTimeMillis() - start;`
279 |  | ``
280 |  | `if (stop)`
281 |  | `return;`
282 |  | ``
283 |  | `String status = layout.getStatus();`
284 |  | `if (statusCallback != null && status != null) {`
285 |  | `statusCallback.callBack(status);`
286 |  | `}`
287 |  | ``
288 |  | `if (stop)`
289 |  | `return;`
290 |  | ``
291 |  | `relaxTimes[relaxIndex++] = delta;`
292 |  | `relaxIndex = relaxIndex % relaxTimes.length;`
293 |  | `relaxfps = average(relaxTimes);`
294 |  | ``
295 |  | `if (stop)`
296 |  | `return;`
297 |  | `fireStateChanged();`
298 |  | ``
299 |  | `if (stop)`
300 |  | `return;`
301 |  | ``
302 |  | `try {`
303 |  | `sleep(relaxerThreadSleepTime);`
304 |  | `} catch (InterruptedException ie) {`
305 |  | `// System.err.println("vis runner sleep insterrupted");`
306 |  | `}`
307 |  | `}`
308 |  | `} finally {`
309 |  | `visRunnerIsRunning = false;`
310 |  | `}`
311 |  | `}`
312 |  | `}`
313 |  | ``
314 |  | `/**`
315 |  | `* Returns a flag that says whether the visRunner thread is running. If`
316 |  | `* it is not, then you may need to restart the thread.`
317 |  | `*/`
318 |  | `public boolean isVisRunnerRunning() {`
319 | 0 | `return visRunnerIsRunning;`
320 |  | `}`
321 |  | ``
322 |  | `/**`
323 |  | `* Returns the double average of a number of long values.`
324 |  | `* @param paintTimes an array of longs`
325 |  | `* @return the average of the doubles`
326 |  | `*/`
327 |  | `protected double average(long[] paintTimes) {`
328 | 0 | `double l = 0;`
329 | 0 | `for (int i = 0; i < paintTimes.length; i++) {`
330 | 0 | `l += paintTimes[i];`
331 |  | `}`
332 | 0 | `return l / paintTimes.length;`
333 |  | `}`
334 |  | ``
335 |  | `/**`
336 |  | `* @param scb`
337 |  | `*/`
338 |  | `public void setTextCallback(StatusCallback scb) {`
339 | 0 | `this.statusCallback = scb;`
340 | 0 | `}`
341 |  | ``
342 |  | `/**`
343 |  | `* set a flag to stop the VisRunner relaxer thread`
344 |  | `*/`
345 |  | `public synchronized void stop() {`
346 | 0 | `manualSuspend = false;`
347 | 0 | `stop = true;`
348 |  | `// interrupt the relaxer, in case it is paused or sleeping`
349 |  | `// this should ensure that visRunnerIsRunning gets set to false`
350 | 0 | `try { relaxer.interrupt(); }`
351 | 0 | `catch(Exception ex) {`
352 |  | `// the applet security manager may have prevented this.`
353 |  | `// just sleep for a second to let the thread stop on its own`
354 | 0 | `System.err.println("got "+ex);`
355 | 0 | `try { Thread.sleep(1000); }`
356 | 0 | `catch(InterruptedException ie) {} // swallow`
357 | 0 | `}`
358 | 0 | `synchronized (pauseObject) {`
359 | 0 | `pauseObject.notifyAll();`
360 | 0 | `}`
361 | 0 | `}`
362 |  | ``
363 |  | `/**`
364 |  | `* Adds a <code>ChangeListener</code>.`
365 |  | `* @param l the listener to be added`
366 |  | `*/`
367 |  | `public void addChangeListener(ChangeListener l) {`
368 | 0 | `changeSupport.addChangeListener(l);`
369 | 0 | `}`
370 |  | ``
371 |  | `/**`
372 |  | `* Removes a ChangeListener.`
373 |  | `* @param l the listener to be removed`
374 |  | `*/`
375 |  | `public void removeChangeListener(ChangeListener l) {`
376 | 0 | `changeSupport.removeChangeListener(l);`
377 | 0 | `}`
378 |  | ``
379 |  | `/**`
380 |  | `* Returns an array of all the <code>ChangeListener</code>s added`
381 |  | `* with addChangeListener().`
382 |  | `*`
383 |  | `* @return all of the <code>ChangeListener</code>s added or an empty`
384 |  | `* array if no listeners have been added`
385 |  | `*/`
386 |  | `public ChangeListener[] getChangeListeners() {`
387 | 0 | `return changeSupport.getChangeListeners();`
388 |  | `}`
389 |  | ``
390 |  | `/**`
391 |  | `* Notifies all listeners that have registered interest for`
392 |  | `* notification on this event type. The event instance`
393 |  | `* is lazily created.`
394 |  | `* The primary listeners will be views that need to be repainted`
395 |  | `* because of changes in this model instance`
396 |  | `* @see EventListenerList`
397 |  | `*/`
398 |  | `public void fireStateChanged() {`
399 | 0 | `changeSupport.fireStateChanged();`
400 | 0 | `}`
401 |  | ``
402 |  | `}`

this report was generated by version 1.0.5 of jcoverage. visit www.jcoverage.com for updates. | copyright © 2003, jcoverage ltd. all rights reserved. Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.