Java 3D Desktop Environment旨在使用Java 3D来创建一个3D桌面环境。功能包括:分布式的应用程序

源代码在线查看: graphlayout.java

软件大小: 1221 K
上传用户: lilacky
关键词: Java Environment Desktop 3D
下载地址: 免注册下载 普通下载 VIP

相关代码

				package org.j3de.ui.impl;
				
				import java.util.ConcurrentModificationException;
				import java.util.Enumeration;
				import java.util.HashMap;
				import java.util.Iterator;
				import java.util.List;
				import java.util.Map;
				import java.util.Vector;
				
				import javax.swing.event.ChangeListener;
				
				import javax.media.j3d.Transform3D;
				import javax.media.j3d.Bounds;    
				import javax.media.j3d.BoundingBox;    
				import javax.media.j3d.BranchGroup;    
				import javax.media.j3d.Group;
				import javax.media.j3d.Node;
				
				import javax.vecmath.Point3d;
				import javax.vecmath.Vector3d;
				
				import org.j3de.ui.LayoutConstraint;
				import org.j3de.ui.LayoutEntry;
				import org.j3de.ui.LayoutInfo;
				import org.j3de.ui.LayoutManager3D;
				import org.j3de.ui.UIElement;
				import org.j3de.ui.UIElementMapper;
				import org.j3de.ui.UILocalElement;
				
				public class GraphLayout extends LayoutManager3D { 
				  private static double MINCHANGE  = 0.1;   
				  private static double ANNEALING  = 0.9;
				
				  protected UIElementMapper       elementMapper;                         
				
				  /** Contains mapping of local UIElement (NOT Stubs) to their GraphLayoutElements) */
				  private Map                   gleMap; 
				
				  private List                  elements;
				  private List                  constraints;   
				  private LayoutInfo            layoutInfo; 
				  private double                annealing; 
				  private boolean               layoutThreadRunning;
				  private boolean               layoutModified;
				  private BoundsChangeHelper     boundsHelper;
				    
				  public GraphLayout() {    
				    this.setCapability(Group.ALLOW_CHILDREN_READ);
				    this.setCapability(Group.ALLOW_CHILDREN_WRITE);
				    this.setCapability(Group.ALLOW_CHILDREN_EXTEND);     
				    this.setBoundsAutoCompute(false);
				    this.setCapability(BranchGroup.ALLOW_BOUNDS_WRITE);
				    this.setCapability(BranchGroup.ALLOW_BOUNDS_READ);
				     
				    this.boundsHelper = new BoundsChangeHelper(this);                  
				    this.gleMap              = new HashMap();
				    this.elements            = new Vector();
				    this.constraints         = new Vector();
				    this.layoutInfo          = new GraphLayoutInfo();
				    this.layoutThreadRunning = false;
				    this.layoutModified      = true;    
				    this.annealing           = 1.0;
				  } 
				  
				  private void updateBounds() {
				    if (elements.size() == 0) {
				      setBounds(new BoundingBox());
				      return;
				    }
				    
				    BoundingBox bb = new BoundingBox(((GraphLayoutElement)elements.get(0)).getBounds());
				    for (int i=0; i				      bb.combine(((GraphLayoutElement)elements.get(i)).getBounds());
				
				    setBounds(bb);
				    boundsHelper.updateBounds();
				  }
				
				  /** Add a ChangeListener, that is notified, when the Bounds of the UIElement change. */
				  public void addBoundsChangeListener(ChangeListener listener) {
				    boundsHelper.addBoundsChangeListener(listener);
				  }
				
				  /** Remove a ChangeListener, that is notified, when the Bounds of the UIElement change. */
				  public void removeBoundsChangeListener(ChangeListener listener) {
				    boundsHelper.removeBoundsChangeListener(listener);
				  }
				 
				  public void setElementMapper(UIElementMapper elementMapper) {
				    this.elementMapper       = elementMapper;    
				  }    
				     
				  protected void doLayout() {
				    // Create a thread every time, because a constantly running thread
				    // would prevent this object from being gc'ed       
				    layoutModified = true; 
				    
				    if (!layoutThreadRunning)
				      new Thread(new LayoutThread()).start();
				  }          
				  
				  public void normalize(Transform3D transform) {
				  }                      
				           
				  public synchronized void add(UIElement element) {      
				    // Get a local reference to element
				    element = elementMapper.getLocal(element).getRemoteElement();
				
				    GraphLayoutElement gle = new GraphLayoutElement(element, elementMapper, GraphLayout.this);        
				      
				    Iterator iter = constraints.iterator();
				    while(iter.hasNext()) {
				      LayoutConstraint constraint = (LayoutConstraint)iter.next();
				      if (constraint.appliesTo(element))
				        gle.addConstraint(constraint);
				    }
				      
				    this.addChild(gle);  
				
				    // We need a pointer to the local element, not a reference to the stub in gleMap
				    gleMap.put(element, gle);
				    elements.add(gle);
				    doLayout();      
				  }
				    
				  public synchronized void   remove(UIElement element)  {    
				    // Get a local reference to element
				    element = elementMapper.getLocal(element).getRemoteElement();
				
				    GraphLayoutElement gle = (GraphLayoutElement)gleMap.get(element); 
				    gle.detach();        
				    
				    gleMap.remove(element);
				    elements.remove(element);
				
				    // TODO : Remove Constraints that are not needed anymore !
				    doLayout();
				  }
				    
				  protected synchronized void   addLayoutConstraint(LayoutConstraint constraint) {    
				    constraints.add(constraint);
				    
				    constraint.setLayoutInfo(layoutInfo);
				    
				    Iterator iter = elements.iterator();
				    while(iter.hasNext()) {
				      GraphLayoutElement gle = (GraphLayoutElement)iter.next();
				      if (constraint.appliesTo(gle.getUIElement()))
				        gle.addConstraint(constraint);
				    }
				    
				    doLayout();
				  }
				    
				  protected synchronized void   removeLayoutConstraint(LayoutConstraint constraint) {
				  }
				  
				  protected class GraphLayoutInfo implements LayoutInfo {
				    
				    public void     getPosition(UIElement element, Vector3d position) {
				      GraphLayoutElement gle = (GraphLayoutElement)gleMap.get(element);
				      gle.getPosition(position);
				    }
				    
				    public javax.media.j3d.Bounds   getBounds(UIElement element) {
				      GraphLayoutElement gle = (GraphLayoutElement)gleMap.get(element);
				      return gle.getElementBounds();
				    }
				    
				    public Enumeration getLayoutEntries(UIElement element) {
				      return new GraphEntryEnumeration();
				    }
				
				  }          
				  
				  protected class GraphEntryEnumeration implements Enumeration { 
				    private Iterator iter;
				    
				    public GraphEntryEnumeration() {   
				      iter = elements.iterator();
				    }     
				    
				    public boolean hasMoreElements() {
				      return iter.hasNext();
				    }                               
				    
				    public Object nextElement() {
				      GraphLayoutElement gle = (GraphLayoutElement)iter.next();
				      Vector3d pos = new Vector3d();   
				      gle.getPosition(pos);
				      return new LayoutEntry(pos, gle.getBounds());
				    }
				  } 
				  
				  protected class LayoutThread implements Runnable {
				    public void run() {               
      
				      Vector3d oldPosition = new Vector3d();
				      Vector3d position    = new Vector3d();
				      Vector3d vector      = new Vector3d();
				      
				      GraphLayoutElement gle;
				      Iterator iter;
				      while (layoutModified) {       
				        layoutModified = false;
				        
				        double maxChange = 0.0;
				        double change;
				        
				        // Calculate next Position of each GraphLayoutElement
				        try {
				          iter = elements.iterator();
				          
				          while (iter.hasNext()) {   
				            gle = (GraphLayoutElement)iter.next();
				            gle.getPosition(oldPosition);
				            gle.move(annealing);       
				            gle.getPosition(position);
				            position.sub(oldPosition);
				            
				            vector.set(position);
				            change = vector.length();
				            
				            if (change > maxChange)
				              maxChange = change;
				          }                                           
				          
				        } catch (ConcurrentModificationException e) {
				          // elements has been modified ...   
				          e.printStackTrace();
				        }                    
				        
				        // next time, we do everything a little bit slower :
				        annealing *= ANNEALING;
				        
				        // if no change has been made and maxChange is smaller than minChange, the thread terminates
				        synchronized (GraphLayout.this) {
				          if (!layoutModified && (maxChange < MINCHANGE))
				            layoutThreadRunning = false;
				        }
				      }
				
				      updateBounds();
				    }
				  }  
				}
							

相关资源