View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors
3    * All rights reserved.
4    * 
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    * 
8    * Created on Oct 8, 2004
9    *
10   */
11  package edu.uci.ics.jung.visualization.layout;
12  
13  import java.awt.Dimension;
14  import java.awt.geom.Point2D;
15  import java.io.FileInputStream;
16  import java.io.FileOutputStream;
17  import java.io.IOException;
18  import java.io.ObjectInputStream;
19  import java.io.ObjectOutputStream;
20  import java.io.Serializable;
21  import java.util.HashSet;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import com.google.common.base.Function;
26  import com.google.common.collect.ImmutableSet;
27  import com.google.common.collect.Maps;
28  
29  import edu.uci.ics.jung.algorithms.layout.Layout;
30  import edu.uci.ics.jung.visualization.util.Caching;
31  import edu.uci.ics.jung.visualization.util.ChangeEventSupport;
32  
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
40   * 
41   *  
42   */
43  public class PersistentLayoutImpl<V, E> extends ObservableCachingLayout<V,E>
44      implements PersistentLayout<V,E>,  ChangeEventSupport, Caching {
45  
46      /**
47       * a container for Vertices
48       */
49      protected Map<V, Point> locations;
50      
51      /**
52       * a collection of Vertices that should not move
53       */
54      protected Set<V> dontmove;
55  
56      /**
57       * whether the graph is locked (stops the VisualizationViewer rendering thread)
58       */
59      protected boolean locked;
60  
61      /**
62       * create an instance with a passed layout
63       * create containers for graph components
64       * @param layout the layout whose positions are to be persisted
65       */
66      public PersistentLayoutImpl(Layout<V,E> layout) {
67          super(layout);
68  	this.locations = Maps.asMap(
69  	    ImmutableSet.copyOf(layout.getGraph().getVertices()),
70  	    new RandomPointFactory<V>(getSize()));
71          this.dontmove = new HashSet<V>();
72      }
73  
74      /**
75       * This method calls <tt>initialize_local_vertex</tt> for each vertex, and
76       * also adds initial coordinate information for each vertex. (The vertex's
77       * initial location is set by calling <tt>initializeLocation</tt>.
78       */
79      protected void initializeLocations() {
80          for(V v : getGraph().getVertices()) {
81              Point2D coord = delegate.apply(v);
82              if (!dontmove.contains(v))
83                  initializeLocation(v, coord);
84          }
85      }
86  
87  
88      /**
89       * Sets persisted location for a vertex within the dimensions of the space.
90       * If the vertex has not been persisted, sets a random location. If you want
91       * to initialize in some different way, override this method.
92       * 
93       * @param v the vertex whose location is to be initialized
94       * @param coord the location 
95       */
96      protected void initializeLocation(V v, Point2D coord) {
97          Point point = locations.get(v);
98          coord.setLocation(point.x, point.y);
99      }
100 
101     /**
102      * save the Vertex locations to a file
103      * @param fileName the file to save to	
104      * @throws IOException if the file cannot be used
105      */
106     public void persist(String fileName) throws IOException {
107 
108         for(V v : getGraph().getVertices()) {
109             Point p = new Point(transform(v));
110             locations.put(v, p);
111         }
112         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
113                 fileName));
114         oos.writeObject(locations);
115         oos.close();
116     }
117 
118     /**
119      * Restore the graph Vertex locations from a file
120      * @param fileName the file to use
121      * @throws IOException for file problems
122      * @throws ClassNotFoundException for classpath problems
123      */
124     @SuppressWarnings("unchecked")
125 	public void restore(String fileName) throws IOException,
126             ClassNotFoundException {
127         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
128                 fileName));
129         locations = (Map<V, Point>) ois.readObject();
130         ois.close();
131         initializeLocations();
132         locked = true;
133         fireStateChanged();
134     }
135 
136     public void lock(boolean locked) {
137         this.locked = locked;
138     }
139 
140     /*
141      * (non-Javadoc)
142      * 
143      * @see edu.uci.ics.jung.visualization.Layout#incrementsAreDone()
144      */
145     public boolean done() {
146         return super.done() || locked;
147     }
148 
149     /*
150      * (non-Javadoc)
151      * 
152      * @see edu.uci.ics.jung.visualization.Layout#lockVertex(edu.uci.ics.jung.graph.Vertex)
153      */
154     public void lock(V v, boolean state) {
155         dontmove.add(v);
156         delegate.lock(v, state);
157     }
158     
159     @SuppressWarnings("serial")
160 	public static class RandomPointFactory<V> implements Function<V,Point>, Serializable {
161 
162     	Dimension d;
163     	public RandomPointFactory(Dimension d) {
164     		this.d = d;
165     	}
166 		public edu.uci.ics.jung.visualization.layout.PersistentLayout.Point apply(V v) {
167 	            double x = Math.random() * d.width;
168 	            double y = Math.random() * d.height;
169 				return new Point(x,y);
170 		}
171     }
172 
173 }