Allows the user to reflectively inspect an object hierarchy : SuperClass « Reflection « Java

Home
Java
1.2D Graphics GUI
2.3D
3.Advanced Graphics
4.Ant
5.Apache Common
6.Chart
7.Class
8.Collections Data Structure
9.Data Type
10.Database SQL JDBC
11.Design Pattern
12.Development Class
13.EJB3
14.Email
15.Event
16.File Input Output
17.Game
18.Generics
19.GWT
20.Hibernate
21.I18N
22.J2EE
23.J2ME
24.JDK 6
25.JNDI LDAP
26.JPA
27.JSP
28.JSTL
29.Language Basics
30.Network Protocol
31.PDF RTF
32.Reflection
33.Regular Expressions
34.Scripting
35.Security
36.Servlets
37.Spring
38.Swing Components
39.Swing JFC
40.SWT JFace Eclipse
41.Threads
42.Tiny Application
43.Velocity
44.Web Services SOA
45.XML
Java » Reflection » SuperClassScreenshots 
Allows the user to reflectively inspect an object hierarchy
        
//package com.ryanm.util.swing;

import java.awt.event.MouseEvent;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedList;

import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;

/**
 * Allows the user to reflectively inspect an object hierarchy
 
 @author ryanm
 */
public class ObjectInspector extends JTree
{
  private boolean showInaccessibleFields = true;

  private boolean showStaticFields = true;

  private ObjectNode treeRoot = new ObjectNodenull, true );

  private DefaultTreeModel treeModel = new DefaultTreeModeltreeRoot );

  private TreeWillExpandListener expansionListener = new TreeWillExpandListener() {

    @Override
    public void treeWillCollapseTreeExpansionEvent event throws ExpandVetoException
    {
      Object obj = event.getPath().getLastPathComponent();

      ifobj instanceof ObjectNode )
      {
        ObjectNode on = ObjectNode obj;
        assert !on.root;

        on.expanded = false;

        on.refreshValueon.inspectedObject );
      }
    }

    @Override
    public void treeWillExpandTreeExpansionEvent event throws ExpandVetoException
    {
      Object obj = event.getPath().getLastPathComponent();

      ifobj instanceof ObjectNode )
      {
        ObjectNode on = ObjectNode obj;
        on.expanded = true;

        on.buildChildren();

        on.refreshTreeon.inspectedObject );

        treeModel.reloadon );
      }
    }

  };

  /**
   * Builds a new {@link ObjectInspector}
   
   @param o
   *           The object to inspect
   @param showInaccessible
   *           <code>true</code> to display inaccessible fields in
   *           the tree, <code>false</code> to hide them
   @param showStatic
   *           <code>true</code> to show static fields,
   *           <code>false</code> to hide them
   */
  public ObjectInspectorObject o, boolean showInaccessible, boolean showStatic )
  {
    setModeltreeModel );

    showInaccessibleFields = showInaccessible;
    showStaticFields = showStatic;

    setEditablefalse );
    addTreeWillExpandListenerexpansionListener );

    treeRoot.refreshTree);

    ToolTipManager.sharedInstance().registerComponentthis );
  }

  /**
   * Inspects an object
   
   @param o
   *           The object to inspect
   */
  public void inspectObject o )
  {
    treeRoot.refreshTree);
  }

  @Override
  public String getToolTipTextMouseEvent me )
  {
    TreePath pathForLocation = getPathForLocationme.getX(), me.getY() );

    ifpathForLocation != null )
    {
      Object lastPathComponent = pathForLocation.getLastPathComponent();
      iflastPathComponent instanceof ObjectNode )
      {
        ObjectNode on = ObjectNode lastPathComponent;

        return on.tooltip;
      }
    }

    return null;
  }

  private class ObjectNode extends DefaultMutableTreeNode
  {
    private Object inspectedObject = null;

    private Field inspectedField = null;

    private final boolean root;

    private final boolean accessible;

    private final boolean primitive;

    private boolean array = false;

    private boolean childrenBuilt = false;

    private TreePath path;

    private final DefaultMutableTreeNode dummyNode = new DefaultMutableTreeNode"Inspecting..." );

    private String tooltip;

    private boolean expanded = false;

    private ObjectNodeObject inspectedObject, boolean root )
    {
      this.root = root;

      this.inspectedObject = inspectedObject;

      accessible = true;
      primitive = false;

      ifroot )
      {
        buildChildren();
        expanded = true;
      }
    }

    private ObjectNodeField inspectedField )
    {
      root = false;

      setUserObjectinspectedField.getType().getSimpleName() " : " + inspectedField.getName() );

      this.inspectedField = inspectedField;

      primitive = inspectedField.getType().isPrimitive();

      boolean a = false;
      try
      {
        inspectedField.setAccessibletrue );
        a = true;
      }
      catchSecurityException se )
      {
        a = false;
      }

      accessible = a;

      if!primitive && accessible )
      {
        insertdummyNode, );
      }

      if!accessible )
      {
        setUserObjectinspectedField.getName() " : Inaccessible" );
      }

      tooltip = inspectedField.getType().toString();
    }

    private void refreshTreeObject o )
    {
      ifobjectTypeChanged) )
      {
        /*
         * the object class has changed, we need to change the
         * tree
         */
        removeAllChildren();
        childrenBuilt = false;

        inspectedObject = o;

        ifinspectedObject != null )
        {

          array = o.getClass().isArray();

          if!primitive && accessible )
          {
            insertdummyNode, getChildCount() );
          }

          ifexpanded )
          {
            buildChildren();
          }
        }
        else
        {
          childrenBuilt = true;
        }

        treeModel.nodeStructureChangedthis );
      }
      else ifarray )
      // need to check if the array length has changed
        int oldCount = getChildCount();
        int desiredCount = Array.getLength);

        // may need to add or remove children
        whilegetChildCount() < desiredCount )
        {
          ObjectNode on = new ObjectNodenull, false );

          inserton, getChildCount() );
        }

        whilegetChildCount() > desiredCount )
        {
          removegetChildCount() );
        }

        ifoldCount != desiredCount )
        {
          treeModel.nodeStructureChangedthis );
        }

        assert getChildCount() == desiredCount;
      }

      inspectedObject = o;

      if!root && getChildCount() == )
      {
        expanded = false;
      }

      ifexpanded && getChildCount() )
      {
        int index = 0;

        forObject child : children )
        {
          assert child != dummyNode;

          ObjectNode on = ObjectNode child;

          ifarray )
          {
            on.refreshTreeArray.getinspectedObject, index ) );
          }
          else ifon.accessible )
          {
            try
            {
              on.refreshTreeon.inspectedField.getinspectedObject ) );
            }
            catchIllegalArgumentException e )
            {
              e.printStackTrace();
            }
            catchIllegalAccessException e )
            {
              e.printStackTrace();
            }
          }

          index++;
        }
      }

      refreshValue);
    }

    /**
     * Updates the value of this node
     
     @param o
     */
    private void refreshValueObject o )
    {
      StringBuilder buff = new StringBuilder();

      ifinspectedField != null )
      {
        buff.appendinspectedField.getName() );
        buff.append" : " );
        buff.appendinspectedField.getType().getSimpleName() );
      }
      else
      {
        assert inspectedField == null;

        ifo != null )
        {
          buff.appendo.getClass().getSimpleName() );
        }
        else
        {
          buff.append"null" );
        }
      }

      ifprimitive )
      {
        buff.append" : " );
        buff.append);
      }
      else if!expanded )
      {
        buff.append" : " );
        buff.appendbuildString) );
      }

      setUserObjectbuff.toString() );

      ifpath != null )
      {
        path = new TreePathgetPath() );
      }

      ifpath == null )
      {
        path = new TreePathgetPath() );
      }

      treeModel.valueForPathChangedpath, getUserObject() );

      ifo != null )
      {
        if!primitive )
        {
          tooltip = o.getClass().getName();
        }
        else
        {
          tooltip = inspectedField.getType().getName();
        }
      }
      else
      {
        tooltip = "null";
      }
    }

    /**
     * Determines if the object type has changed
     
     @param o
     *           the new object
     @return <code>true</code> if the tree needs to be changed,
     *         false otherwise
     */
    private boolean objectTypeChangedObject o )
    {
      ifinspectedObject == null && o == null )
      {
        return false;
      }
      else ifinspectedObject == null != o == null ) )
      {
        return true;
      }
      else ifinspectedObject != null && o != null
          && !inspectedObject.getClass().equalso.getClass() ) )
      {
        return true;
      }

      return false;
    }

    private void buildChildren()
    {
      if!childrenBuilt )
      {
        ifchildren != null && children.containsdummyNode ) )
        {
          removedummyNode );
        }

        ifinspectedObject != null )
        {
          ifarray )
          {
            forint i = 0; i < Array.getLengthinspectedObject ); i++ )
            {
              ObjectNode on = new ObjectNodeinspectedObject, false );

              inserton, getChildCount() );
            }
          }
          else
          {
            Collection<Field> fields = new LinkedList<Field>();

            getFieldsfields, inspectedObject.getClass() );

            forField f : fields )
            {
              ObjectNode on = new ObjectNode);

              if( ( showInaccessibleFields || on.accessible )
                  && showStaticFields || !Modifier.isStaticf.getModifiers() ) ) )
              {
                inserton, getChildCount() );
              }
            }
          }

          treeModel.nodeStructureChangedthis );
        }
        else
        {
          setUserObject"null" );
        }

        childrenBuilt = true;
      }
    }

  }

  /**
   * Recurses up the inheritance chain and collects all the fields
   
   @param fields
   *           The collection of fields found so far
   @param c
   *           The class to get fields from
   */
  private static void getFieldsCollection<Field> fields, Class )
  {
    forField f : c.getDeclaredFields() )
    {
      fields.add);
    }

    ifc.getSuperclass() != null )
    {
      getFieldsfields, c.getSuperclass() );
    }
  }

  /**
   * Attempts to build a nicer looking string than the basic
   {@link Object}.toString()
   
   @param o
   *           The object to build from
   @return A descriptive string
   */
  private static String buildStringObject o )
  {
    ifo == null )
    {
      return "null";
    }

    // first see if there is a version of toString more specific
    // than that supplied by Object...
    try
    {
      Method m = o.getClass().getMethod"toString" );

      if!m.getDeclaringClass().equalsObject.class ) )
      {
        return o.toString();
      }
    }
    catchSecurityException e )
    {
    }
    catchNoSuchMethodException e )
    {
    }

    // then see if it is an array...
    ifo.getClass().isArray() )
    {
      StringBuilder buff = new StringBuilder" [ " );

      forint i = 0; i < Array.getLength); i++ )
      {
        /*
         * this could recurse infinitely, but only if the user is
         * trying to be malicious, like so - Object[] array = new
         * Object[ 1 ]; array[ 0 ] = array; - which, I'm sure
         * we'll agree, is and odd thing to do. I say let the
         * StackOverflowException catch it.
         */

        buff.appendbuildStringArray.geto, i ) ) );
        buff.append", " );
      }

      ifArray.getLength)
      {
        buff.deletebuff.length() 2, buff.length() );
      }

      buff.append" ]" );

      return buff.toString();
    }

    return getObjectPosition);
  }

  /**
   * Returns a String of an object's position in memory
   
   @param o
   @return The object's memory position
   */
  private static String getObjectPositionObject o )
  {
    String s = o.toString();
    s = s.substrings.lastIndexOf"@" ) );
    return s;
  }
}

   
    
    
    
    
    
    
    
  
Related examples in the same category
1.Getting the Superclass of an Object
2.Superclass of Object is null
3.The superclass of primitive types is always null
4.Although the type of o2 is an interface, getSuperclass() returns the object's superclass
5.Retrieving other information through the class pointer
6.Return true if class a is either equivalent to class b, or if class a is a subclass of class b, i.e. if a either "extends" or "implements" b.
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.