How many times have we pulled out our hair trying to find a proper
way to deploy high-end graphics and animation over the Web? The
answer is perhaps a bit embarrassing. In DHTML concepts, with the
help of JavaScript and layered components, we could render
interactivity with graphics and produce some animation effects, but
those were far from what we desired and what existing multimedia
packages could offer for PC-based games and animation programs. By
the time Java came into the picture it offered graphics-handling
features, which perhaps put a ray of hope into the developer's world.
Despite the fact that Java could handle graphics, it was to a limited
degree and had inherent problems with graphics rendering, such as
flickering, and frequent repaint problems. It was (should I say is?)
a head-breaking task to write extra code to avoid those problems.
Moreover, in a browser environment Java applets took a fairly long
time to download and display heavy graphics, calling into question
their potential as a solution.
Then Macromedia came up with award-winning products such as
Flash, and developers could at last find a real solution to the
problem. The Macromedia product families used vector-based graphics
and framed animation and successfully produced animation in a
compressed format called Shockwave, which had considerably smaller
files and took less time to download into the client browser. So with
all their rich features, Macromedia products immediately became the
most popular way to present graphics and animation over Internet
browsers.
Director: The Choice
Macromedia Director belongs to a similar line of products and
is the tool of choice for legions of Web and multimedia developers.
With Director we can create movies for Web sites, kiosks, and
presentations. Movies can be as small and simple as an animated logo
or as complex as an online chat room or game. Director movies can
include a variety of media, such as sound, text, graphics, animation,
and digital video. A Director movie can link to external media or be
one of a series of movies that refer to one another.
We can view Director movies in one of three ways:
- In the Shockwave movie format, which plays in
Shockwave-enabled Web browsers
- In a projector, which plays on your user's computer as a
stand-alone application
- In the form of a Java applet
Even though Director movies and Shockwave animation became
popular and efficient ways to deploy graphics and animation over the
Web, cross-platform compatibility was restricted to Windows and
Macintosh environments. Director needed a way in which browsers could
display movies with the help of a plug-in.
Director then offered cross-platform compatibility through
its internal conversion engine, called Xtra, that transformed
Director movies into Java applets, although Java applets aren't yet
as smooth as their Shockwave equivalents. They work, however, and
platform independence was achieved, making it useful for those with
something other than Windows or Macintosh. The quality of graphics
and the animation in the applets were dependent on the size and
resolution of the images used to render the movie.
Everything is apparently set and done for a
platform-independent, high-end graphics and animation deployment
framework. But human beings are never satisfied, and we're still
frustrated. The possibility of transforming Director movies to Java
applets tempted us to apply the same rich functionality of graphics
and animation outside the domain of the browser and, more important,
in a platform-independent manner. Unfortunately, Macromedia didn't
offer a ready-made, one-shot solution for this through Director. They
offered projectors that are .exe files to run the movies as a
stand-alone, but they're not platform independent.
In reality it's not too difficult to work out a solution to
the problem. In fact, the bottom line is that we have to find a
mechanism through which we can run the Director movie applets,
loading them into a container such as Java Frame or a Java Window.
Interestingly, Director allows us to produce source code of the movie
applet along with a few other helper .class files to run it. We can
manipulate the applet source file depending on our need and even
embed our own objects that may in turn be responsible for activities
such as database access, complex networking, or even RMI. In the end
what we have is a powerful mechanism to build a truly
platform-independent graphics and animation framework.
Creating the First Applet
Creating the applet from a Director movie is a trivial task.
Any basic Director movie can be saved as a Java applet by going to
the "File" menu, then choosing the "Save as Java" option. If this
option isn't visible, download the "Save as Java" Xtra from the
Macromedia site and install it on your machine. The options are to
save it as compiled Java or as Java source code. If we choose to save
it as a compiled Java source, then Director produces all the required
classes to run the movie as an applet and a .djr file of the movie
that's loaded by the applet, as well as an .html file that can be
loaded in a browser or applet-viewer utility to see it running.
When we want to customize the applet on our own, we must save
the movie by selecting the option "Save as Source." Although things
seem to be straightforward (indeed they are), it's unwise to assume
at an early stage that everything within a Director movie can be
converted to an applet. In fact, there are limitations (we'll discuss
them in due course). But to be optimistic, we can reasonably say that
a Director movie, with simpler event handling and animation features,
can more or less be converted to an applet. Before covering the
applet issues, it's worth discussing Director terminology and looking
into Lingo, the scripting language of Director and the basic
architecture of the conversion of Director movies into Java applets.
Some Useful Director Terminology
- Stage: The visible portion of the movie in which media elements appear.
- Cast member: The prepared form of any media element to be
used in the Director movie. Any media elements we use have to be
present in the cast window.
- Sprite: An object that controls when, where, and how cast
members appear in a movie. Multiple sprites can use the same cast
member. It's also possible to switch the cast member assigned to a
sprite as the movie plays.
- Behavior: A prewritten Lingo script we use to provide
interactivity and add interesting effects to a movie.
Introduction to Lingo
Lingo is Director's scripting language and a 4GL language
with a lot of power. It offers:
- Event-handling capability
- Data parsing and manipulation ability
- Audio and video handling features
- Database interaction
- Some networking
- XML support
Everything we draw on a Director movie stage becomes a
sprite, and the object of the movie animation is to control these
sprites. For example, suppose we draw a button (Sprite1) on the
stage, and by clicking it we want to move another Sprite, a ball
(Sprite 2), to point 100,100. The equivalent expression in Lingo
would be:
As mentioned, the Director movie is a kind of framed
animation, and each sprite on the stage is assigned several
behaviors. We can control these behaviors with the help of Lingo and,
loosely speaking, that's the key to Director movie animation.
It's possible to write two kinds of scripts with Lingo. A
frame script controls the behavior of the movie when it reaches a
particular frame. A behavior script controls the sprite's behavior,
such as dancing and movement. By attaching custom scripts to the
sprites and cast members, we can achieve a high level of framed
animation. It's recommended that the developer consult a thorough
tutorial on Lingo before developing complicated movies in Director.
How the Movie Works as an Applet
The basic architecture of how the applet reproduces the movie
can be summarized in the following manner.
Every running applet has exactly one instance of movie-
Name.class, which is the first object created when the applet runs.
This object reads the media file, creates the score and cast data
structures, then begins to play the movie. According to the movie's
tempo (the number of frames covered in a second), this object
periodically advances the frame counter, dispatches frame events to
active sprites and their behaviors, and redraws the stage. As the
applet receives mouse and key events, this object dispatches the
events to movie, sprite, and cast member scripts. The DirectorMovie
class's public API supports Lingo commands that manipulate the entire
movie and access to sprite and cast member objects.
Standard Java Classes
Director's "Save as Java" Xtra can minimize the player to
reduce the size of the applet. If Xtra doesn't minimize the player,
it contains standard player classes. A minimized player contains only
those classes the converted movie requires. The included classes
contain the code only for the features the applet uses.
Core Classes
Following are the key classes for the Director movies running
as applets. These classes represent a movie's basic structure. All
classes aren't always required to run the movie applets. If the movie
doesn't use any of the features available in the Lingo value or
helper classes, they can be omitted and the minimized player would
contain only the core classes. Each class provides an API through
which we control the behavior of the objects of the corresponding
classes.
DirectorMovie (extends Applet)
Contains all data and functions that pertain to the overall
movie, such as:
- The score
- The cast, which is a list of objects of the Member class and
can represent all the sprites taking part in the movie
- Movie properties, such as the frame counter, list of active
sprite objects and Lingo commands for common features, such as
network operations, mouse and key interactions, and movie control
- Event dispatching
- Interacting with the browser (via overridden applet methods)
- Handling media files
DirectorMovie is an abstract class. The class movieName
derives from the DirectorMovie class, where movieName represents the
movie's final name. For example, a movie named testMovie will have
the corresponding class testMovie.class.
Member
In a movie converted to Java every cast member (either taken
to the stage or not) has a corresponding member object that's created
when the movie begins playing.
A Member object contains the data and functions required to
load, draw, and use a single cast member. The Member class handles
all the built-in cast member types - shape, sound, bitmap, field,
transition, and script. We can create custom subclasses of Member.
The Member class's public API primarily provides get-and-set
access to Lingo-visible properties, such as getWidth() and
setText(String). The DirectorMovie.getMember() functions fetch an
existing member object given its name or number. Use the
Sprite.getMember() function to fetch the cast member attached to a
particular sprite.
Sprite
Every sprite that's currently active has one instance of the
sprite class, which the player creates and destroys as required.
A sprite object contains the data and functions required to
animate a single sprite, including stepping and interpreting the
score and dispatching events to behaviors. The sprite class handles
all built-in sprite types, and we can create custom subclasses of
sprites.
The sprite class's public API primarily provides get-and-set
access to Lingo-visible properties, such as getInk() or setLocH(). We
can use the DirectorMovie.getSprite() function to fetch a sprite
object by number and manipulate the sprite's properties by the public
API of the sprite class. The Behavior.__s property is a reference to
the sprite object that a particular behavior is attached to.
Behavior
This abstract class is the base class for all sprites and
frame scripts that contain property declarations. Each such sprite or
frame script is a unique subclass of behavior. For sprite and frame
scripts that contain property declarations, the behavior object's
public API consists of the following:
- Event-handling methods: All handlers in other sprite and
frame scripts are grouped into the single function
.uberHandleAnEvent(). Grouping these handlers reduces the number of
distinct classes, which substantially reduces the player's size.
Lingo Value Classes
When the export Xtra for Java translates scripts to Java, it
tries to determine whether a variable or parameter's data type is one
of Java's built-in data types: int, String, float, or Boolean. If the
Xtra can determine that the variable or parameter is one of Java's
built-in data types, it takes the same data type in Java. Sometimes
the Xtra can't determine the data type.
For example, several set statements assign a variable
different data types if the type isn't a built-in Java data type. In
these situations the Xtra gives the variable or parameter the Java
type LVal, or "Lingo value." An LVal object can be a null, integer,
string, double, sprite, member, symbol, linear list, property list,
rect, or point data type. Various subclasses of LVal handle the
possible types of data that an LVal object can hold. The player
creates and destroys Lingo values as required. After Java creates a
Lingo value object, the object can't change its type.
- LVal: The base class of all Lingo values. Its public API
contains all the Lingo-visible operations on any valid data types.
These operations include fetching the value as a certain type and all
list and arithmetic operations.
- LPoint: Extends LVal and implements Lingo values that are
points. We can use LVal.accessProp() to access the point's locH and
locV properties.
- LRect: Extends LVal and implements Lingo values that are
rects. We can use LVal.accessProp to access the left, right, top,
bottom, width, and height of the rect.
- LList: Extends LVal and implements Lingo values that are linear
lists. We can use various functions of the LVal class to access the
list.
Helper Classes
These classes have no public API. The Xtra includes them in
the player when they're required.
- NetworkFetch: This class implements getNetText() and
associated functions.
- J10IS, J11IS, MyMemoryImageSource: These classes help decode
GIF and JPEG images.
Classes Generated by the Export Xtra for Java
The Export Xtra for Java places the Java source code it
generates in the file movieName.java. This file always contains the
class movieName and may also contain one or more behaviorMemberName
classes.
- movieName Extends DirectorMovie: Each Director player for
Java has one subclass of DirectorMovie named after the original movie
file. The Export Xtra for Java creates this class. The movieName's
data and functions are simply the original Director movie's global
variables and movie handlers.
- behaviorMemberName Extends Behavior: Every sprite and frame
script that has properties is a unique subclass of behavior. Each
behaviorMemberName class's data and functions are simply the
properties and handlers of the original behavior script. In addition,
each behaviorMemberName class also has the Member variable __m, which
is a reference to the DirectorMovie object that owns the behavior.
Limitations of Custom Java
Following are some known tasks that custom Java can't do in
the Director player for Java.
JavaBeans can't easily be embedded because they're drawn
differently than Director cast members and sprites. To embed the bean
we have to rewrite the bean's source as a class that inherits from
the member and sprite.
AWT components and functionality can't be integrated because
they're drawn differently than Director draws. Director's rich
compositing model uses a custom Java engine that doesn't mesh with
the AWT drawing model.
Java's other inherent limitations, including security
restrictions and lack of direct connection with the operating system,
also limit how much we can customize Java in an applet.
Not all the events that Lingo is capable of handling are
converted to the applet. For example, a doubleClick event can't be
directly converted to an applet.
Many animation and movie features included in Director can't
be converted to Java applets.
The Framework
In the context of developing a mechanism to load and play
Director movie applets, we need to understand how an applet works.
While executing, applets need to have information regarding the
environment in which they're running, so they require a standard way
of interacting with their environments. This is provided by two
interfaces: AppletStub and AppletContext, both defined in the
java.applet package. When an applet is first created, a stub is
attached to it using the applet class's setStub() method. This stub
serves as the interface between the applet and the browser
environment or applet viewer environment in which the applet is
running. The AppletContext interface corresponds to an applet's
environment - the document containing the applet and other applets
(if any) in the same document. The methods in this interface can be
used to obtain information about its environment.
We'll create the applet, provide a stub and context for it,
place it in a container to be displayed, and execute its actions and
properties. This is possible only if the applet is the kind of
component that can be placed inside a container. If we look into the
Java class hierarchy, we see that the applet class inherits from the
panel class that in turn is inherited from the component class (see
Figure 1).
An applet also inherits the properties of a component, and it
should be possible to place it inside a standard Java container, such
as a frame or window, as simply as any other graphics component, like
Button or TextField. So far it's as simple as that. But applets are a
special type of component in the sense that they're not static like
AWT components, but possess their own life cycles to execute. At the
same time they can also act as a container that can be a placeholder
for other AWT components.
In a nutshell, to design and implement a framework for
playing the Director movie applets as stand-alone applications we
need to achieve the following:
- Get the Director movie in the form of an applet that's like
any other normal applet extending from the java.applet.Applet class.
- Implement a class loader that will load a named applet class.
- Provide the required AppletStub and AppletContext interfaces
to the applet.
- Implement a container object, typically a frame or window, to
hold the applet.
Designing the ClassLoader
The CustomClassLoader class extends from the
java.lang.ClassLoader, an abstract class that contains an abstract
method called loadClass (String className, Boolean resolve) (see
Listing 1). If the resolve flag is true, the method should call the
resolveClass() method of the resulting Class object. Our
CustomClassLoader class implements this method and returns the Class
object specified in the variable className. Following is the code
snippet doing the required job:
. . . .
Hashtable classDefs=new Hashtable();
. . . . . .
public Class loadClass(String className, boolean flag) {
try{
if(flag) {
resolveClass(findSystemClass(className));
classdefs.put(className, findSystemClass(className));
}
}catch(Exception e){ }
return (Class)classdefs.get(className);
}
The advantage of putting the resolved class into a hashtable
is that the same class doesn't get loaded twice; if it's already been
loaded, it's fetched from the hashtable and returned as the class
object.
The CustomStub class implements both AppletStub and
AppletContext interfaces defined in the java.applet package and
provides the custom implementation of the methods defined within
those two interfaces (see Listing 2). In our program the CustomStub
constructor expects movieName to be passed because the movie applet
queries the getParameter(ShockwaveMediaFile) about the .djr file to
be loaded. This is normally passed via the PARAM tag of the APPLET
tag in the HTML file. To return a proper .djr file name, the
CustomStub needs to know the name of the movie, which it does via the
constructor.
The next step is to implement a movieLoader class that's also
a container and can contain an applet and attach the necessary
CustomStub object to the applet (see Listing 3). This class
essentially makes a call to the loadClass() method of the
CustomClassLoader class, passing the name of the movie applet. It's
important to note that loading the applet doesn't mean the applet is
executing its life cycle. We have to explicitly call the life cycle
methods of the applet (init(), start(), destroy()) as needed and
provide it a CustomStub object to see it perform the actions defined
within them. The following lines of the movieLoader class do
precisely that.
CustomClassLoader loader=new CustomClassLoader();
CustomStub stub=new CustomStub(movieName);
Applet theApplet=(Applet)loader.loadClass(movieName, true);
theApplet.setStub(stub);
theApplet.init();
theApplet.start();
The overall proposed architecture is presented in Figure 2.
Live Example
Once these classes are implemented we have everything in
place to load and run the movie applet, so it's time to build a live
example of the concepts explored. I'll present a bare-bones example
of the process that includes our own Java objects and methods within
the movie applet. It minimally illustrates Director's animation
capability and how we can integrate the Director movie into our other
external Java programs. The example will obtain a random number
between one and six from the NumberGenerator class and show the image
of the generated number on the stage in response to clicking on a
button.
The Movie
To produce the movie (sample.djr), I've created the .bmp
images of numbers one to six, made them cast members, drawn them onto
the stage to make them available as sprites, and put them on the
stage so they become invisible at the start of the movie. I'll pick
the relevant sprite that corresponds to the number obtained from the
NumberGenerator class and place it onto the stage at a particular
location, 250,100, in this case.
The NumberGenerator Class
This is a simple class that generates a random number (see
Listing 4). It has a default constructor and a method called
generateNumber() that returns a random integer between one and six.
The movie applet will instantiate this class and call the
generateNumber() method each time we hit a button on the stage. The
sprite corresponding to the generated number is then displayed to the
location (250,100). This sounds much simpler and may be frustrating
for our animation lovers, but it teaches us a few very basic rules of
creating and integrating a Director movie applet with other external
Java programs.
Creating the Movie Applet
It's beyond the scope of this article to show every step
needed to follow a Director movie (which readers can learn from the
tutorial inside the Director package itself). For this example, I've
drawn a button on the stage and attached a dummy script to the button
that looks like this:
On mouseDown me
set the location of Sprite(1) to point(250,100).
End mouseDown
The script typically handles a mouseDown event on the button
and brings any particular sprite to the determined location
(250,100). If we don't attach any script to the button before
converting it to the Java applet, the button sprite won't be
configured to register any event through the Java code. This occurs
because all the behaviors of the sprites are registered inside the
behavior class. Each member of the movie has to be notified in a way
that it's capable of handling an event on it. This is according to
Macromedia's model of handling the movies as Java applets.
Having done that, if we save the movie as the source Java
file (from the "Save as Java" option), we'd see the sections of the
code shown below.
The movie class (in this case I've named the movie as Sample)
extends the DirectorMovie class, which in turn extends the Applet
class (see Listing 5).
public class sample extends DirectorMovie
{
public sample() {
__m = this;
}
static public sample __m;
Following is an event-handling method that typically holds
the translation of the movie scripts:
// --- Movie Script Translations ---
public void uberHandleAnEvent (Member member, int eventCode)
{
if ( member.castNumber == 1 && member.memberNumber == 8 )
//Translation of script: castMember8
{
switch( eventCode )
{
case DirectorMovie.__MouseUp: // mouseUp
{
//set the loc of Sprite(1) to point (250,100)
__m.getSprite(1).setLoc(new Lpoint(250,100).asPoint());
break;
}
default: break;
}
}
}
The event handling contains the Java equivalent translation
of the Lingo script we attached to the button. We need to modify this
code to our specific needs to show the generated number sprite on the
stage.
Adding Our Own Objects
Now we're ready to add our own NumberGenerator object to the
movie to obtain the random number between one and six generated by
the NumberGenerator class. First we declare a NumberGenerator object
like this at the class level:
NumberGenerator generator= null;
Then we initialize the object in the constructor of the sample.java.
generator=new NumberGenerator();
Now we need to write the code to obtain the number by
invoking the generateNumber() method of the NumberGenerator class. We
do this in the event-handling portion of the sample.java and bring
the corresponding sprite to the predetermined point (250,100)
location (see Listing 5). Each time we click the button, a number is
generated and shows the relevant sprite. But remember we also have to
remove any previous sprite present on the stage.
There are two ways to do this:
- Read the number generated before generating a new number, and
remove the corresponding sprite from the stage.
- Before generating a new number or after obtaining the new number,
remove all the number sprites from the stage, then show the sprite
corresponding to the generated number.
Since the first method seems more efficient to me, I'll
follow that. Removing a sprite from the stage is as simple as moving
it to a high location, for example 2000,2000. This is no doubt beyond
the stage of the movie, which is designed to be full-screen size in
any resolution.
Setting the Classpath
We must include the current working directory in our
classpath or mention it explicitly while executing the movie program.
Running the Application
We've completed the framework, so it's as simple as running
the application from the command line by typing the command:
java movieLoader sample
and the movie appears (see Figure 3). We can generate and see the
number by clicking on the button on the stage.
Conclusion
This article is a guideline to running Director movies as
stand-alone Java applications. Keep in mind that this is a developing
field and improvements are subject to further research. Take interest
in this area and develop more robust and efficient frameworks to work
in.
Resources
Additional information is available at
www.mcli.dist.maricopa.edu/director/javalist/dir2java.html.
For Java support within Lingo, visit
www.macromedia.com/support/director/how/expert/javasupport/Javasupp.html.
Author Bio
Samudra Gupta has been involved in the Java field in various research
projects for more than three years. Currently, he works as a
consultant to various UK concerns for their intranet- and
Internet-based e-commerce applications.
samudrag@hotmail.com.
Listing 1 CustomClassLoader.java
/**
* this class is a customized class loader which loads a named class
and puts into a Hashtable for future reference
*/
import java.io.*;
import java.util.*;
public class CustomClassLoader extends ClassLoader
{
Hashtable classdefs; //Hashtable for storing the reference
of the loaded class(s)
public CustomClassLoader()
{
classdefs=new Hashtable();
}
/**
* this method loads a named java class file and returns it as a Class object
*/
public Class loadClass(String className, boolean flag)
{
try
{
if(flag)
{
resolveClass(findSystemClass(className));
//putting the class name into the hashtable
classdefs.put(className, findSystemClass(className));
}
}catch(Exception e)
{
System.out.println("Error in loading the
class : "+e.toString());
}
//returning the class by picking up from the hashtable
return (Class)classdefs.get(className);
}
}
Listing 2 CustomStub.java
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.util.*;
import java.io.*;
/**
* This is a custom class providing the required AppletStub and
AppletContext environment to the
* movie applet. This is a very minimal implementation of the
AppletStub and AppletContext interfaces with
* only the methods implemented as they are required by the movie applet.
* The getCodeBase() , getImage(0 and getParameter() methods are used
by the movie applet.
* So they are implemented accordingly.
*/
public class CustomStub implements AppletStub, AppletContext, Enumeration
{
private URL codeBase;
private URL documentBase;
private String mName=null;
/* The constructor accepts the name of the movie because from the
getParameter() method we have to return
* the movieName.djr as a string which is used by the movie applet to
display the movie.
*/
public CustomStub(String movieName)
{
mName=movieName;
try
{
codeBase=new
URL("file:/"+System.getProperty("user.dir")+"/");
documentBase=codeBase;
}catch(Exception e)
{
}
}
public void appletResize(int w, int h){ }
public AppletContext getAppletContext()
{
return (AppletContext)this;
}
public URL getDocumentBase()
{
return documentBase;
}
public URL getCodeBase()
{
return codeBase;
}
public String getParameter(String param)
{
return mName+".djr";
}
public boolean isActive()
{
return true;
}
//AppletContext methods
public Applet getApplet(String name)
{
return null;
}
public Enumeration getApplets()
{
return (Enumeration)this;
}
public AudioClip getAudioClip(URL url)
{
return null;
}
public Image getImage(URL url)
{
return Toolkit.getDefaultToolkit().getImage(url);
}
public void showDocument(URL url){ }
public void showDocument(URL url, String target){ }
public void showStatus(String status){ }
//Enumeration methods
public boolean hasMoreElements()
{
return false;
}
public Object nextElement()
{
return null;
}
}
Listing 3 MovieLoader.java
/**
This class loads a Director movie applet and displays in a java Frame component
*/
import java.applet.*;
import java.awt.*;
import javax.swing.*;
public class MovieLoader extends JFrame
{
CustomClassLoader loader=null;
Class theClass=null;
Applet theApplet=null;
CustomStub stub=null;
public MovieLoader()
{
super("The sample Director movie");
try
{
//setting the size of the frame to 400X400
this.setSize(400,400);
//setting the background color of the frame to white
this.setBackground(Color.white);
//making the frame visible
this.show();
}catch(Exception e)
{
System.out.println(e.toString());
}
}
/**
* this method loads a named movie applet
*/
public void loadMovie(String movieName)
{
try
{
//initializing a CustomClassLoader object
loader=new CustomClassLoader();
//loading a named movie applet class through the
CustomClassLoader object
theClass=loader.loadClass(movieName,true);
//casting the loaded class to an Applet class
theApplet=(Applet)theClass.newInstance();
//initializing the CustomStub class with the name of
the movie applet
stub=new CustomStub(movieName);
//providing the applet a CustomStub object
theApplet.setStub(stub);
//setting the width and height of the applet
theApplet.setSize(400,400);
//adding the applet to the frame
this.getContentPane().add(theApplet);
}catch(Exception e){ System.out.println(e.toString());}
//calling the life cycle methods of the applet
theApplet.init();
theApplet.start();
validate();
}
public static void main(String args[])
{
new MovieLoader().loadMovie(args[0]);
}
}
Listing 4 NumberGenerator.java
class NumberGenerator
{
public NumberGenerator()
{
}
public int generateNumber()
{
java.util.Random random = new java.util.Random();
int i = random.nextInt(5)+1;
return i;
}
}
Listing 5 sample.java
import java.applet.Applet;
import java.awt.image.*;
import java.awt.*;
import java.util.*;
import java.net.*;
public class sample extends DirectorMovie
{
NumberGenerator generator = null;
int number = 0;
int usedNumber=0;
static public sample __m; //global movie variable declaration
public sample()
{
__m = this;
generator = new NumberGenerator();
}
/**
* --- Movie Script Translations ---
*/
public void uberHandleAnEvent (Member member, int eventCode)
{
if ( member.castNumber == 1 && member.memberNumber == 8 )
//anslation of script: castMember8
{
switch( eventCode )
{
case DirectorMovie.__MouseUp: // mouseUp
{
//finding if there is a number already
displayed and then moving it out of stage
if(usedNumber != 0)
{
__m.getSprite( usedNumber ).setLoc(new
LPoint( 2000,2000 ).asPoint());
}
//obtaining a generated number from the
NumberGenerator class
number=generator.generateNumber();
// set the location of the sprite
corresponding to the generated number
// to point(250,100)
__m.getSprite( number ).setLoc(new LPoint(
250, 100 ).asPoint());
usedNumber = number;
break;
}
default: break;
}
}
}
}