import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class Table extends Frame
{
    /**
     * Instantiate a Table object
     */
    public static void main(String args[])
    {
        new Table();
    }

    /**
     * The Table constructor sets the frame's size, adds the
     * visual components, and then makes the visible to the user.
     *
     * We place a Canvas3D object into the frame so that Java 3D 
     * has the heavy weight component it needs to render 3D
     * Graphics into. We the call methods to construct the view
     * and content branches of iour scene graph.
    */
    public Table()
    {
        super("Java 3D Table"); // Frame title
        setSize(400,300); // set theframe size

        // Here is our first Java 3D-specific code. We add a
        // Canvas3D to our frame so that we can render our 3D
        // graphics. Java 3D requires a heavy weight component
        // Canvas3D into which to render.
        GraphicsConfiguration grconfig =
                SimpleUniverse.getPreferredConfiguration();
        Canvas3D the3DCanvas = new Canvas3D(grconfig);
        add("Center",the3DCanvas);

        setVisible(true); // turn on the visibility of the frame.

        // We want to be sure we properly dispose of resources
        // this frame is using when the window is closed. We use
        // an anonymous inner class adapter for this.
        addWindowListener(new WindowAdapter()
          { public void windowClosing(WindowEvent e)
            { dispose(); System.exit(0);}
          }
        );

        //Start  building scene
        View theView = constructView(the3DCanvas);
        Locale theLocale = constructViewBranch(theView);
        constructContentBranch(theLocale);
    }

    /**
     * constructView() takes a Canvas3D referenec and constructs
     * a View to display in that Canvas3D. It uses the default
     * PhysicalBody and PhysicalEnvironment (both required to be set
     * or else the 3D runtime will throw exception). The returned
     * View is used by constructViewBranch() to attach the scene
     * graph's ViewPlatform to Canvas3D for rendering.
     *
     * @see constructViewBranch(view)
     */
     private View constructView(Canvas3D mycan3D)
     {
        View myView = new View();
        myView.addCanvas3D(mycan3D);
        myView.setPhysicalBody(new PhysicalBody());
        myView.setPhysicalEnvironment(new PhysicalEnvironment());
        return (myView);
     }

     /**
      * constructViewBranch() takes as input a view which we
      * attached to our Canvas3D in constructView(). It constructs
      * a default view branch for the scene raph, attaches
      * the view to the viewPlatform, and returns a reference to
      * our locale for use by the constructContentBranch()
      * in creating content for our scene graph.
      *
      * @see constructView(Canvas3D)
      * @see constructContentBranch(Locale)
     **/
     private Locale constructViewBranch(View myView)
     {
        // First we create the necessary coordinate systems
        // (VirtualUniverse, Locale, container nodes
        // (BranchGroup, TransformGroup, and platform which
        // determines our viewing position and direction        // (ViewPlatform).
        VirtualUniverse myUniverse = new VirtualUniverse();
        Locale myLocale = new Locale(myUniverse);
        BranchGroup myBranchGroup = new BranchGroup();
        TransformGroup myTransformGroup = new TransformGroup();
        ViewPlatform myViewPlatform = new ViewPlatform();

        // Next we insert the platform into the transform group,
        // the transform group into the branch group, and the branch
        // group into the Locale's branch graph portion of the 
        // scene graph.
        myTransformGroup.addChild(myViewPlatform);
        myBranchGroup.addChild(myTransformGroup);
        myLocale.addBranchGraph(myBranchGroup);

        // Finally we attach our view to the view platform and we
        // return a reference to our view universe. We are ready to
        // render 3D content.
        myView.attachViewPlatform(myViewPlatform);
        return (myLocale);
     }

     /**
      * constructContentBranch() is where we specify the 3D graphics
      * content to be rendered into the Locale referenced
      * in the passed parameter.  
     **/

     private void constructContentBranch(Locale myLocale)
     {

        // Define some colors
        Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
        Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
        Color3f blue = new Color3f(0.0f, 1.0f, 0.0f);
        Color3f green = new Color3f(0.0f, 0.0f, 1.0f);
        Color3f black = new Color3f(0.0f,  0.0f, 0.0f);

        // Insert content to be rendered here.
        Shape3D table = new Shape3D();
        int stripCounts[] = {10};
        TriangleStripArray tableGeom = new TriangleStripArray(10,
        GeometryArray.COORDINATES, stripCounts);
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.0f, -1.0f));
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.2f, -1.0f));
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.0f,  1.0f));
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.2f,  1.0f));
        tableGeom.setCoordinate(0, new Point3f( 1.0f, 0.0f,  1.0f));
        tableGeom.setCoordinate(0, new Point3f( 1.0f, 0.2f,  1.0f));
        tableGeom.setCoordinate(0, new Point3f( 1.0f, 0.0f, -1.0f));
        tableGeom.setCoordinate(0, new Point3f( 1.0f, 0.2f, -1.0f));
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.0f, -1.0f));
        tableGeom.setCoordinate(0, new Point3f(-1.0f, 0.2f, -1.0f));

        table.setGeometry(tableGeom);
        table.setAppearance(createMaterialAppearance(white));

        // We created a new branch group and transform group to hold
        // our content. this time when we create the transform group,
        // however, we pass in a transform3D to the transform group's
        // constructor. This 3D transform has been manipulated to
        // perform the transformation we desire, which results in these
        // manipulations being carried out on all children of the given
        // transform group, in this case, our content.
        BranchGroup contentBranchGroup = new BranchGroup();
        Transform3D myTransform3D = new Transform3D();

        myTransform3D.setTranslation(new Vector3f(-1.0f, 0.0f,-4.05f));	
        myTransform3D.setScale(0.1);
Transform3D tempTransform3D = new Transform3D();
tempTransform3D.rotY(Math.PI/4.0d);
myTransform3D.mul(tempTransform3D);

        TransformGroup contentTransformGroup = new    TransformGroup(myTransform3D);
        // We add our child nodes and insert the branch group into
        // the live scene graph. This results in Java 3D rendering
        // the content.
        contentTransformGroup.addChild(table);
        contentBranchGroup.addChild(contentTransformGroup);
        myLocale.addBranchGraph(contentBranchGroup);
     }

     Appearance createMaterialAppearance(Color3f color)
     {
        Appearance appear = new Appearance();
        Material material = new Material();
        material.setDiffuseColor(color);
        material.setShininess(50.0f);
        appear.setMaterial(material);
        return appear;
     }
}