www.pudn.com > JAVIS-0.3.zip > ForceLayoutManager.java



package animation.layout;

import animation.layout.GraphLayoutManager;
import java.util.Dictionary;
import java.util.Enumeration;
import java.awt.Dimension;
import animation.Node;
import animation.Link;
import iface.VisualiserPanel;
import util.Debug;
import util.Preferences;

/**
   ForceLayoutManager provides an implementation of an autolayout mechanism
   shown in the JDK 1.1.7 demo directory. It's basically cut&paste&hack but
   works.
*/
public class ForceLayoutManager extends GraphLayoutManager{

    VisualiserPanel m_panel;

    /**
       Redraw the panel after doing that many iterations.
    */
    public final static int REPAINT_THRESHHOLD = 5;

    /**
       The constructor simply takes the nodes and links as parameters.
       @param nodes a dictionary of all nodes, indexed by node address
       @param links a vector of links
       @param screensize the dimensions that can be allocated to nodes
       @param panel the current drawing panel (used for updating)
    */
    public ForceLayoutManager(Dictionary nodes,java.util.Vector links,
			      Dimension screensize,VisualiserPanel panel) {
      super(nodes,links,screensize);
      Debug.out.println(screensize);
      m_panel=panel;
    } 


    /**
       doLayout will apply a force optimisation layout a specified number
       of times, where the number of times is set in the constructor.
       This uses the stuff found in the JDK 1.1.7. However, in addition to
       that it centres the networkx.
       @param iterations the number of times to repeat the layout 
    */
    public synchronized void doLayout(int iterations) {

      for (int cnt=0;cnt0) {
	    dlen=Math.sqrt(dlen)/2;
	    
	    n1.move(dx/dlen,dy/dlen);
	  }
	}

	// Values to find minima and maxima
	double minx=10000,maxx=-10000,miny=10000,maxy=-10000;

	// Find minima and maxima
	for (Enumeration i=m_nodes.elements();i.hasMoreElements();) {
	  Node n=(Node)i.nextElement();

	  if (n.getX()maxx) maxx=n.getX();

	  if (n.getY()maxy) maxy=n.getY();
	}

	// Now scale network (leaves a border of 50 pixels)
	double scale_x=(m_screen.width-50)/(maxx-minx);
	double scale_y=(m_screen.height-50)/(maxy-miny);
	double move_x=m_screen.width/2-(minx+(maxx-minx)/2);
	double move_y=m_screen.height/2-(miny+(maxy-miny)/2);

	//Debug.out.println(minx+" "+maxx);
	//Debug.out.println(move_x);
	
	for (Enumeration i=m_nodes.elements();i.hasMoreElements();) {
	  Node n=(Node)i.nextElement();

	  double x=n.getX()-m_screen.width/2+move_x;
	  double y=n.getY()-m_screen.height/2+move_y;
	  
	  x=x*scale_x+m_screen.width/2;
	  y=y*scale_y+m_screen.height/2;

	  n.setX(x);
	  n.setY(y);
	}



      }
    }
}