| 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. |