Use Special Syntax to Find Applet Running in Another Frame?

Question:
I have two applets running on the same page, one in each of two frames. I want them to communicate, but when I do a getAppletContext.getApplet() call, the second applet can’t find the first. I’ve gone through the enumeration returned by getApplets(), and only the applet that makes the call is found.

Is there a special syntax I have to use to find an applet running in another frame?

Answer:
First a little background for newcomers:

For security reasons, there are many restrictions on the ability of an applet to communicate with other processes. However, an applet can communicate with other applets running on the same Web page. How is this done?

One way is to give names to each applet on a Web page using aNAME specifier in the applet tag. Here’s a sample HTML filecontaining two applets named “senderapplet” and “receiverapplet.”Note that the names MUST be in lowercase letters:

********************************** Test     

This applet sends outputs to the applet below.

This browser can’t run applets.

This applet receives inputs from the applet above.

This browser can’t run applets. **********************************
Information about the Web page containing an applet is represented in anAppletContext object, which an applet can obtain using its getAppletContextmethod:
AppletContext context = getAppletContext();
Among other things, this context contains references to all other appletson the Web page. These references can be accessed from the applet’sname (given by the NAME specifier above) using the getApplet method. Forexample, if an instance of Sender.class wants a reference to the instance of the Receiver.class residing on the same Web page, it can call:
Applet recApp = context.getApplet(“receiverapplet”);
Communication with the Receiver applet is possible if the Receiver appletprovides a special public method that can process messages. Assume the Receiver object has a method called ProcessInput, which expectsa String input. Then the Sender object can invoke this method throughthe reference obtained above (after the appropriate cast):
((Receiver)recApp).processInput(“your message here”);
Now the problem:

A frame is an HTML element that contains a Web page. Thus, using frames it is possible to nest Web pages. Although not yet a standard HTML feature, framesare supported by Netscape. Assume the Sender and Receiver applets above residein separate HTML files called “send.html” and “rec.html,” respectively. Using theframe feature, they can appear in separate frames on the same Web page:

**********************************     Parent Frame                  ********************************** 
Unfortunately, the AppletContext of the Sender applet represents send.html,the Web page within the Sender frame. Since the Receiver applet resides inrec.html, it will not be among the applets represented inside the Senderapplet’s AppletContext. Thus, the technique outlined above fails.

And now the solution:

I wish I could take all the credit for this idea, but alas, I stand onthe shoulders of giants. My inspiration was a “Tip of the Week” submitted to JavaWorld by Greg Williams.

My strategy is this: Since Sender’s AppletContext doesn’t hold areference to the Receiver applet, why not create our own class and call it a MetaContext, containing references to all registered applets? Receiver and Sender applets can register themselves with theMetaContext during initialization. The MetaContext can provide itsown getApplet method to allow applets to access registered applets.

But how will applets running on different pages obtain references to a common MetaContext? This should be possible if everything in the MetaContext is static.

Here’s my definition of MetaContext. Registered applets are held in a hash table, where they are indexed by their names:

**********************************import java.applet.*;import java.util.*;public class MetaContext       {     // registered applets live here     private static Hashtable applets = new Hashtable(10);     // to access registered applets     public static Applet getApplet(String s) {        return (Applet)applets.get(s);      }     // to register applets     public static void regApplet(String s, Applet a) {        applets.put(s, a);     }   // etc.}********************************** 
As an example, my Sender and Receiver applets each contain twoTextFields, one showing the applet’s input, the other showingits output. The user enters a number x into the Sender’s inputfield, x is sent to the Receiver, x appears in the Receiver’s input field, the Receiver computes y = x * x, places y in its outputfield, then sends y back to the Sender. The Sender computes z = y + 1,then displays z in its output field. The example is silly, but itdoes show a non-trivial, two-way communication between Sender and Receiver.

To receive inputs, both Sender and Receiver provide a method:

public void processInput(String s) { … }
To access the Receiver’s processInput() method, the Sender firstobtains a reference to the Receiver applet through the MetaContext:
Applet recApp = MetaContext.getApplet(“receiverapplet”);
Then invokes the Receiver’s processInput method:
((Receiver)recApp).processInput(sendField.getText());
Here’s the complete code for Sender and Receiver:
**********************************// Sender.javaimport java.awt.*;import java.applet.*;public class Sender extends Applet {   private TextField sendField;    // input field   private TextField receiveField; // output field   public void init() {      setLayout(new FlowLayout());      sendField = new TextField(“SEND”, 7);      add(sendField);      receiveField = new TextField(“RECEIVE”, 7);      add(receiveField);      // register with MetaContext      MetaContext.regApplet(“senderapplet”, this);   }   public boolean action (Event e, Object arg) {      if (e.target instanceof TextField && e.target == sendField) {         AppletContext context = getAppletContext();         context.showStatus(“***** ” + sendField.getText() + ” sent!”);         // get reference to receiver applet:         // Applet recApp = context.getApplet(“receiverapplet”);         Applet recApp = MetaContext.getApplet(“receiverapplet”);         // send message to receiver applet:         if (!recApp.isActive())             receiveField.setText(“Error!”);         else {                      receiveField.setText(”   “);            ((Receiver)recApp).processInput(sendField.getText());         }      }      else return false;  // event not handled      return true; // event handled   }   // s = number sent by receiver applet   public void processInput(String s) {      double y = (Double.valueOf(s)).doubleValue();      double z = doSomething(y);      receiveField.setText(String.valueOf(z));      repaint();   }   private double doSomething(double z) { return z + 1; }}  // Sender**********************************// Receiver.javaimport java.awt.*;import java.applet.*;public class Receiver extends Applet {   private TextField sendField;    // input field   private TextField receiveField; // output field   public void init() {      setLayout(new FlowLayout());      sendField = new TextField(“SEND”, 7);      add(sendField);      receiveField = new TextField(“RECEIVE”, 7);      add(receiveField);      // register with MetaContext      MetaContext.regApplet(“receiverapplet”, this);   }   // s = number sent by sender   public void processInput(String s) {      receiveField.setText(s);      repaint();      AppletContext context = getAppletContext();      context.showStatus(“***** ” + s + ” received!”);      // get reference to sender applet      // Applet senderApp = context.getApplet(“senderapplet”);      Applet senderApp = MetaContext.getApplet(“senderapplet”);      double x = (Double.valueOf(s)).doubleValue();      double y = doSomething(x);      String t = String.valueOf(y);      sendField.setText(t);      repaint();      // send message back to sender applet      ((Sender)senderApp).processInput(sendField.getText());         }   private double doSomething(double z) { return z * z; }}  // Receiver********************************** 
To complete the picture, here are send.html and rec.html:
**********************************   Sender       

The applet in this frame sends outputs to the applet in the other frame.

This browser can’t run applets. ********************************** Receiver

The applet in this frame receives inputs from the applet in the Sender frame.

This browser can’t run applets. **********************************

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: