
import javax.swing.*;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.*;


/**
 * @author Remi Forax
 *
 */
public class TreeExample2 {

  static class ClassTreeModel implements TreeModel {

    public ClassTreeModel(Class root) {
      this.root=root;
    }

    public Object getRoot() {
      return root;
    }

    public int getChildCount(Object parent) {
      if (parent instanceof Class) {
        Object[][] children=getChildren((Class)parent);
        
        int size=0;
        for(int i=0;i<children.length;i++)
          size+=children[i].length;
        return size;
        
      } else {
        return 0;
      }
    }

    public boolean isLeaf(Object node) {
      return !(node instanceof Class);
    }

    public void addTreeModelListener(TreeModelListener l) {
    }

    public void removeTreeModelListener(TreeModelListener l) {
    }

    public Object getChild(Object parent, int index) {
      Object[][] children=getChildren((Class)parent);
      
      for(int i=0;i<children.length;i++) {
        int length=children[i].length;
        if (index<length)
          return children[i][index];
        index-=length;
      }
      
      throw new AssertionError("invalid index "+index+" for parent "+parent);
    }

    public int getIndexOfChild(Object parent, Object child) {
      Object[][] children=getChildren((Class)parent);
      
      int size=0;
      for(int i=0;i<children.length;i++) {
        for(int j=0;i<children[i].length;j++,size++) {
          if (children[i][j].equals(child))
            return size;
        }
      }
      
      throw new AssertionError("invalid child "+child+" for parent "+parent);
    }

    public void valueForPathChanged(TreePath path, Object newValue) {
      throw new UnsupportedOperationException();
    }
    
    private static Object[][] getChildren(Class clazz) {
      return new Object[][] {
        clazz.getDeclaredClasses(),
        clazz.getDeclaredConstructors(),
        clazz.getDeclaredMethods(),
        clazz.getDeclaredFields()
      };
    }

    private final Class root;
  }

  public static void main(String[] args) {
    TreeModel model=new ClassTreeModel(TreeExample2.class);
    JTree tree=new JTree(model);
    
    JFrame frame=new JFrame("TreeExample2");
    frame.setContentPane(new JScrollPane(tree));
    frame.pack();
    frame.show();
  }
}
