⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphlayout.java

📁 Java 3D Desktop Environment旨在使用Java 3D来创建一个3D桌面环境。功能包括:分布式的应用程序
💻 JAVA
字号:
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<elements.size(); 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();
    }
  }  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -