HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

I'm going to try to do two things in this month's column. As always, I'm going to show you a Java trick that you may find useful, or at least wildly entertaining. Second, I'm going to show you my interpretation of a (gasp) Microsoft technology after migrating to Java.

Those readers familiar with Java Beans probably know what customizers are. Bean customizers are supposed to be Java classes where you can keep customizing (editing) functionality for Java Beans. For example, let's say I create a simple animator Bean. Probably this is going to be implemented very similar to the Animator applet that comes as one of the sample applets in the JDK. I want to have a way of letting user's graphically choose the images and other parameters that define how the animator bean will perform. That's what the animator bean's customizer will do. It will be some dialog or graphical user interface which the bean user might use to select images that make up an animation, use a spin button to set the interval between animation frames and so on. What's really nice about the customizer/customizee design pattern is that the customizee (the Bean, in this case), doesn't have to carry around extra editing and design-time user interaction code. This makes the Bean class itself much smaller, which is better.

After playing with Beans a little bit I thought,"Gee, it would have been great if JavaSoft had defined Applet customizers as part of Java 1.0. Then, I wouldn't have had to waste so much of my life writing so many <PARAM> tags. Instead, I could use a customizer to write out an <APPLET> and associated <PARAM> tags for me!" My idea was that I wanted a graphical customizer whose output was an HTML <APPLET> tag and associated <PARAM> tags that I could just plop down into an HTML document. I wouldn't have to know anything about applet parameters, strange string-based parameter value formats, etc. I would just use a nice graphical interface. There was a flaw in my thinking, though.

Microsoft's "Design-Time" Controls
The problem with my initial idea for applet customizers is that I wanted a customizer to do something most customizers don't do. I wanted a customizer that would write an HTML version of an applet object out to some output stream. But that's not what customizers do. The only job of a customizer is to change the properties (i.e., parameters with respect to applets) of an object, nothing more. It's some other application or container's job to write a customizer's customizee out to a file to an output stream somewhere.

I've just finished a book on Microsoft's Visual InterDev Web application development environment (a nice development environment, if you want my opinion). Something that VI has that doesn't exist in Java is the notion of a design-time control. The design-time control is exactly what I was looking for in an applet customizer. The only difference is that design-time controls are ActiveX-only items. I had to translate the design-time control concept into Java.

A design-time control is a graphical element that, like a customizer, is used to set toe properties (or applet parameters) of some other element. The design-time control has the added responsibility of being able to write-output a text-based description of the control. In Visual InterDev, design-time controls are used to auto-generate server-side JavaScript and VBScript code. In my setup, the job of the Java design-time applet customizer is to write out an HTML <APPLET> tag and associated <PARAM> tags that I can place into an HTML document.

Applet Customizer Application
I created an Applet Customizer application which consists of an AWT main frame. Within the main frame you can create a new applet of any applet class. You provide the applet class and you also provide an applet customizer class that can customize that type of applet. Within the application's main frame you can see an Animator applet. The dialog to the right of the application's main frame is an Animator applet Customizer's interface.

The Applet Customizer application itself is little more than a simple applet container. This means it can load applets and provide them with an AppletContext and an AppletStub. My implementations of these two interfaces are quite minimal.

The application can only load one applet at a time. You use the application's Applet | Create New menu option to create a new applet object. The application asks you for an applet class name to use. The class name is turned into a classfile name, and the application loads the applet's class using Class.forName(). This part of the application is pretty simple.

The trick is finding the applet's customizer. The Beans spec defines a customizer class for a bean as having the same name as the Bean's class, with the added suffix "Customizer". So, if I had a Bean class "MyBean" and I defined a customizer, all I would have to do is call the customizer class "MyBeanCustomizer". The system automatically detects the name similarities and is able to associate the Bean class with its customizer class.

I do the same thing in any Applet Customizer application. When you load a new applet by giving the applet's class name, the application also tries to load an additional class called "<applet-classname>CustomizerForHTML". (I didn't use simply "<applet-classname>Customizer" because that would cause problems when I started to mixed applet and Beans projects together.) So, if my application user tells my application to create an applet of class "MyApplet", my application also tries to load the class "MyAppletCustomizerForHTML" and create an instance.

The CustomizerForHTML Interface
The only requirement I place on applet customizers is that they implement an interface called CustomizerForHTML. Through this interface, the Applet Customizer application communicates with the applet customizer.

The applet customizer is allowed to gather input from the user in any way it wishes. If it wants to create a new Frame window to gather user information, then it can. If it wants to have absolutely no user interface, then so be it. (For example, some of my initial test customizers had no UI but instead just ran a timer and did different things as if a user was doing them.)

The customizer is responsible for initializing, starting and stopping the target applet and providing string parameters to the applet when the applet asks for them. To accomplish this, the applet customizer object is handed a reference to the applet object it is supposed to be customizing, and a reference to the AppletContext and AppletStub allocated for the applet by the Applet Custromizer application. Each customizer is expected to provide its own AppletStub for the applet. Through the customizer's own AppletStub, it can hand the applet parameters. Any other requests (such as image or audio clip downloads, and so on) can be passed to the AppletStub provided by the Applet Customizer application.

Therefore, one method of the CustomizerForHTML interface looks like this:

public void setAppletAndAssoc(Applet a, AppletContext ac, AppletStub as);

The Applet Customizer application calls this method once to initialize the customizer object after it has been created.

The other responsibility of the applet's customizer object is to provide information necessary to make an HTML version of the applet. This is made up of just a set of parameter settings. Generally, these will be settings taken from user input to the customizer's user interface. Once it has these parameter settings, the Applet Customizer application writes an <APPLET> tag and associated <PARAM> tags (and a trailing </APPLET> tag) to System.out.

To get parameter information from the customizer object, the CustomizerForHTML interface defines a second method:

public Properties getAppletParameterSettings();

The return value from this method is a Properties object whose keys are the parameter names of the applet, and whose values are the parameter values. Each key/value pair in the Properties object causes the Applet Customizer application to write a tag like this:

<PARAM NAME="<key>" VALUE="<value>">

Listing 1 is the full Java source code for the definition of the CustomizerForHTML interface.

An Example
Listing 2 is part of the definition of the AnimatorCustomizerForHTML class. This class is able to customize the Sun sample applet Animator using my Applet Customizer application. Left out of Listing 2 is most of the UI setup and event handling code to save space in this magazine. Along with the code for the Applet Customizer application, the full code for this sample customizer class is available at the Java Developer's Journal Web site.

Basically, the job of this customizer is to gather from the user a list of images, time intervals and frame offsets. The Animator applet itself defines the parameters, but provides no easy UI for entering the parameter values in. The Applet Customizer application, along with a customizer class for the Animator applet, accomplishes this task.

Summary
Some of you readers may be wondering why I bother making such a customizer at all. After all, won't Java Beans take over the world soon anyhow? My opinion is that, while being way more versatile and fun to program with, Java Beans will not take over Java's place on the World Wide Web any time soon. This is for a couple of reasons:

  • Java 1.0 is still top dog. On the WWW, the overwhelming majority of browsers are 1.0-capable, not 1.1. This fact alone makes me cringe from the prospect of distributing Java 1.1 Beans or Applets to the public at large through the World Wide Web.
  • No HTML standards for adding Beans to an HTML page exist. Other than through object technology bridges (such as JavaSoft's ActiveX-Beans bridge), there's no standardized method for placing beans within an HTML page. The use of Beans is just way too new to think about as commercially viable (yet).
So, instead of heading down the Beans path, I figured I'd try to get a couple more good months (that's about ten years in "Internet time") out of the applet and Java 1.0 technology out there today. An Applet Customizer application for automatically writing <APPLET> and <PARAM> tags will save you personally a lot of keyboard strokes. In addition, it will make your applets a whole lot easier to use for those people who want to incorporate your applets into their home pages. Instead of having to know the strange formats of your various Applet parameters, you just give them an applet customizer. The user of your applet interacts with a friendly UI instead of a nasty text editor. They think you are some sort of technical genius, and your applet's get wider use. What could be better?

About the Author
Brian Maso is a programming consultant working out of Portland, OR. He is the co-author of The Waite Group Press's upcoming release, "The Java API SuperBible." Before Java, he spent five years corralled in the MS Windows branch of programming, working for such notables as the Hearst Corp., first DataBank, and Intel. Readers are encouraged to contact Brian via e-mail with any comments or questions at bmaso@europa.com

	

Listing 1: The CustomizerForHTML interface

import java.util.Properties;
import java.applet.*;

public interface CustomizerForHTML extends AppletStub {
    // Sets the applet, base stub and context
    // for this CustomizerForHTML.
    public void setAppletAndAssoc(Applet a, AppletStub as,
            AppletContext ac);
    public Properties getAppletParameterSettings();
}

Listing 2: Excerpts from the AnimatorCustomizerForHTML class

import java.applet.*;
import java.awt.*;

public class AnimatorCustomizerForHTML implements CustromizerForHTML {
    // State variables
    private AppletStub m_baseStub;
    private AppletContext m_context;
    private Properties m_params = new Properties();
    private Applet m_applet;

    // Public default constructor, required.
    public AnimatorCustomizerForHTML() {}

    // Set the applet, stub and context
    public void setAppletAndAssoc(Applet a, AppletStub as,
            AppletContext ac) {
        m_applet = a;
        m_baseStub = as;
        m_context = ac;
        m_applet.setStub(this);
    }

    // Gets the list of parameters and values set by the user.
    public Properties getAppletParameterSettings() {
        return m_params;
    }

    // The only overridden AppletStub method is getParameter.
    // The rest pass thropugh the call to the m_baseStub AppletStub.
    public String getParameter(String p) {
        return m_params.getProperty(p);
    }

    // This method is called by event handling code when user,
    // through UI, changes a parameter's value. The only way
    // to get the applet to properly reflect the new property
    // value is to stop, destroy, and re-init the applet. I
    // know it's based to re-init applets, against spec and all.
    // a more complete solution is beyond the scope of this column.
    public void setParameter(String param, String val) {
        m_applet.stop();
        m_applet.destroy();

        Properties.put(param, val);

        m_applet.setStub(this);
        m_applet.init();
        m_applet.start();
    }

    // Event handling code has been omitted for space reasons.
    // The pertinent code for this class is above.

}


 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: info@sys-con.com

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.