1 package hero.client.grapheditor; 2 3 import java.awt.Rectangle ; 4 import java.awt.geom.Point2D ; 5 import java.util.Hashtable ; 6 7 import com.jgraph.graph.CellView; 8 import com.jgraph.graph.Edge; 9 import com.jgraph.graph.GraphConstants; 10 11 12 public class Touch implements Runnable { 13 14 private WFGraph graph; 15 private Hashtable deltas = new Hashtable (); 16 private Hashtable positions = new Hashtable (); 17 private Thread relaxer; 18 private boolean allowedToRun = false; 19 private boolean repaintNeeded = false; 20 private double damper=1.0; private double maxMotion=0; private double lastMaxMotion=0; 23 private double motionRatio = 0; private boolean damping = true; 26 private double rigidity = 1; private double newRigidity = 1; 30 31 33 35 public Touch(WFGraph graph) { 36 this.graph = graph; 37 relaxer = null; 38 } 39 40 void setRigidity(double r) { 41 newRigidity = r; } 43 44 private synchronized void relaxEdges() { 46 try{ 47 Object [] edges = graph.getEdges(graph.getAll()); 48 for (int i = 0; i < edges.length; i++) { 50 CellView from = graph.getSourceView(edges[i]); 51 CellView to = graph.getTargetView(edges[i]); 52 CellView fromV = graph.getView().getMapping(((Edge) edges[i]).getSource(), false); 53 CellView toV = graph.getView().getMapping(((Edge) edges[i]).getTarget(), false); 54 55 56 if (from != null && to != null) { 57 Rectangle bf = fromV.getBounds(); Rectangle bt = toV.getBounds(); double vx = bt.x - bf.x; 62 double vy = bt.y - bf.y; 63 double len = Math.sqrt(vx * vx + vy * vy); 64 double dx=vx*rigidity; double dy=vy*rigidity; 66 double length = getLength(edges[i])*100; 67 dx /=length; 68 dy /=length; 69 moveView(to, -dx*len, -dy*len); 70 moveView(from, dx*len, dy*len); 71 72 } 73 } 74 }catch(Exception e){run();} 75 } 76 77 public double getLength(Object edge) { 78 CellView view = graph.getView().getMapping(edge, false); 79 return GPGraphTools.getLength(view); 80 } 81 82 private synchronized void avoidLabels() { 83 Object [] vertices = graph.getVertices(graph.getAll()); 84 for (int i = 0; i < vertices.length; i++) { 85 for (int j = i+1; j < vertices.length; j++) { 86 CellView from = graph.getView().getMapping(vertices[i], false); 87 CellView to = graph.getView().getMapping(vertices[j], false); 88 if (from != null && to != null) { 89 Point2D.Double bf = getPosition(from); 90 Point2D.Double bt = getPosition(to); 91 92 double dx=0; 93 double dy=0; 94 double vx = bf.x - bt.x; 95 double vy = bf.y - bt.y; 96 double len = vx * vx + vy * vy; if (len == 0) { 98 dx = Math.random(); 99 dy = Math.random(); 100 } else if (len <200*200) { 101 dx = vx / len; 102 dy = vy / len; 103 } 104 int repSum =400; moveView(from, dx*repSum, dy*repSum); 106 moveView(to, -dx*repSum, -dy*repSum); 107 } 108 } 109 } 110 } 111 112 public void startDamper() { 113 damping = true; 114 } 115 116 public void stopDamper() { 117 damping = false; 118 damper = 1.0; } 120 121 public void resetDamper() { damping = true; 123 damper = 1.0; 124 } 125 126 public void setDamper(double newValue) { 127 damper = newValue; 128 } 129 130 public void damp() { 131 if (damping) { 132 if(motionRatio<=0.001) { 138 if ((maxMotion<0.2 || (maxMotion>1 && damper<0.9)) && damper > 0.01) damper -= 0.01; 142 else if (maxMotion<0.4 && damper > 0.003) damper -= 0.003; 144 else if(damper>0.0001) damper -=0.0001; 146 } 147 } 148 if(maxMotion<0.001 && damping) 149 damper=0; 150 } 152 153 154 private synchronized void moveNodes() { 155 lastMaxMotion = maxMotion; 156 double maxMotionA=0; 157 Object [] vertices = graph.getVertices(graph.getAll()); 158 for (int i = 0; i < vertices.length; i++) { 159 CellView view = graph.getView().getMapping(vertices[i], false); 160 if (view != null) { 161 Rectangle bounds = GraphConstants.getBounds(view.getAttributes()); 162 Point2D.Double delta = getDelta(view); 163 Point2D.Double position = getPosition(view); 164 double dx = delta.getX(); 166 double dy = delta.getY(); 167 dx*=damper; 168 dy*=damper; 169 delta.setLocation(dx/2, dy/2); 170 double distMoved = Math.sqrt(dx*dx+dy*dy); 171 if (GraphConstants.isMoveable(view.getAttributes()) && 172 !graph.isCellSelected(vertices[i]) && (dx != 0 || dy != 0)) 173 { 174 position.x +=Math.max(-5, Math.min(5, dx)); 176 position.y +=Math.max(-5, Math.min(5, dy)); 177 bounds.x = Math.max(0, (int) position.x-bounds.width/2); 178 bounds.y = Math.max(0, (int) position.y-bounds.height/2); 179 repaintNeeded = true; 180 } 181 maxMotionA=Math.max(distMoved,maxMotionA); 182 183 } 184 }; 185 maxMotion=maxMotionA; 186 if (maxMotion>0) motionRatio = lastMaxMotion/maxMotion-1; 187 else motionRatio = 0; 188 damp(); 189 } 190 191 private synchronized void relax() { 192 for (int i=0;i<10;i++) { 193 relaxEdges(); 194 avoidLabels(); 195 moveNodes(); 196 } 197 if(rigidity!=newRigidity) 198 rigidity= newRigidity; if (repaintNeeded) { 200 graph.repaint(); 201 repaintNeeded = false; 202 } 203 } 204 205 public void run() { 206 Thread me = Thread.currentThread(); 207 while (relaxer == me && allowedToRun) { 208 relax(); 209 try { 211 Thread.sleep(20); 212 } catch (InterruptedException e) { 213 break; 214 } 215 } 216 } 217 218 public void start() { 219 relaxer = new Thread (this); 220 allowedToRun = true; 221 relaxer.start(); 222 } 223 224 public boolean isRunning() { 225 if (relaxer != null) 226 return relaxer.isAlive(); 227 return false; 228 } 229 230 public void stop() { 231 allowedToRun = false; 232 relaxer = null; 233 } 234 235 public Point2D.Double getPosition(CellView view) { 236 Point2D.Double p1 = (Point2D.Double ) positions.get(view); 237 238 Rectangle rect = GraphConstants.getBounds(view.getAttributes()); 239 Point2D.Double p2 = new Point2D.Double (rect.x+rect.width/2, rect.y+rect.height/2); 240 241 if(p1!=null) { 242 if(Math.abs(p1.x-p2.x)>5 || Math.abs(p1.y-p2.y)>5) { 243 p1.setLocation(p2.x,p2.y); 245 } 246 return p1; 247 } 248 else { 249 positions.put(view, p2); 250 return p2; 251 } 252 } 253 254 public Point2D.Double getDelta(CellView view) { 255 Point2D.Double p = (Point2D.Double ) deltas.get(view); 256 if (p == null) { 257 p = new Point2D.Double (0,0); 258 deltas.put(view, p); 259 } 260 return p; 261 } 262 263 public void moveView(CellView view, double dx, double dy) { 264 Point2D.Double p = getDelta(view); 266 p.setLocation(p.getX()+dx, p.getY()+dy); 267 } 268 269 } 270 | Popular Tags |