FileDocCategorySizeDatePackage
Java3dTree.javaAPI DocExample11821Tue Jan 04 18:38:26 GMT 2000com.tornadolabs.j3dtree

Java3dTree.java

/*
//*****************************************************************************
/*
*	@(#) Java3dTree.java
*
*	Project:		Java3dTree
*	Client:		Java 3D Community
*
*	Project Information:
*		dselman@tornadolabs.com
*		http://www.tornadolabs.com
*	
*	@author Daniel Selman: dselman@tornadolabs.com
*/
//*****************************************************************************

// Authors:
// DCS - dselman@tornadolabs.com

// Change History (YYYY/MM/DD). Newest first.
// ==========================================

// [2000/01/04] - DCS - Added detailed reporting for Object (methods and fields)
// [2000/01/04] - DCS - Added detailed reporting for Transform3D
// [2000/01/04] - DCS - Added detailed reporting for Alpha
// [2000/01/04] - DCS - Added detailed reporting for Interpolator

// [1999/12/10] - DCS - Added detailed reporting for ColoringAttributes
// [1999/12/10] - DCS - Added detailed reporting for LineAttributes
// [1999/12/10] - DCS - Added detailed reporting for Material
// [1999/12/10] - DCS - Added detailed reporting for PointAttributes
// [1999/12/10] - DCS - Added detailed reporting for PolygonAttributes
// [1999/12/10] - DCS - Added detailed reporting for RenderingAttributes
// [1999/12/10] - DCS - Added detailed reporting for TexCoordGeneration
// [1999/12/10] - DCS - Added detailed reporting for Texture
// [1999/12/10] - DCS - Added detailed reporting for TransparencyAttributes

// [1999/11/17] - DCS - Added detailed reporting for Behavior.

// [1999/10/25] - DCS - Added detailed reporting for AmbientLight.
// [1999/10/25] - DCS - Added detailed reporting for DirectionalLight.
// [1999/10/25] - DCS - Added detailed reporting for PointLight.
// [1999/10/25] - DCS - Added detailed reporting for SpotLight.	
// [1999/10/25] - DCS - Added detailed reporting for Light.

// [1999/10/23] - DCS - Added expansion of Link Nodes by following SharedGroups.
// [1999/10/23] - DCS - Added reporting of Nodes' parents for non-live scenegraphs.

// [1999/10/10] - DCS - Added detailed reporting for Background Node.
// [1999/10/10] - DCS - Added ability to call updateNodes multiple times.

// [1999/10/09] - DCS - Added check for compiled bit so we don't apply capability changes to compiled objects.
// [1999/10/07] - DCS - Fixed bug in Group so it reports CollisionBounds

package com.tornadolabs.j3dtree;

import java.applet.Applet;
import java.awt.*;
import java.util.*;

import javax.media.j3d.*;
import javax.vecmath.*;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JFrame;

//*****************************************************************************
/**
*	Java3dTree
*
*	Display a Java 3D scenegraph in a Swing Tree control
*
*	@author Daniel Selman
*	@version 1.0
*/
//*****************************************************************************

public class Java3dTree extends JFrame implements TreeSelectionListener
{
	private final String						m_kszLineStyle = "Angled";
	private JEditorPane						m_TextPane = null;
	private JSplitPane						m_SplitPane = null;
	private VirtualUniverse					m_Universe = null;
	private JTree								m_Tree = null;
	private final String						m_kszPackageName = "com.tornadolabs.j3dtree.";
	
	private Hashtable							m_ObjectInfoTable = null;
	
	public Java3dTree()
	{
		super( "Java 3D Scenegraph" );
		buildObjectInfoTable();
   }
	
	private void buildObjectInfoTable()
	{
		m_ObjectInfoTable = new Hashtable( 100 );
				
		addObjectInfoTableItem( "javax.media.j3d.Alpha" );
		addObjectInfoTableItem( "javax.media.j3d.AmbientLight" );
		addObjectInfoTableItem( "javax.media.j3d.Appearance" );
		addObjectInfoTableItem( "javax.media.j3d.Background" );
		addObjectInfoTableItem( "javax.media.j3d.Behavior" );
		addObjectInfoTableItem( "javax.media.j3d.Bounds" );
		addObjectInfoTableItem( "javax.media.j3d.BoundingLeaf" );
		addObjectInfoTableItem( "javax.media.j3d.BranchGroup" );		
		addObjectInfoTableItem( "javax.media.j3d.ColoringAttributes" );
		addObjectInfoTableItem( "javax.media.j3d.Clip" );
		addObjectInfoTableItem( "javax.media.j3d.DirectionalLight" );
		addObjectInfoTableItem( "javax.media.j3d.Fog" );
		addObjectInfoTableItem( "javax.media.j3d.Group" );
		addObjectInfoTableItem( "javax.media.j3d.Interpolator" );
		addObjectInfoTableItem( "javax.media.j3d.Leaf" );
		addObjectInfoTableItem( "javax.media.j3d.Light" );
		addObjectInfoTableItem( "javax.media.j3d.LineAttributes" );
		addObjectInfoTableItem( "javax.media.j3d.Link" );
		addObjectInfoTableItem( "javax.media.j3d.Locale" );
		addObjectInfoTableItem( "javax.media.j3d.Material" );
		addObjectInfoTableItem( "javax.media.j3d.Morph" );
		addObjectInfoTableItem( "javax.media.j3d.OrderedGroup" );
		addObjectInfoTableItem( "javax.media.j3d.PointAttributes" );
		addObjectInfoTableItem( "javax.media.j3d.PointLight" );
		addObjectInfoTableItem( "javax.media.j3d.PolygonAttributes" );
		addObjectInfoTableItem( "com.sun.j3d.utils.geometry.Primitive" );
		addObjectInfoTableItem( "javax.media.j3d.RenderingAttributes" );
		addObjectInfoTableItem( "javax.media.j3d.SceneGraphObject" );
		addObjectInfoTableItem( "javax.media.j3d.Shape3D" );
		addObjectInfoTableItem( "javax.media.j3d.SharedGroup" );
		addObjectInfoTableItem( "com.sun.j3d.utils.universe.SimpleUniverse" );
		addObjectInfoTableItem( "javax.media.j3d.Sound" );
		addObjectInfoTableItem( "javax.media.j3d.Soundscape" );
		addObjectInfoTableItem( "javax.media.j3d.SpotLight" );
		addObjectInfoTableItem( "javax.media.j3d.Switch" );
		addObjectInfoTableItem( "javax.media.j3d.TexCoordGeneration" );
		addObjectInfoTableItem( "javax.media.j3d.Texture" );
		addObjectInfoTableItem( "javax.media.j3d.TextureAttributes" );
		addObjectInfoTableItem( "javax.media.j3d.Transform3D" );
		addObjectInfoTableItem( "javax.media.j3d.TransformGroup" );
		addObjectInfoTableItem( "javax.media.j3d.TransparencyAttributes" );
		addObjectInfoTableItem( "com.sun.j3d.utils.universe.ViewingPlatform" );
		addObjectInfoTableItem( "javax.media.j3d.ViewPlatform" );
		addObjectInfoTableItem( "javax.media.j3d.VirtualUniverse" );
	}
	
	Class getClass( String szClass )
	{
		Class classObject = null;
		
		try
		{
			classObject = Class.forName( szClass );
		}
		catch( Exception e )
		{
			try
			{
				classObject = Class.forName( m_kszPackageName + "ObjectInfo" );
			}
			catch( Exception e2 )
			{
				classObject = null;
			}
		}
		
		return classObject;
	}
	
	public void recursiveApplyCapability( Object obj )
	{
		try
		{
			if( obj != null )
			{			
				ObjectInfo objInfo = getObjectInfo( obj.getClass().getName() );
				
				if( objInfo != null )
					objInfo.setCapabilityBits( this, obj );
			}
			else
				System.err.println( "Warning: ignored null object in recursiveApplyCapability." );
		}
		catch( Exception e )
		{
			System.err.println( "Warning: caught Exception applying capabilities: " + e.toString() );
		}
	}
	
	public void recurseObject( Object obj, DefaultMutableTreeNode parent )
	{
		if( obj != null )
		{
			ObjectInfo objInfo = getObjectInfo( obj.getClass().getName() );
			
			if( objInfo != null )
				objInfo.addToTree( this, parent, obj );
		}
		else
			System.err.println( "Warning: ignored null object in recurseObject." );
	}
	
	ObjectInfo getObjectInfo( String szClass )
	{
		// look it up, maybe we have a direct match...		
		// System.out.println( "Looking up: " + szClass );
		
		ObjectInfo objReturn = (ObjectInfo) m_ObjectInfoTable.get( szClass );
		// System.out.println( "Direct Match: " + szClass );
		
		Class classObject = null;
		
		try
		{
			classObject = Class.forName( szClass );
		}
		catch( Exception e )
		{
		}
		
		Class parentClass = null;
		
		if( classObject != null )
			parentClass = classObject.getSuperclass();
		
		while( objReturn == null && parentClass != null )
		{			
			// if we did not get a match we should walk
			// up the inheritance tree and look for a match on a base classe
			objReturn = (ObjectInfo) m_ObjectInfoTable.get( parentClass.getName() );			
			parentClass = parentClass.getSuperclass();
			
			// System.out.println( "Parent Class: " + parentClass );
		}
		
		// System.out.println( "Returning: " + objReturn );
		
		return objReturn;
	}
	
	private void addObjectInfoTableItem( String szClass )
	{
		// strip the package name from szClass (everything before the final ".")
		int nIndex = szClass.lastIndexOf( "." );
		
		String szTrimedClass = szClass;
		
		if( nIndex > -1 )
			szTrimedClass = szClass.substring( nIndex+1, szClass.length() );
		
		szTrimedClass = m_kszPackageName + szTrimedClass;
		szTrimedClass += "_Info";
		
		// System.out.println( szClass + "-->" + szTrimedClass );
		
		Class classObject = getClass( szTrimedClass );
		
		try
		{
			if( classObject != null )
			{
				m_ObjectInfoTable.put( szClass, classObject.newInstance() );
				return;
			}
		}
		catch( Exception e )
		{
			System.err.println( e.toString() );
		}

		System.err.println( "Unable to create a new instance of info class for: " + szClass );
	}
	
	public void valueChanged(TreeSelectionEvent e)
	{
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) m_Tree.getLastSelectedPathComponent();
		
		if (node == null) 
			return;
		
		Object sceneGraphObject = node.getUserObject();
		
		// get the _Info object for the node type
		ObjectInfo objInfo = getObjectInfo( sceneGraphObject.getClass().getName() );
		
		try
		{
			if( objInfo != null )
			{
				String szText = objInfo.getInfo( sceneGraphObject );
				// System.out.println( szText );
				displayText( szText );
			}
			else
				displayText( "No Info Handler for:" + sceneGraphObject );
		}
		catch( Exception ex )
		{
			displayText( ex.toString() );
		}
	}

	private void displayText( String szText ) 
	{
		m_TextPane.setText( szText );
	}

	public void updateNodes( VirtualUniverse universe )
	{
		m_Universe = universe;
		
		//Create the top level parent node.
		DefaultMutableTreeNode top = new DefaultMutableTreeNode( "Scenegraph" );
		
		recurseObject( m_Universe, top );
		
		//Create a tree that allows one selection at a time.
		m_Tree = new JTree(top);
		m_Tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
		
		//Listen for when the selection changes.
		m_Tree.addTreeSelectionListener( this );

		//Create the scroll pane and add the tree to it. 
		JScrollPane treeView = new JScrollPane(m_Tree);
		Dimension minimumSize = new Dimension(100, 50);
		treeView.setMinimumSize(minimumSize);
				
		//Add the scroll panes to a split pane.
		if( m_SplitPane == null )
		{
			//Create the viewing pane.
			m_TextPane = new JEditorPane();
			m_TextPane.setEditable(false);
			JScrollPane htmlView = new JScrollPane(m_TextPane);

			m_SplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
			
			m_SplitPane.setTopComponent(treeView);
			m_SplitPane.setBottomComponent(htmlView);
		
			htmlView.setMinimumSize(minimumSize);
			m_SplitPane.setDividerLocation(100);
		
			m_SplitPane.setPreferredSize(new Dimension(500, 300));
		
			//Add the split pane to this frame.
			getContentPane().add( m_SplitPane, BorderLayout.CENTER);
			
			pack();
			setVisible( true );
		}
		else
			m_SplitPane.setTopComponent(treeView);
	}
}