Tips 'N Tricks
Java Tip 101: An alternative way for applet-to-applet
communication
Learn how to let your applets speak across frames and
browser window boundaries
Summary
You might think that your only
option for letting applets communicate with each other is to use the
getApplet
method. Unfortunately, the getApplet
method only returns applets on the same HTML page as the calling applet,
limiting the ways you can build interesting interfaces with
applet-to-applet communication. This tip shows you an alternative way to
let applets invoke methods on each other when they're located in
different frames or even in different browser windows. (1,000
words)
By Tobias Hill

Printer-friendly
version |
Mail this to a
friend
he AppletContext
class in the
java.applet
package contains the two member functions
getApplet
and getApplets
. By using those
functions, an applet can find other applets and invoke methods on them.
That can only be done if the following security requirements are met:
- The applets originate from the same server and from the same
directory on the server.
- The applets are running on the same page and in the same browser
window.
Those security restrictions may have been designed that way for good
reason; however, the latter requirement limits the ways you can make
interesting multiapplet interfaces featuring applet-to-applet (a2a)
communication.
Imagine the following scenario:
You have just finished writing a nice stock-market-trade applet and
decide to write an even nicer help system for it. You also want the help
system to be an applet and to be placed in a different browser frame than
the stock-market-trade applet. Your motive for that decision could be
based on structural concerns of your Website or the need to always keep
the help system on display. In addition, you want to make the help system
change to the correct information/guides based on what the user is doing
in the stock-trade applet (much like the paper clip in the Microsoft
Office suite). You even plan to make wizards within the help system that
can remotely point out things and perform tasks in the stock-market-trade
applet.
The idea behind that scenario is good. However, since the applets are
located on different pages, the Java API in AppletContext
will not help you develop the idea completely -- but this tip will.
Using the AppletContext API
Before I explain the alternative a2a-communication
mechanism, I will briefly show how the getApplet
and
getApplets
methods work. An applet can find another applet in
the same HTML page by either using the getApplet
method to
look it up by name or using the getApplets
method to find all
the applets on the page. Both methods, if successful, return one or more
Applet
objects to the caller. Once the caller finds an
Applet
object, it can invoke the Applet
's public
methods.
Suppose that a snippet of the HTML page looks like this:
<applet code="Applet1" width="400"
height="100"
name="app1">
</applet>
<br>
<applet
code="Applet2" width="400" height="100"
name="app2">
</applet>
<br>
By using the name attribute in the applet tag, you can refer to a
specific applet in the following way:
Applet theOtherApplet =
getApplet("app1");
theOtherApplet.anyMethod();
//calling any public method
Or, you can use the following code to retrieve all applets on the page:
Enumeration allAppletsOnSamePage =
getApplets();
while(allAppletsOnSamePage.hasMoreElements())
{
Applet appl =
(Applet)
allAppletsOnSamePage.nextElement();
appl.anyMethod();
//Calling any public method
}
When the calling applet has retrieved one or several applets on the
same HTML page, it can call those applets' public methods.
Using a static data structure
Unfortunately with the standard approach, you are
limited to communicating only with applets in the same HTML page. Luckily,
you can circumvent that limitation very easily. The way you make a2a
communication over page boundaries is based on the fact that two applets,
even though loaded in different browser windows, will share the same
runtime environment if their codebases are the same. Roughly speaking, the
codebase is the directory from which the applet was loaded. See Resources
below for a link to a tutorial on codebases.
The fact that the runtime environment is shared will make static fields
and structures accessible for all applet instances, and therefore, those
static fields and structures can be used to pass information between
different applets.
Not only can you let simple data types like integers, chars, and
strings be stored, but you can also let each applet store a reference to
itself (to the instance) in a static field (possibly within its own
class). Any other applet will be able to access that field, getting the
reference to the instance.
Does that sound tricky? Well, it is not. I'll start with an easy
example. Suppose you have one applet (AppletA.class) in one frame and
another applet (AppletB.class) in another frame, and both applets are
loaded from the same codebase.
You now want to give AppletA access to AppletB's public methods. You
need to make AppletB save a reference to itself in a static and public
field, like this:
public class AppletB
{
public static AppletB
selfRef = null; // Initially
zero
public void
init()
{
// Making
reference to the
instance
selfRef
=
this;
}
...
}
From AppletA you can now access the instance of AppletB:
public class AppletA
{
AppletB
theOtherApplet =
null;
public void
callAppletB()
{
//
Getting the static field where the
pointer
//
to the instance of AppletB is
stored.
theOtherApplet
=
AppletB.selfRef;
//
After this it is possible to call
instance
//
methods, like
this...
theOtherApplet.repaint();
}
...
}
That is all there is to it. That method works even though the applets
are not on the same page because the runtime environment is shared between
different applets.
It is important to note that the code above does not deal with the case
where the callAppletB
method in AppletA is called before
AppletB has started. If that happens, the selfRef
will be
null
and no communication can take place.
A more generic approach
Of
course, there is a more generic approach. You can create a class whose
only purpose is to store references to applets in a static data structure.
An example of such a class, called AppletList
, can be seen
below. Applet instances that want to give other applets access to their
public methods register with the AppletList
. By following the
pattern in AppletContext.getApplet(string name)
, each
registration has to be associated with a string. The string then serves as
a key when another applet calls for a reference to a certain applet.
Typically, an applet registers like this:
public class AppletA
{
public void start()
{
AppletList.register("Stock-trade-applet",
this);
...
}
}
Then another applet gets access to it:
public class AppletB
{
public void run()
{
AppletA
tradeApplet
=
(AppletA)
AppletList.getApplet("Stock-trade-applet");
...
}
}
You must also remember to unregister from the AppletList
when the applet stops:
public void stop()
{
AppletList.remove("Stock-trade-applet");
...
}
The complete source for the AppletList
class looks like
this:
0: import java.util.*;
1: import java.applet.Applet;
2:
3:
public class AppletList {
4: private static
Hashtable applets = new
Hashtable();
5:
6: public static void
register(String name, Applet applet)
{
7: applets.put(name,applet);
8: }
9:
10:
public static void remove(String name)
{
11:
applets.remove(name);
12: }
13:
14:
public static Applet getApplet(String name)
{
15: return (Applet)
applets.get(name);
16: }
17:
18: public
static Enumeration getApplets()
{
19: return
applets.elements();
20: }
21:
22: public
static int size() {
23:
return applets.size();
24: }
25: }
Please download the exampleCode.zip file in Resources
for examples of how to use this class.
Limitations
As I mentioned
earlier, the applets have to be loaded from the same codebase. Moreover,
if two different copies of the browser are running and applets are loaded
into each copy, the applets might not be able to communicate (depending on
browser version and settings) since they may no longer share the same
runtime environment. However, that will not be a problem if the browser
itself is spawning new browser windows.
That technique has been tested successfully on several platforms and
browser versions, but configurations may exist in which each applet's
runtime environment is kept separate. It has been successfully tested on
the following operating system and browser combinations:
Windows 2000: |
Internet Explorer 5.0, Internet Explorer 5.5, Netscape Navigator
4.72, Opera 4.01 |
Windows 98: |
Internet Explorer 4.72, Internet Explorer 5.0, Netscape
Navigator 4.02 |
Mac OS 9: |
Internet Explorer 4.5, Netscape Navigator 4.5 |
Red Hat 6.2: |
Netscape Navigator 4.73 |
Conclusion
This tip has shown
an alternative way to allow applet-to-applet communication. This approach
works in a way that the Java API's getApplet()
method does
not. Knowledge of this tip broadens your opportunities for developing
applets as part of a Website or an intranet -- use it as an alternative or
complement to the getApplets
methods.
Printer-friendly
version |
Mail this to a
friend
About the author
Tobias Hill is one of the founders of Sweden-based Citerus, a company that focuses on the
Java Platform for building Internet, intranet, and extranet systems. Hill
has programmed in Java since 1996 on various projects ranging from
programming an autonomic guide robot to making an online firework
postcard maker.