You’ve just completed your masterpiece — a killer Java applet that is bound to make any Web site stand out from the rest. The only problem is it’s a little bit bulky; instead of using the default Java components, you opted to design and build your own high-performace ones. Good move! But there is a downside: the end-user must download all of them. No problem! It’s worth the wait. But wait, what about the dreaded “gray” box?
While loading, Java applets appear on the Web page as a plain-jane gray box with little or no status information (unless you’re looking at the status bar at the bottom of your browser’s window). Even after a Web page has loaded (and the familiar Netscape or Explorer “loading” animation has stopped), a Java applet may still be loading. This can be a bit confusing to the person waiting for a Java applet. What’s going on? Is it loading? Is it broken? Only the most experienced users are likely to know. And this is a big problem considering more than one user will probably get a little restless and jet off to a different page instead of waiting.
So what to do? There are lots of ways to make applets load faster. The first way is to design applets that use only the default Java components (which are already on the user’s hard drive). Sadly, this solution sometimes is inappropriate or impossible — or just plain unsightly. Another way would be to put the applet on the user’s harddrive directly. But most users would be reluctant to go to the trouble of downloading and installing a bunch of class files. And CAB or JAR files help improve download time, but users still have to wait for the whole thing to download before seeing the applet. The first step into finding a solution is to take a look at the applet itself. We’ll use a simple example here:
import java.applet.*;
import java.awt.*;
import java.net.*;
public class ACoolApplet extends Applet
{
private Image bigGIF;
public void init()
{
String gif = this.getCodeBase().toString() + “waytoobig.gif”;
try
{
bigGIF = this.getImage(new URL(gif));
}
catch (MalformedURLException e) { }
}
public void paint(Graphics g)
{
g.drawImage(bigGIF, 0, 0, this);
}
}
As you can see, there is much to be desired with respect to the “gray” box. We’ll employ a couple of tricky methods to get rid of it as soon as possible and at the same time put something dazzling on the screen so that our users are amused while they’re waiting.
To do this, we add a few simple items to our applet:
- The first thing to do is make our applet implement the Runnable interface. This part is simple; we just add to our class declaration and add a run() method.
- Next, we use a MediaTracker object to monitor the progress of the loading image. MediaTracker is an interesting class in java.awt which monitors the loading of images and lets us know when they’re ready to show.
- Finally, we make paint() draw something interesting while we’re waiting for the images to load. I’ve opted to draw a bunch of dots but I’m guessing you’ll want to be more original here!
Our resulting applet looks something like this:
import java.applet.*;
import java.awt.*;
import java.net.*;
public class ACoolerApplet extends Applet implements Runnable
{
private Image bigGIF;
private Thread thread;
private MediaTracker mt;
private boolean loaded;
private String message;
public void init()
{
super.init();
String gif = this.getCodeBase().toString() + “waytoobig.gif”;
message = “Loading (be more original than this!) …”;
try
{
bigGIF = this.getImage(new URL(gif));
}
catch (MalformedURLException e) { }
mt = new MediaTracker(this);
mt.addImage(bigGIF, 1);
loaded = false;
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g)
{
if (loaded)
{
g.drawImage(bigGIF, 0, 0, this);
}
else // (!loaded)
{
g.setColor(Color.blue);
g.fillRect(0, 0, this.size().width, this.size().height);
g.setColor(Color.white);
g.drawString(message, 10, 20);
}
}
public void run()
{
try
{
paint(this.getGraphics());
while(mt.statusAll(true) != MediaTracker.COMPLETE)
{
message += “..”;
paint(this.getGraphics());
thread.sleep(500);
}
}
catch (InterruptedException e)
{
}
finally
{
loaded = true;
paint(this.getGraphics());
}
}
}
Of course, you’ll notice that this applet is a fairly simple example — it didn’t implement nifty tricks like double buffering and the like. But for getting rid of the dreaded “gray” screen (and replacing it with a nifty “blue” screen), this applet certainly does the job.
Does this really work? The truth is, we can’t get rid of the gray screen completely. But we can try and get rid of it as soon as possible — even before the Applet is entirely loaded. The key to doing this is to paint something flashy to the screen before you load all of the classes and images that your applet is going to use. This will distract the user while they’re waiting for all the good stuff from your applet to load. Trust me, it works! And if you don’t trust me, just think back to the last time you waited for a stalled Web page to load based only on the browser’s unsavory little animation.
Chris Knight is an independent software developer building nifty software projects such as swIRC and Retrix RetroBoard. He also is presently studying Communication, Philosophy and Computer Science at Simon Fraser University. He can be contacted at chris@knight.net.