classtreenode.java

来自「Semantic Web Ontology Editor」· Java 代码 · 共 446 行

JAVA
446
字号
package org.mindswap.swoop.utils.graph.hierarchy;

import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.net.URI;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

import org.mindswap.swoop.SwoopModel;
import org.mindswap.swoop.utils.graph.hierarchy.colors.GraphColorScheme;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLException;


/*
 * Created on Jul 15, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author Dave Wang
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ClassTreeNode 
{	
	class DescendingClassTreeNodeComparator implements Comparator
	{
		public int compare(Object o1, Object o2)
		{
			ClassTreeNode t1 = (ClassTreeNode)o1;
			ClassTreeNode t2 = (ClassTreeNode)o2;
			int t1_size = t1.getSubTreeSize();
			int t2_size = t2.getSubTreeSize();
			if ( t1_size > t2_size)
				return -1;
			else if (t1_size == t2_size)
				return 0;
			else
				return 1;			
		}
		
		public boolean equals(Object o2)
		{
			return false;
		}
	}
	
	public static final int UNASSIGNED_SIZE = -1423;
	
	private URI myURI;
	private ClassTreeNode myParent = null;
	private Vector myChildren = new Vector();
	
	private int mySubTreeSize = UNASSIGNED_SIZE;
	private TreeNodeSizeInfo myChildNodeSizeInfo = null;
	
	private double localX = -1;
	private double localY = -1;
	
	private double globalX = -1;
	private double globalY = -1; 
	
	private double myRotationAngle = 0;
	
	private boolean isSelected = false;    // whether selected by user via mouse
	private boolean isHighlighted = false; // whether highlighted via search
	private boolean isListBrowsed = false; // whether viewed by user via list
	private boolean isOverlayed   = false; // whether this class node is overlayed
	private boolean hasRelations  = false; // whether related to other classes via some restrictions  
	
	private SwoopModel myModel = null;
	private OntologyGraphNode myOntologyGraphNode = null; // init in sortChildren(....)
	private GraphColorScheme myColorScheme = null;        // init in sortChildren(....)
	
	private AffineTransform myLocalXForm;
	private AffineTransform myGlobalXform;
	
	private int myDepth = 0;
	private int mySubtreeDepth = 0;
	
	public ClassTreeNode(SwoopModel model, URI uri, int depth )
	{
		myURI   = uri;
		myModel = model;		
		myDepth = depth;
		// myOntologyNode, myColorSchem are set by 
		// call to sortChildren by OntologyGraphNode constructor
	}
	
	public int getNumChildren()
	{ return myChildren.size(); }
	
	public int getDepth()
	{ return myDepth; }
	
	public int getSubtreeDepth()
	{ return mySubtreeDepth; }
	public void setSubtreeDepth( int subtreeDepth )
	{ mySubtreeDepth = subtreeDepth; }
	
	public OWLClass getOWLClass()
	{
		try
		{
			return myOntologyGraphNode.getOntology().getClass( myURI);
		}
		catch( OWLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	
	public ClassTreeNode getChild(int index)
	{
		if ( (index < 0) || (index > (myChildren.size() -1) ) )
			return null;
		
		return (ClassTreeNode)myChildren.elementAt( index );
	}
	
	public ClassTreeNode addChild( ClassTreeNode node )
	{
		node.setParent( this );
		myChildren.add( node );
		return node;
	}
	
	public void setParent( ClassTreeNode parent )
	{ myParent = parent; }
	
	public void removeChild( ClassTreeNode node)
	{
		myChildren.remove( node );
	}
	
	public ClassTreeNode findNode( String id )
	{
		for (int i = 0; i < myChildren.size(); i++)
		{
			ClassTreeNode node = (ClassTreeNode)myChildren.elementAt(i);
			if (node.getURI().toString().equals(id))
				return node;
		}
		return null;
	}
	
	// returns size of subtree rooted at THIS node.  Includes itself
	public int getSubTreeSize()
	{
		// if already assigned, return that value
		if (mySubTreeSize != UNASSIGNED_SIZE)
			return mySubTreeSize;
		
		// leaf case
		if ( myChildren.size() == 0 )
		{
			mySubTreeSize = 1;
			return mySubTreeSize;
		}
		
		int size = 0;
		for (int i = 0; i < myChildren.size(); i ++)
		{
			ClassTreeNode node = (ClassTreeNode)myChildren.elementAt( i );
			size = size + node.getSubTreeSize();
		}
		
		mySubTreeSize = size + 1;
		return mySubTreeSize;
	}
	
	
	public TreeNodeSizeInfo getChildNodeSizeInfo()
	{
		if (myChildNodeSizeInfo != null )
			return myChildNodeSizeInfo;
		
		int numChildren = this.getNumChildren();
		if (numChildren == 0)
		{
			myChildNodeSizeInfo = TreeNodeSizeInfo.getNullInfo();
			return myChildNodeSizeInfo;
		}
		int maxChildRadius = Integer.MIN_VALUE;
		ClassTreeNode largestNode = null;
		boolean isFirstTime = true;
		boolean areSameSize = true;
		boolean isFirstChildLarge = false;
		for (int i = 0; i < numChildren; i++ )
		{
			ClassTreeNode child = this.getChild( i );
			if ( i == 0 ) //largest node
			{
				if ( (2 * child.getRadius()) > (this.getRadius() * 0.75) )
					isFirstChildLarge = true;
			}
			int childsize = child.getRadius();
			if ((!isFirstTime) && ( maxChildRadius != childsize))
				areSameSize = false;
			if ( maxChildRadius < childsize)
			{
				maxChildRadius = childsize;
				largestNode = child;
			}
			if ( isFirstTime )
				isFirstTime = !isFirstTime;
		}
		TreeNodeSizeInfo info = new TreeNodeSizeInfo();
		info.areSameSize = areSameSize;
		info.maxRadius = maxChildRadius;
		info.myLargestNode = largestNode;
		info.isFirstChildBig = isFirstChildLarge;
		
		myChildNodeSizeInfo = info;
		return myChildNodeSizeInfo;
	}
	
	
	public int getRadius()
	{ return getSubTreeSize() * SizeConstants.unitSize; }
	
	public URI getURI()
	{ return myURI; }
	
	public ClassTreeNode getParent()
	{ return myParent; }
	
	public Vector getChildren()
	{ return myChildren; }
	
	// guarantees for the current Colorscheme
	public GraphColorScheme getColorScheme()
	{ return myOntologyGraphNode.getColorScheme(); }
	public Color getFillColor()
	{ return myOntologyGraphNode.getColorScheme().getTreeNodeFillColor( this ); }
	public Color getOutlineColor()
	{ return myOntologyGraphNode.getColorScheme().getTreeNodeOutlineColor( this ); }
	
	// sets the center for this treenode.  It is local coordinate (from its parent's center)
	public void setLocalCenterPoint( double newx, double newy)
	{
		ClassTreeNode parentNode = this.getParent();
		// this node is root, so set global = center = (newx, newy)
		if ( parentNode == null )
		{
			this.localX  = newx;
			this.localY  = newy;
			return;
		}
		localX = newx;
		localY = newy;
	}

	public Point2D.Double getLocalCenter()
	{ return new Point2D.Double(this.localX, this.localY);	}
	
	public Point2D.Double computeGlobalCenter()
	{
		Point2D point = new Point2D.Double(0,0);
		Point2D.Double destPoint = new Point2D.Double();
		destPoint = (Point2D.Double)myGlobalXform.transform( point, destPoint );
		return destPoint;
	}
	public Point2D.Double getGlobalCenter()
	{ return new Point2D.Double( globalX, globalY); }
	
	
	public double getLocalX()
	{ return this.localX; }
	public double getLocalY()
	{ return this.localY; }
	public double getGlobalX()
	{ return this.globalX; }
	public double getGlobalY()
	{ return this.globalY; }
	
	// in radians
	public double getRotationAngle()
	{ return myRotationAngle; }	
	public void setRotationAngle( double angle)
	{ myRotationAngle = angle; }
	
	public void setLocalXForm( AffineTransform form )
	{ myLocalXForm = form; }
	public AffineTransform getLocalXForm()
	{ return myLocalXForm; }
	
	// set global transform (which transforms (0,0) to this node's center)
	//  and also set the global center
	public void setGlobalTransform( AffineTransform form )
	{ 
		myGlobalXform = form;
		Point2D gPoint = computeGlobalCenter();
		globalX = gPoint.getX();
		globalY = gPoint.getY();
	}
	
	
	
	// recursively sorts current tree node's child by (subtree)size ( largest first )
	// invoked by constructor of OntologyGraphNode.  myOntologyGraphNode is guaranteed
	// to set.  myColorScheme is guaranteed to set.
	public void sortChildren( OntologyGraphNode motherNode)
	{
		motherNode.indexNode( this.getURI(), this );
		Collections.sort( myChildren, new DescendingClassTreeNodeComparator());
		myOntologyGraphNode = motherNode;
		myColorScheme       = myOntologyGraphNode.getColorScheme();

		for (int i = 0; i < getNumChildren(); i++)
		{
			ClassTreeNode child = getChild(i);
			child.sortChildren( motherNode );
		}
	}
	
	public OntologyGraphNode getOntologyNode()
	{ return myOntologyGraphNode; }
	
	public boolean getIsSelected()
	{ return isSelected; }
	public void setIsSelected( boolean flag )
	{ isSelected = flag; }

	public boolean getIsHighlighted()
	{ return isHighlighted; }
	public void setIsHighlighted( boolean flag )
	{ isHighlighted = flag; }
	
	public boolean getIsListBrowsed()
	{ return isListBrowsed; }
	public void setIsListBrowsed( boolean flag )
	{ isListBrowsed = flag; }
	
	public boolean gethasRelations()
	{ return hasRelations; }
	public void sethasRelations( boolean flag)
	{ hasRelations = flag; }

	public boolean getIsOverlayed()
	{ return isOverlayed; }
	public void setIsOverlayed( boolean flag)
	{ isOverlayed = flag; }
	
	/* 
	 * 
	 * Returns the node that's selected by the point passed in.
	 *   If this node is selected, then it recursively finds if any child is selected (more
	 *   precisely selected node).
	 *      If true, then that child is returned
	 * 		else this node is returned
	 * 
	 * Invoked by GraphMouseImpl in TestVisualizationViewer
	 */	
	public ClassTreeNode getSelectedChild( Point2D p)
	{
		ClassTreeNode selectedNode = null;
		Point2D.Double myCenter = this.getLocalCenter();
		// find xform that translate p to local space
		AffineTransform xform = AffineTransform.getTranslateInstance( -myCenter.x, -myCenter.y );
		Point2D localPoint = null;
		localPoint = xform.transform( p, localPoint );
		
		for (int i  = 0; i < getNumChildren(); i++)
		{
			ClassTreeNode child = getChild( i );
			ClassTreeNode selectedChild = child.getSelectedNode( localPoint );
			if (selectedChild != null)
				selectedNode = selectedChild;
		}
		return selectedNode;
	}
	
	//
	// localPoint is in the same local space as this node
	// however, it has not been rotated correctly, since this node's parent may have rotated
	//
	public ClassTreeNode getSelectedNode( Point2D localPoint )
	{
		ClassTreeNode selectedNode = null;

		if ( isWithinMe( localPoint ) )
		{
			selectedNode = this;   // set return value to self.
			Point2D result= null;
			AffineTransform xform = null;
			
			try
			{
				xform = myLocalXForm.createInverse();
			}
			catch( Exception e)
			{ e.printStackTrace(); }
			
			Point2D newLocal = null;
			newLocal = xform.transform( localPoint, newLocal );
			
			for (int i  = 0; i < getNumChildren(); i++)
			{
				ClassTreeNode child = getChild( i );
				ClassTreeNode selectedChild = child.getSelectedNode( newLocal );
				if (selectedChild != null)
					selectedNode = selectedChild;
			}
		}
		return selectedNode;
	}
	
	//
	// point p is in local space, same space as this node's parent
	//
	private boolean isWithinMe( Point2D p )
	{
		if (Math.sqrt( (Math.pow(p.getX() - this.localX , 2)  ) +
				        Math.pow(p.getY() - this.localY , 2)  ) <= this.getRadius())
			return true;
		return false;
	}

	public String toString()
	{ return myModel.shortForm( this.getURI() ); }
	
	// differs from toString() in that this method only returns
	//   the name of the class (no qnames when qname toggle is on in swoop)
	public String getName()
	{
		String name = myModel.shortForm( this.getURI() );
		int index = name.indexOf(":");
		if (index == -1)
			return name;
		else
			return name.substring( index );
	}
}



⌨️ 快捷键说明

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