An Annotated Description of CylinderExam.java file http://king.npac.syr.edu:2006/src/hasan/Vrml/EAI/Cylinder/docs/

We add the applet to the frame on left hand side with the following way:

<applet name="Control" code="CylinderExam.class" mayscript width="150" height="200">
</applet>

Let's look at the CylinderExam.java file. First we need to include some Java AWT classes to prepare the user interface.

//** Necessary JAVA Classes
import java.awt.*;
import java.applet.*;
import java.util.*;
You need to import the following classes into your java file to use External Authoring Interface (EAI).
//** Apperantly we need External Authoring Interface classes
import vrml.external.Node;
import vrml.external.Browser;
import vrml.external.field.*;
import vrml.external.exception.*;
We need LiveConnect technology to get the handle of the Browser object. With the recent release of EAI we can use Browser.getBrowser() to get the VRML Browser's handle. Then we do not need LiveConnect technology and it will work without any problem on the Internet Explorer(IE) also.
//** We need LiveConnect Support
import netscape.javascript.JSObject;
We extend the object from Applet as usual. We do not need to say that this object implements EventOutObserver since we did not use the callback mechanism of the EAI for this application.

public class CylinderExam extends Applet 
{  
   private       boolean  DEBUG           = false;
   private       Browser  browser         = null;
   private          Node  rootNode        = null;
   private EventInMFNode  addChildren     = null;
   private EventInMFNode  removeChildren  = null;
   private         Label  radius, height, bottom; 
   private         Label  top, side, DragLabel;
   private     TextField  radiusTF;
   private     TextField  heightTF;
   private        Choice  bottomC;   
   private        Choice  topC;
   private        Choice  sideC;
   private         float  Cheight = 1f;
   private         float  Cradius = 1f;
   private       boolean  Cbottom = true;
   private       boolean  Ctop    = true;
   private       boolean  Cside   = true;
   private          Node  myNode[]      = null;
   private          Node  myTransform[] = null;
   private       boolean  Dragging = true;
   private        Choice  DragMode ;
         
Let's define the user interface of the applet.

   /** 
   * User Interface 
   */
   public void 
   init()
   { 
      radius = new Label("radius");
      radiusTF = new TextField(4);

      height = new Label("height");
      heightTF = new TextField(4);

      bottom = new Label("bottom");
      bottomC = new Choice();
      bottomC.addItem("true");
      bottomC.addItem("false");
      
      top    = new Label("top");
      topC = new Choice();
      topC.addItem("true");
      topC.addItem("false");
      
      side   = new Label("side");
      sideC = new Choice();
      sideC.addItem("true");
      sideC.addItem("false");
      
      DragLabel   = new Label("Dragging");
      DragMode = new Choice();
      DragMode.addItem("Move");
      DragMode.addItem("Rotate");
     
      setLayout(new GridLayout(0,2));

      Panel Labels = new Panel();
      Labels.setLayout(new GridLayout(7,0));

      infoPanel p1 = new infoPanel(InfoWindow,"radius.html",this); 
      p1.add(radius);
      Labels.add(p1);

      infoPanel p2 = new infoPanel(InfoWindow,"height.html",this); 
      p2.add(height);
      Labels.add(p2);
    
      infoPanel p3 = new infoPanel(InfoWindow,"bottom.html",this); 
      p3.add(bottom);
      Labels.add(p3);
      
      infoPanel p4 = new infoPanel(InfoWindow,"top.html",this);
      p4.add(top);
      Labels.add(p4);

      infoPanel p5 = new infoPanel(InfoWindow,"side.html",this); 
      p5.add(side);
      Labels.add(p5);

      infoPanel p6 = new infoPanel(InfoWindow,"Info.html",this);
      p6.add(DragLabel);
      Labels.add(p6);
      
      infoPanel p7 = new infoPanel(InfoWindow,"Info.html",this);
      Labels.add(p7);

      Panel entries = new Panel();
      entries.setLayout(new GridLayout(7,0));

      Panel p11 = new Panel();
      p11.add(radiusTF);
      entries.add(p11);
      
      Panel p12 = new Panel();
      p12.add(heightTF);
      entries.add(p12);
      
      Panel p13 = new Panel();
      p13.add(bottomC);
      entries.add(p13);
     
      Panel p14 = new Panel();
      p14.add(topC);
      entries.add(p14);
   
      Panel p15 = new Panel();
      p15.add(sideC);
      entries.add(p15);

      Panel p16 = new Panel();
      p16.add(DragMode);
      entries.add(p16);

      Button submit = new Button("Submit");
      Panel p17 = new Panel();
      p17.add(submit);
      entries.add(p17);

      add(Labels);
      add(entries);

      System.out.println(" End of Init() ");

   }// end of init()


start() method is where we have to get the handle of Browser, events and nodes that we are interested in the scene. If you want Browser notifies this applet for the occurence of the particular event, you need to use the advise() method to make sure that this event also calls the callback() of this applet.
   public void 
   start()
   { 

The following code part gets the browser object.
      // ** Let's first get the handle of VRML 2.0 Browser
      // ** We need to use LiveConnect Technology here
      JSObject  win    = JSObject.getWindow(this);
      JSObject  parent = (JSObject) win.getMember("parent");
       
      JSObject  brWin  = (JSObject) parent.getMember("browser");
      JSObject  doc    = (JSObject) brWin.getMember("document");
      JSObject  embeds = (JSObject) doc.getMember("embeds");
      
      // ** Now it is time to get the handle of browser
      browser = (Browser) embeds.getSlot(0);
      if(DEBUG==true) System.out.println("after browser handle ");
         
We can get the handle of CYLINDER node with getNode() method.
      try {
            if(DEBUG==true) System.out.println("before rootNode handle ");
            rootNode = browser.getNode("CYLINDER");
            if(DEBUG==true) System.out.println("after rootNode handle ");
      
      } catch (InvalidNodeException e)
        { System.out.println("Invalid Node Exception"); }
      

We can get the handle of the addChildren and removeChildren eventIns.
      // Get EventIns of the rootNode
      addChildren = (EventInMFNode) rootNode.getEventIn("addChildren");
      removeChildren = (EventInMFNode) rootNode.getEventIn("removeChildren");
      
      if(DEBUG == true ) System.out.println(" events are registered !! ");      

      String vrmlString = " Group { children [ DEF myCone Transform { children ["+
                          " Shape { appearance Appearance { material Material {} }"+
                          " geometry Cylinder { radius "+Cradius+" height "+Cheight+
                          " bottom "+(Cbottom==true?"TRUE":"FALSE")+
                          " top "+(Ctop==true?"TRUE":"FALSE")+
                          " side "+(Cside==true?"TRUE":"FALSE")+" } }] }"+
                          " DEF Sensor PlaneSensor { } ] "+
                          " ROUTE Sensor.translation_changed TO myCone.set_translation}";
        
Create the VRML node dynamically and tell the browser to add this.
      myNode = browser.createVrmlFromString(vrmlString);
      
      addChildren.setValue(myNode);
      if(DEBUG==true) System.out.println("New Node is added to the scene");
 
   }// end of start()

action() is where we need to handle the user action. After user sets the necessary values from the applet's interface, she has to submit these values. Whenever we get the submit event, we create the necessary node(createVrmlFromString()) by using current values and replace(addChildren and removeChildren) this new node with the previous one.
   public boolean 
   action(Event event, Object what)
   {
      if (event.target instanceof Button)
      {
        Button b = (Button) event.target;
        if (b.getLabel() == "Submit")
        {
          String heightStr = heightTF.getText();
          String radiusStr = radiusTF.getText();

          if(heightStr.length()>0) Cheight = Float.valueOf(heightStr).floatValue();
          else Cheight = 1f;

          if(radiusStr.length()>0) Cradius = Float.valueOf(radiusStr).floatValue();
          else Cradius = 1f;

          Cbottom = (bottomC.getSelectedIndex()==0?true:false);
          Ctop    = (topC.getSelectedIndex()==0?true:false);
          Cside   = (sideC.getSelectedIndex()==0?true:false);
          Dragging = (DragMode.getSelectedIndex()==0?true:false);

          if(DEBUG==true)
          System.out.println(" height is "+Cheight+" radius "+Cradius+" bottom is "+Cbottom+
                             " top is "+Ctop+" side is "+Cside+" Moving is "+Dragging);
Delete the previous node from the scene with removeChildren.
          removeChildren.setValue(myNode);
          String vrmlString = " Group { children [ DEF myCone Transform { children ["+
                              " Shape { appearance Appearance { material Material {} }"+
                              " geometry Cylinder { radius "+Cradius+" height "+Cheight+
                              " bottom "+(Cbottom==true?"TRUE":"FALSE")+
                              " top "+(Ctop==true?"TRUE":"FALSE")+
                              " side "+(Cside==true?"TRUE":"FALSE")+" } } ] }"+
                              (Dragging==true?
                  " DEF Sensor PlaneSensor { } ] ROUTE Sensor.translation_changed TO myCone.set_translation }":
                  " DEF Sensor SphereSensor { } ] ROUTE Sensor.rotation_changed TO myCone.set_rotation } ");
        
Define the new node with createVrmlFromString().
          myNode = browser.createVrmlFromString(vrmlString);
      
Add this node to the scene with addChildren().

          addChildren.setValue(myNode);
          if(DEBUG==true) 
          { System.out.println("New Node is added to the scene");
            System.out.println(" event is SUBMIT ");
          }// end of if

       }// end of if

      }// end of if

      return true;

  }// end of action()
    
}// end of class CylinderExam

This object handles the information for each field in the node. For each field, there is a HTML page and this object shows this page in the lower right hand frame(Info frame) by using showDocument() method of AppletContext object.


/**
*
*/
class infoPanel extends Panel
{  
   private String   myurl   = null;
   private boolean  DEBUG = true;
   private Applet   app = null;

   infoPanel(JSObject _win, String _url, Applet _app)
   {  
      myurl = _url; 
      app = _app;

   }// end of constructor
   
   public boolean
   mouseEnter(Event e, int x, int y)
   {  boolean ret = false; 

      if(DEBUG==true) 
         System.out.println("in mouseEnter() ");

      if( myurl!=null ) ret = showDoc();
      
      return ret;

   }// end of mouseEnter()
 
   boolean showDoc()
   {
      boolean ret = false;
      URL url = null;
      try
      {
         url = new URL( app.getCodeBase() + myurl );

         if(DEBUG==true)
            System.out.println(" URL OK!");

         /** Show the url in the given netscape window */
         app.getAppletContext().showDocument( url, "Info");

         ret = true;

      } catch( MalformedURLException e )
        {  System.out.println(" Can not create URL from string "+myurl);
           e.printStackTrace();
        }
 
      return ret;

   }//end of showDoc()


}// end of class infoPanel


All Files