Scenegraph TreeModel

This can help you inspect your scenegraph. It doesn't respond to scenegraph changes and is really only a 5 minute job for anybody with some swing experience, but since a lot of people won't touch swing with a ten foot pole I thought I might post it to help those infidels ;).

Enjoy!


import com.jme.animation.SpatialTransformer;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Box;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;

/**
 * shows SceneElements and their Controllers
 */
public class JMETreeModel implements TreeModel{
    Node rootNode;
    ArrayList<TreeModelListener> listeners;
   
    public JMETreeModel(com.jme.scene.Node root){
        listeners = new ArrayList<TreeModelListener>();
        rootNode = root;
    }
   
    public boolean isLeaf(Object node) {
        return (getChildCount(node) < 1);
    }

    public int getChildCount(Object parent) {
        if(!(parent instanceof Node)){
            return 0;
        }else{
            int controllers = ((Spatial)parent).getControllers().size();
            int childs = 0;
            if(((Node) parent).getChildren() != null){
                childs = ((Node) parent).getChildren().size();
            }
            return controllers + childs;
        }
    }

    public void valueForPathChanged(javax.swing.tree.TreePath path, Object newValue) {
        //not supported
    }

    public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
        listeners.remove(l);
    }

    public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
        listeners.add(l);
    }

    public Object getChild(Object parent, int index) {
        Node jn = (Node) parent;
        if(index < jn.getChildren().size())
            return jn.getChild(index);
        else
            return jn.getController(index-jn.getChildren().size());
    }

    public Object getRoot() {
        return rootNode;
    }

    public int getIndexOfChild(Object parent, Object child) {
        Node jn = (Node) parent;
        ArrayList al = jn.getChildren();
        int childs = al.size();
        for(int i=0; i< childs; i++){
            if(al.get(i) == child)
                return i;
        }
        al = ((Spatial)parent).getControllers();
        for(int i=0; i< al.size(); i++){
            if(al.get(i) == child)
                return i+childs;
        }
        return -1;
    }
  
    public static void showScenegraph(Node rootNode){
        JFrame f = new JFrame();
        JTree tree = new JTree(new JMETreeModel(rootNode));
        f.getContentPane().add(new JScrollPane(tree));
        f.pack();
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }
   
    //example usage
    public static void main(String[] args){
        //set up a fake scene
        Node root = new Node("root");
        root.attachChild(new Node("child1"));
        Node child2= new Node("child2");
        child2.attachChild(new Box("box", Vector3f.ZERO, 1, 1, 1));
        root.attachChild(child2);
        root.addController(new SpatialTransformer());
       
        TriMesh m = (TriMesh) root.getChild(0);
       
        //now display it all
        JMETreeModel.showScenegraph(root);
    }
}



Usage:

JMETreeModel.showScenegraph(rootNode);

Cool, I was just thinking how people might benefit from something like this, especially for seeing their models.

Also interested i did that in system output for Java3D, cool to have something better for jME lol 

I'll give it a try tomorrow.