Java IoT Authors: Zakia Bouachraoui, Pat Romanski, Elizabeth White, Liz McMillan, Yeshim Deniz

Related Topics: Java IoT

Java IoT: Article

Java & Macromedia, a perfect match

Java & Macromedia, a perfect match

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:

  1. In the Shockwave movie format, which plays in Shockwave-enabled Web browsers
  2. In a projector, which plays on your user's computer as a stand-alone application
  3. 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.

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.

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.

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) {
if(flag) {
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);

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());
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:

  1. Read the number generated before generating a new number, and remove the corresponding sprite from the stage.
  2. 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.

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.

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.

More Stories By Samudra Gupta

Samuda has five years of experience in Java and web technology related fields. He is presently working as an independent Java Consultant in the United Kingdom, providing solutions for different e-commerce projects.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

IoT & Smart Cities Stories
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.