The MPEG-4 Java API & MPEGlets
by Aaron E. Walsh

Example 1: 

#VRML V2.0 utf8
Group {
 children [
    Shape {
     appearance Appearance {
       material Material { }
     }
     geometry Cone { }
    }
  DEF TOUCH TouchSensor { }    # define the sensor 
  DEF LIGHT DirectionalLight { # define the light 
    color 0 1 0                
    on FALSE
  }
 ]
ROUTE TOUCH.isOver TO LIGHT.set_on
}



Listing One
/** LifecycleSkeleton.java
  * Skeleton (boilerplate) code illustrating "lifecycle" methods
  * common to all MPEGlets.
  * @author Aaron E. Walsh, Mantis Development Corp.
  */
import org.iso.mpeg.mpegj.*;   // import all classes in main MPEG-J package
public class LifecycleSkeleton implements MPEGlet {
 /** Any operations necessary to perform before the MPEGlet runs go here.
   * The init() lifecycle method is called by the MPEG-J player to inform the
   * MPEGlet that it has been loaded into the system. init() is always called
   * before the MPEGlet is executed as a separate thread via run() method.
   */
  public void init()
  {
  }
 /** Any operations necessary for MPEGlet's main thread of execution go here.
   * run() is called by the MPEG-J player to inform the MPEGlet that it may
   * now execute. init() is always called before run().
   */
  public void run()
  {
     try {
            // invoke methods that can throw exceptions related to MPEG-J and
            // MPEGlets here, with corresponding catch clauses below. This
            // boilerplate code catches and prints the stack trace for
            // MPEGJException and InterruptedException objects, in addition
            // to generic Exception objects, but doesn't do anything truly
            // productive after they are caught:
         } catch (MPEGJException e) {
            e.printStackTrace();
         } catch (InterruptedException e) {
            e.printStackTrace();
         } catch (Exception e) {
            e.printStackTrace();
         }
  }
  /** Any operations necessary to perform before MPEGlet is stopped go here.
   * stop() is called by the MPEG-J player to inform the MPEGlet that it
   * should stop its execution. stop() is always called before destroy() and
   * can also be called anytime execution of the MPEGlet must cease.
   */
  public void stop()
  {
  }
  /** Cleanup operations necessary to perform before MPEGlet is destroyed go
   * here. destroy() is called by MPEG-J player to inform MPEGlet it is being
   * reclaimed by system and should therefore destroy any resources it has
   * allocated that won't automatically be cleaned up via garbage collection.
   * stop() will always be called before destroy().
   */
  public void destroy()
  {
  }
}



Listing Two
/** SceneExampleMpeglet.java
  * Complete MPEGlet using the Scene API to invert the color of a shape when
  * users click on it. This software module is featured in "More MPEG-4
  * Jump-Start" by Aaron E. Walsh and Mikael Bourges-Sevenier and appears here
  * courtesy of the publisher, Prentice Hall, & original authors of this code.
  * @author Vishy Swaminathan, Sun Microsystems, Inc.
  * @author Alex MacAulay, Envivio, Inc.
  */

import org.iso.mpeg.mpegj.*;
import org.iso.mpeg.mpegj.scene.*;
public class SceneExampleMpeglet implements
  MPEGlet, SceneListener, EventOutListener {
    Scene m_scene = null;
    boolean m_isTouched = false;
    public void run() {
        try {
            // Get the scene manager and register to be
            // notified when the scene is ready.
            MpegjTerminal terminal = new MpegjTerminal(this);
            SceneManager manager = terminal.getSceneManager();
            manager.addSceneListener(this);
            // Wait until the scene is ready.
            synchronized (this) {
                while (m_scene == null) {
                    wait();
                }
            }
            // Get the TouchSensor node.
            Node touch = m_scene.getNode("TOUCH");
            // Register to be notified when it's touched.
            touch.addEventOutListener(
              EventOut.TouchSensor.touchTime, this);
            // Wait until it's touched.
            synchronized (this) {
                while (!m_isTouched) {
                    wait();
                }
            }
            // Invert the color of a shape as feedback.
            Node material2d = m_scene.getNode("MATERIAL");
            FieldValue val = material2d.getEventOut(
              EventOut.Material2D.emissiveColor);
            final float[] color = ((SFColorFieldValue) val).getSFColorValue();
            color[0] = 1 - color[0];
            color[1] = 1 - color[1];
            color[2] = 1 - color[2];
            material2d.sendEventIn(
                EventIn.Material2D.emissiveColor,
                new SFColorFieldValue() {
                    public float[] getSFColorValue() {
                        return color;
                    }
                }
            );
        } catch (MPEGJException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            return;
        }
    }
    // Called by the scene manager when the scene is ready.
    public synchronized void notify(int msg, Scene scene) {
        if (msg == SceneListener.Message.SCENE_READY) {
            m_scene = scene;
            notify();
        }
    }
    // Called when the touchTime eventOut is triggered.
    public synchronized void notify(int id, FieldValue v) {
        m_isTouched = true;
        notify();
    }
    // lifecycle methods that aren't implemented by this MPEGlet:
    public void init() {}
    public void stop() {}
    public void destroy() {}
}






