Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Java and Inter-Applet Communication


Dr. Dobb's Journal October 1997: Java and Inter-Applet Communication

A communication mechanism using the Java hash table

Andrew is a senior programmer for Access Health and can be contacted at [email protected].


Developing commonly consists of writing a single applet from which the functionality of the system will evolve. This works fine for small programs that display multimedia on web pages or present simple data-entry forms. But as systems get more complex, this approach becomes problematic. It would be difficult, for example, to rewrite a large desktop application as a giant monolithic applet embedded in a web page. Even if the task was accomplished, the price would be paid in other ways -- class download time, maintenance, and so on. When facing these problems, what we need is a system that supports many relatively small applets that communicate with one another -- which together make up the entire application.

Of course, the base Java libraries partially support inter-applet communication. If all applets are within the same applet context (the same HTML page), they can freely communicate. However, if there are multiple applet contexts (multiple HTML pages) displayed in the browser at one time, the applets in different contexts cannot communicate with one another with the standard Java libraries. This is a severe limitation, since you often want to have distinct sections of a web page split up into different frames (see Figure 5). In this article, I'll present one technique for addressing this problem.

Inter-Applet Communication Across Frames

A viable solution to the problem of inter-applet communication is to create a common class that is accessible by every applet in the browser, regardless of where it is running. This common class could then be used as the central communication link between all the applets.

The difficult part is constructing the mechanism by which all the applets communicate within this class. A cryptic approach might be to set flags or messages in the class to certain values that the other applets that are running would know how to interpret. This approach works, but would quickly become inefficient. If you closely examine the problem, you see that applets can't communicate across applet contexts (frames) because they can't get the object reference to the applet with which they are trying to communicate. If a data structure were created to capture the object references of all the applets currently running within the browser, an applet could communicate with any other running applet by getting its object reference and using it to communicate with the applet. In essence, you would be tricking Java into thinking that the applet you want to talk to is on the same HTML page.

The Java hash table is a perfect data structure for implementing a communication mechanism in this fashion. This hash table could be designed to accept entries that consist of a unique string identifier to distinguish the applet, and an object reference to the applet. When an applet wants to talk to another applet, all the applet needs to do is get the object reference out of the hash table by specifying its unique string identifier, then make calls to visible methods in the destination applet to conduct communication. In Figure 1, three applets are communicating using this inter-applet communications technique. Each of the applets must use the CommManager class (presented here) for communication with any of the other applets. The CommManager class contains the hash table where all the applet information is stored. CommManager allows applets to:

  • Register themselves, allowing other applets to communicate with them.
  • Unregister themselves if they are shutting down, preventing other applets from communicating with them.
  • Obtain object references of any other applets running in the browser, in order to communicate with them. This is the option that will be used most frequently. Registering and unregistering are only done once per applet. Obtaining the object reference is executed repeatedly depending on the actions that users perform within the system. Whenever an applet needs to communicate with another applet, this step will be performed.

Figure 2 illustrates the relationships between all the classes in this example. Every box represents a Java class. Inside each box are the class name (top), its data members (middle), and the available methods (bottom). The line between each of the applet classes and the communication manager class indicates that each applet class can have only one CommManager class associated with it. This relationship is commonly referred to as a "one-to-one" relationship.

Figure 3 is a data-flow diagram that shows the flow of data between the various processes. The boxes represent the applet objects. The oval structures are processes that the objects use to affect the flow of information. The hash table is represented at the top as the sole data store for this model. All of the lines represent flow of data between the various structures in this diagram. The two dotted lines showing the flow of information into the inter-applet communication process represent conditional flow of data. This flow of data is only possible if the label on the line is met. In other words, inter-applet communication is only possible in this model if the applet that wants to communicate with another applet has that applet's reference. If the applet reference has not yet been obtained using the three processes shown in Figure 3, this flow of data is invalid.

There are two paths in Figure 3 that lead away from the Applet classes. The path that leads from the Applet class and goes to the Get Applet process uses the unique identifier for the class that the applet wants to communicate with. This path for the Applet 1 class, for example, uses the unique identifier for Applet 3 because this is the applet that Applet 1 wants to communicate with. The converse would likewise be true for Applet 3. The other path that leads away from the applet classes and goes to the Unregister Applet process uses the unique identifier of the applet that is trying to unregister itself. When Applet 1, for example, uses the Unregister Applet process to unregister itself, it would use the unique identifier for itself. Once again, the converse would likewise be true for Applet 3.

Figure 4 shows these three applets running on separate HTML pages (split by HTML frames) in Internet Explorer. All have the ability to communicate with one another. (The CommManager class shown in Figure 5 is for clarity.) You can send text from one applet to any of the other applets by typing text in its text area and pressing the appropriate "send message" button. Once this button is pressed, the text will be displayed in the destination applet's text area.

If, for example, the "send message to Applet 3" button is pressed in Applet 1, the following events will occur:

1. Applet 1 will call getApplet() in the CommManager class, passing it Applet 3's unique string identifier.

2. Applet 1 will use the object reference obtained in step 1 to communicate with Applet 3 and send it the contents of its text area control.

Figure 6 shows a scenario that could occur if users were sending information back and forth between Applet 1 and Applet 3. Figure 7 shows an event trace of the scenario, illustrating how each event affects the various classes.

The CommManager Class

The communication manager class used in this inter-applet communications technique is called CommManager.class. Listing One is its declaration in its entirety.

At the heart of this class is the hash table private static Hashtable applets = new Hashtable(), where all the entries will be stored for all the applets that are running in the web browser. The hash table resizes itself automatically as needed, so CommManager doesn't have to worry about doing this. This data structure is private, so it cannot be modified except through the provided methods. It is also static to ensure that there is only one instance of the hash table regardless of how many instances of the class there are.

The CommManager class remains in memory as long as something is using it. When the last applet using it shuts down, CommManager also goes away. Theoretically, since the entire class consists of static information, you don't have to instantiate it before using it -- it can be used directly.

Registering Applets with CommManager

For an applet to be accessible by other applets, it must register itself with the communications manager. This is accomplished by making a call to regApplet() in the CommManager class. The method declaration is: public static boolean regApplet(String s, Applet a).

For the registration attempt to be successful, a unique string identifier to identify the applet and a reference to the applet itself must be passed into this method. If the registration is successful, a new entry is created in the hash table for the applet and a value of True will be passed back to let the calling method know that the registration attempt was successful. If the registration attempt fails, a value of False will be returned and a new entry will not be added to the hash table.

Usually applets register themselves with the communications manager when they are first loaded and the start method is executed. For example, Listing Two registers Applet 1 (Figure 6). Once Listing Two code is executed, an entry is added to the hash table for Applet 1. It consists of the unique string identifier Applet1 and the reference to Applet 1, which is represented by the keyword this. Once this occurs, all other applets that are already registered with the communications manager can freely communicate with Applet 1.

All the unique identifiers that are used in CommManager are case sensitive. This means that if Applet 1 is registered by passing regApplet "Applet1", the same exact string must be used in order to obtain a reference to the applet and to unregister it.

Getting an Object Reference from CommManager

Before one applet can attempt to talk to another over an HTML frame, the applet initiating the communication will need to get an object reference from the communications manager. This is done by calling the getApplet() method in CommManager. The method declaration is public static Applet getApplet(String s).

The unique identifier for the destination applet needs to be passed into this method. If the method is successful and able to find the applet in the hash table, it will pass back the object reference to the destination applet. This reference can then be used to initiate communications with the destination applet. If the applet is not found in the hash table, the method returns null.

In this demonstration, when the "send message to Applet 3" button is clicked, Listing Three is executed. This code will first get the object reference to Applet 3, and then call the ReceiveText() method in Applet 3 to send it the contents of Applet 1's text area control. The line that calls ReceiveText is a little confusing. The refApplet3 object is of type Applet, so it doesn't know what the ReceiveText method is. To get this to work properly, you have to cast the refApplet3 object with Applet 3. Once this is accomplished, Applet 1 can freely call all of the methods that are visible in Applet 3.

Unregistering an Applet from CommManager

When an applet is shutting down, its entry in the CommManager hash table is no longer valid, so it must be removed. The applet is responsible for removing itself from CommManager, which is accomplished by calling the unregApplet() method in CommManager. The method declaration is public static boolean unregApplet(String s).

When the call to unregApplet() is made, the unique string identifier must be passed in to tell it which class to remove, or unregister, from the hash table. The method passes back a Boolean value indicating success or failure.

In Figure 6, Listing Four unregisters Applet 3. This method only gets called when the applet stops. Once this line of code is executed, the entry in the hash table with a key of Applet3 is removed and can no longer be called.

Future Enhancements

Even though CommManager is useful as is, there are modifications that would make it more robust and flexible for a particular environment, including:

  • Adding exception handling. There are several places where the code is vulnerable for throwing an exception.
  • Adding a mechanism to help ensure that object references are valid. Although no mechanism can completely guarantee that object references are valid, there are several techniques that can improve their reliability. A thread could be added to this class that runs a process every so often that checks all the object references to ensure that they are valid at that point in time. If the object reference were not valid, its entry would be removed from the hash table.
  • Modifying or removing places where values are hardcoded in this class. For instance, if one applet wants to talk to another applet, it has to know its exact string identifier in order to communicate with it. Although this technique works, it is not flexible.
  • Removing the need for the applet to cast the method that it is calling with the destination applet once the object reference has been obtained. One technique that could be used is to have all the applets use a common base applet class. Then the cast will always be the same, regardless which applet is conducting communication.
  • Adding methods for a particular environment, possibly including methods to return the number of running applets, return a list of all the applet references, or return a copy of the hash table.
  • Adding a facility that allows applets to "query" CommManager for the current interface for another applet. This would make the class similar in many ways to COM.
  • Extending the class to include not just applets, but other kinds of objects that are being used in a particular environment.
  • Extending CommManager to allow applets to not only call other applets' methods, but to access other applets' variables. Although this really goes against the essence of object orientation, it could prove useful in many cases.

Listing One

import java.applet.*;import java.util.*;
public class CommManager
{
    private static Hashtable applets = new Hashtable();
    public static Applet getApplet(String s)
    {
        return (Applet)applets.get(s);
    }
    public static boolean regApplet(String s, Applet a)
    {
        if (a != null) {
            applets.put(s, a);
        return true;
        }
        else
            return false;
    }
    public static boolean unregApplet(String s)
    {
        if (applets.containsKey(s)) {
            applets.remove(s);
            return true;
        }
        else
            return false;
    }
}

Back to Article

Listing Two

public void start(){
    CommManager.regApplet("Applet1", this);
}

Back to Article

Listing Three

public boolean action(Event event, Object obj){               
    if ("Send Message to Applet 3".equals(obj)) {
        Applet refApplet3 = CommManager.getApplet("Applet3");
        ((Applet3)refApplet3).ReceiveText(SendTextEdit.getText());

    }
} 

Back to Article

Listing Four

public void stop(){
    CommManager.unregApplet("Applet3");
}

Back to Article

DDJ


Copyright © 1997, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.