The Applet Context

   


An applet runs inside a browser or the applet viewer. An applet can ask the browser to do things for it, for example, fetch an audio clip, show a short message in the status line, or display a different web page. The ambient browser can carry out these requests, or it can ignore them. For example, if an applet running inside the applet viewer asks the applet viewer program to display a web page, nothing happens.

To communicate with the browser, an applet calls the getAppletContext method. That method returns an object that implements an interface of type AppletContext. You can think of the concrete implementation of the AppletContext interface as a communication path between the applet and the ambient browser. In addition to getAudioClip and getImage, the AppletContext interface contains several useful methods, which we discuss in the next few sections.

Inter-Applet Communication

A web page can contain more than one applet. If a web page contains multiple applets from the same codebase, they can communicate with each other. Naturally, this is an advanced technique that you probably will not need very often.

If you give name attributes to each applet in the HTML file, you can use the getApplet method of the AppletContext interface to get a reference to the applet. For example, if your HTML file contains the tag

 <applet code="Chart.class" width="100" height="100" name="Chart1"> 

then the call

 Applet chart1 = getAppletContext().getApplet("Chart1"); 

gives you a reference to the applet. What can you do with the reference? Provided you give the Chart class a method to accept new data and redraw the chart, you can call this method by making the appropriate cast.

 ((Chart) chart1).setData(3, "Earth", 9000); 

You can also list all applets on a web page, whether or not they have a name attribute. The getApplets method returns an enumeration object. (You learn more about enumeration objects in Volume 2.) Here is a loop that prints the class names of all applets on the current page.

 Enumeration e = getAppletContext().getApplets(); while (e.hasMoreElements()) {    Object a = e.nextElement();    System.out.println(a.getClass().getName()); } 

An applet cannot communicate with an applet on a different web page.

Display of Items in the Browser

You have access to two areas of the ambient browsers: the status line and the web page display area. Both use methods of the AppletContext class.

You can display a string in the status line at the bottom of the browser with the showStatus message, for example,

 showStatus("Loading data . . . please wait"); 

TIP

In our experience, showStatus is of limited use. The browser is also using the status line, and, more often than not, it will overwrite your precious message with chatter like "Applet running." Use the status line for fluff messages like "Loading data . . . please wait," but not for something that the user cannot afford to miss.


You can tell the browser to show a different web page with the showDocument method. There are several ways to do this. The simplest is with a call to showDocument with one argument, the URL you want to show.

 URL u = new URL("http://java.sun.com/index.html"); getAppletContext().showDocument(u); 

The problem with this call is that it opens the new web page in the same window as your current page, thereby displacing your applet. To return to your applet, the user must click the Back button of the browser.

You can tell the browser to show the document in another window by giving a second parameter in the call to showDocument (see Table 10-2). If you supply the special string "_blank", the browser opens a new window with the document, instead of displacing the current document. More important, if you take advantage of the frame feature in HTML, you can split a browser window into multiple frames, each of which has a name. You can put your applet into one frame and have it show documents in other frames. We show you an example of how to do this in the next section.

Table 10-2. The showDocument Method

Target Parameter

Location

"_self" or none

Show the document in the current frame.

"_parent"

Show the document in the parent frame.

"_top"

Show the document in the topmost frame.

"_blank"

Show in new, unnamed, top-level window.

Any other string

Show in the frame with that name. If no frame with that name exists, open a new window and give it that name.


NOTE

Sun's applet viewer does not show web pages. The showDocument method is ignored in the applet viewer.



 java.applet.Applet 1.2 

  • public AppletContext getAppletContext()

    gives you a handle to the applet's browser environment. On most browsers, you can use this information to control the browser in which the applet is running.

  • void showStatus(String msg)

    shows the string specified in the status line of the browser.


 java.applet.AppletContext 1.2 

  • Enumeration getApplets()

    returns an enumeration (see Volume 2) of all the applets in the same context, that is, the same web page.

  • Applet getApplet(String name)

    returns the applet in the current context with the given name; returns null if none exists. Only the current web page is searched.

  • void showDocument(URL url)

  • void showDocument(URL url, String target)

    show a new web page in a frame in the browser. In the first form, the new page displaces the current page. The second form uses the target parameter to identify the target frame (see Table 10-2 on page 516).

A Bookmark Applet

This applet takes advantage of the frame feature in HTML. We divide the screen vertically into two frames. The left frame contains a Java applet that shows a list of bookmarks. When you select any of the bookmarks, the applet tells the browser to display the corresponding web page (see Figure 10-8).

Figure 10-8. A bookmark applet


Example 10-6 shows the HTML file that defines the frames.

Example 10-6. Bookmark.html
  1. <html>  2.    <head>  3.       <title>Bookmark Applet</title>  4.    </head>  5.    <frameset cols="320,*">  6.       <frame name="left" src="/books/1/281/1/html/2/Left.html"  7.          marginheight="2" marginwidth="2"  8.          scrolling="no" noresize="noresize"/>  9.       <frame name="right" src="/books/1/281/1/html/2/Right.html" 10.          marginheight="2" marginwidth="2" 11.          scrolling="yes" noresize="noresize"/> 12.    </frameset> 13. </html> 

We do not go over the exact syntax elements. What is important is that each frame has two essential features: a name (given by the name attribute) and a URL (given by the src attribute). We could not think of any good names for the frames, so we simply named them "left" and "right".

The left frame uses the Left.html file (Example 10-7) , which loads the applet into the left frame. It simply specifies the applet and the bookmarks. You can customize this file for your own web page by changing the bookmarks.

Example 10-7. Left.html
  1. <html>  2.    <head><title>A Bookmark Applet</title></head>  3.    <body>  4.       <p>  5.          Click on one of the radio buttons.  6.          The corresponding web page  7.          will be displayed in the frame on the right.  8.       </p>  9.       <applet code="Bookmark.class" width="290" height="300"> 10.          <param name="link.1" value="http://java.sun.com"/> 11.          <param name="link.2" value="http://java.net"/> 12.          <param name="link.3" value="http://linuxtoday.com"/> 13.          <param name="link.4" value="http://www.horstmann.com"/> 14.          <param name="link.5" value="http://www.phptr.com"/> 15.          <param name="link.6" value="http://usps.com"/> 16.          <param name="link.7" value="http://www.cafeaulait.org"/> 17.       </applet> 18.    </body> 19. </html> 

The right frame loads a dummy file that we called Right.html (Example 10-8). (Some browsers do not approve when you leave a frame blank, so we supply a dummy file for starters.)

Example 10-8. Right.html
 1. <html> 2.    <head><title>Web pages will be displayed here.</title></head> 3.    <body> 4.       <p>Click on one of the radio buttons to the left. 5.       The corresponding web page will be displayed here.</p> 6.    </body> 7. </html> 

The code for the bookmark applet that is given in Example 10-9 is simple. It reads the values of the parameters link.1, link.2, and so on, and turns each of them into a radio button. When you select one of the radio buttons, the showDocument method displays the corresponding page in the right frame.

Example 10-9. Bookmark.java
  1. import java.awt.*;  2. import java.awt.event.*;  3. import java.applet.*;  4. import java.util.*;  5. import java.net.*;  6. import javax.swing.*;  7.  8. public class Bookmark extends JApplet  9. { 10.    public void init() 11.    { 12.       Box box = Box.createVerticalBox(); 13.       ButtonGroup group = new ButtonGroup(); 14. 15.       int i = 1; 16.       String urlString; 17. 18.       // read all link.n parameters 19.       while ((urlString = getParameter("link." + i)) != null) 20.       { 21. 22.          try 23.          { 24.             final URL url = new URL(urlString); 25. 26.             // make a radio button for each link 27.             JRadioButton button = new JRadioButton(urlString); 28.             box.add(button); 29.             group.add(button); 30. 31.             // selecting the radio button shows the URL in the "right" frame 32.             button.addActionListener(new 33.                ActionListener() 34.                { 35.                   public void actionPerformed(ActionEvent event) 36.                   { 37.                      AppletContext context = getAppletContext(); 38.                      context.showDocument(url, "right"); 39.                   } 40.                }); 41.          } 42.          catch (MalformedURLException e) 43.          { 44.             e.printStackTrace(); 45.          } 46. 47.          i++; 48.       } 49. 50.       add(box); 51.    } 52. } 

It's an Applet. It's an Application. It's Both!

Quite a few years ago, a Saturday Night Live skit poking fun at a television commercial showed a couple arguing about a white, gelatinous substance. The husband said, "It's a dessert topping." The wife said, "It's a floor wax." And the announcer concluded triumphantly, "It's both!"

Well, in this section, we show you how to write a Java program that is both an applet and an application. That is, you can load the program with the applet viewer or a browser, or you can start it from the command line with the java program launcher. We are not sure how often this comes up we found it interesting that this could be done at all and thought you would, too.

The screen shots in Figures 10-9 and 10-10 show the same program, launched from the command line as an application and viewed inside the applet viewer as an applet.

Figure 10-9. The calculator as an application


Figure 10-10. The calculator as an applet


Let us see how this can be done. Every class file has exactly one public class. For the applet viewer to launch it, that class must derive from Applet. For Java to start the application, it must have a static main method. So far, we have

 class MyAppletApplication extends JApplet {    public void init() { . . . }    . . .    public static void main(String[] args) { . . . } } 

What can we put into main? Normally, we make an object of the class and invoke setVisible(true) on it. But this case is not so simple. You cannot call setVisible on a naked applet. The applet must be placed inside a frame.

To provide a frame, we create the class AppletFrame, like this:

 public class AppletFrame extends JFrame {    public AppletFrame(Applet anApplet)    {       applet = anApplet;       add(applet);       . . .    }    . . . } 

The constructor of the frame puts the applet (which is a Component) inside the content pane of the frame.

In the main method of the applet/application, we construct and show an AppletFrame.

 class MyAppletApplication extends JApplet {    public void init() { . . . }    . . .    public static void main(String args[])    {       AppletFrame frame = new AppletFrame(new MyAppletApplication());       frame.setTitle("MyAppletApplication");       frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       frame.setVisible(true);    } } 

When the applet starts, its init and start methods must be called. We achieve this by overriding the setVisible method of the AppletFrame class:

 public void setVisible(boolean b) {    if (b)    {       applet.init();       super.setVisible(true);       applet.start();    }    else    {       applet.stop();       super.setVisible(false);       applet.destroy();    } } 

There is one catch. If the program is started with the Java launcher and not the applet viewer, and it calls getAppletContext, it gets a null pointer because it has not been launched inside a browser. This causes a runtime crash whenever we have code like

 getAppletContext().showStatus(message); 

While we do not want to write a full-fledged browser, we do need to supply the bare minimum to make calls like this work. The call displays no message, but at least it will not crash the program. It turns out that all we need to do is implement two interfaces: AppletStub and AppletContext.

You have already seen applet contexts in action. They are responsible for fetching images and audio files and for displaying web pages. They can, however, politely refuse, and this is what our applet context will do. The major purpose of the AppletStub interface is to locate the applet context. Every applet has an applet stub (set with the setStub method of the Applet class).

In our case, AppletFrame implements both AppletStub and AppletContext. We supply the bare minimum functionality that is necessary to implement these two interfaces.

 public class AppletFrame extends JFrame    implements AppletStub, AppletContext {    . . .    // AppletStub methods    public boolean isActive() { return true; }    public URL getDocumentBase() { return null; }    public URL getCodeBase() { return null; }    public String getParameter(String name) { return ""; }    public AppletContext getAppletContext() { return this; }    public void appletResize(int width, int height) {}    // AppletContext methods    public AudioClip getAudioClip(URL url) { return null; }    public Image getImage(URL url) { return null; }    public Applet getApplet(String name) { return null; }    public Enumeration getApplets() { return null; }    public void showDocument(URL url) {}    public void showDocument(URL url, String target) {}    public void showStatus(String status) {}    public void setStream(String key, InputStream stream) {}    public InputStream getStream(String key) { return null; }    public Iterator getStreamKeys() { return null; } } 

NOTE

When you compile this file with the JDK 1.3 compiler, you will get a warning that the class java.awt.Window also has a method called isActive that has package visibility. Because our class is not in the same package as the Window class, it cannot override the Window.isActive method. That is fine with us we want to supply a new isActive method for the AppletStub interface. And, interestingly enough, it is entirely legal to add a new method with the same signature to the subclass. Whenever the object is accessed through a Window reference inside the java.awt package, the package-visible Window.isActive method is called. But whenever the call is made through an AppletFrame or AppletStub reference, the AppletFrame.isActive method is called.


Next, the constructor of the frame class calls setStub on the applet to make itself its stub.

 public AppletFrame(Applet anApplet) {    applet = anApplet    Container contentPane = getContentPane();    contentPane.add(applet);    applet.setStub(this); } 

One final twist is possible. Suppose we want to use the calculator as an applet and application simultaneously. Rather than moving the methods of the CalculatorApplet class into the CalculatorAppletApplication class, we will just use inheritance. Here is the code for the class that does this.

 public class CalculatorAppletApplication extends CalculatorApplet {    public static void main(String args[])    {       AppletFrame frame = new AppletFrame(new CalculatorApplet());       . . .    } } 

You can do this with any applet, not just with the calculator applet. All you do is derive a class MyAppletApplication from your applet class and pass a new MyApplet() object to the AppletFrame in the main method. The result is a class that is both an applet and an application.

Just for fun, we use the previously mentioned trick of adding the applet tag as a comment to the source file. Then you can invoke the applet viewer with the source file without requiring an additional HTML file.

Examples 10-10 and 10-11 list the code. You need to copy the CalculatorApplet.java file into the same directory to compile the program. Try running both the applet and the application:

 appletviewer CalculatorAppletApplication.java java CalculatorAppletApplication 

Example 10-10. AppletFrame.java
  1. import java.awt.*;  2. import java.awt.event.*;  3. import java.applet.*;  4. import java.io.*;  5. import java.net.*;  6. import java.util.*;  7. import javax.swing.*;  8.  9. public class AppletFrame extends JFrame 10.    implements AppletStub, AppletContext 11. { 12.    public AppletFrame(Applet anApplet) 13.    { 14.       applet = anApplet; 15.       add(applet); 16.       applet.setStub(this); 17.    } 18. 19.    public void setVisible(boolean b) 20.    { 21.       if (b) 22.       { 23.          applet.init(); 24.          super.setVisible(true); 25.          applet.start(); 26.       } 27.       else 28.       { 29.          applet.stop(); 30.          super.setVisible(false); 31.          applet.destroy(); 32.       } 33.    } 34. 35.    // AppletStub methods 36.    public boolean isActive() { return true; } 37.    public URL getDocumentBase() { return null; } 38.    public URL getCodeBase() { return null; } 39.    public String getParameter(String name) { return ""; } 40.    public AppletContext getAppletContext() { return this; } 41.    public void appletResize(int width, int height) {} 42. 43.    // AppletContext methods 44.    public AudioClip getAudioClip(URL url) { return null; } 45.    public Image getImage(URL url) { return null; } 46.    public Applet getApplet(String name) { return null; } 47.    public Enumeration getApplets() { return null; } 48.    public void showDocument(URL url) {} 49.    public void showDocument(URL url, String target) {} 50.    public void showStatus(String status) {} 51.    public void setStream(String key, InputStream stream) {} 52.    public InputStream getStream(String key) { return null; } 53.    public Iterator getStreamKeys() { return null; } 54. 55.    private Applet applet; 56. } 

Example 10-11. CalculatorAppletApplication.java
  1. /*  2.   The applet viewer reads the tags below if you call it with  3.       appletviewer CalculatorAppletApplication.java (!)  4.   No separate HTML file is required.  5.   <applet code="CalculatorAppletApplication.class" width="200" height="200">  6.   </applet>  7. */  8.  9. import javax.swing.*; 10. 11. public class CalculatorAppletApplication 12.    extends CalculatorApplet 13. // It's an applet. It's an application. It's BOTH! 14. { 15.    public static void main(String[] args) 16.    { 17.       AppletFrame frame = new AppletFrame(new CalculatorApplet()); 18.       frame.setTitle("CalculatorAppletApplication"); 19.       frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 20.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 21.       frame.setVisible(true); 22.    } 23. 24.    public static final int DEFAULT_WIDTH = 200; 25.    public static final int DEFAULT_HEIGHT = 200; 26. } 


       
    top



    Core Java 2 Volume I - Fundamentals
    Core Java(TM) 2, Volume I--Fundamentals (7th Edition) (Core Series) (Core Series)
    ISBN: 0131482025
    EAN: 2147483647
    Year: 2003
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net