Java ScreenShot
     

Screenshot Core Java 2: Volume I - Fundamentals

Table of Contents
 10.  Deploying Applets and apps


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 show 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 show 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 String) 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" >


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 will 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.

Displaying 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");


Java graphics exclamatory_icon.gif

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.oracle.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. The second argument is a string. If it is the special string "_blank", the browser opens a new window with the document, instead of displacing the current document. More importantly, 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 will show you an example of how to do this in the next section. Table 10-2 shows all possible arguments to showDocument.

Table 10-2. showDocument arguments

Second Argument to showDocument

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.

java.applet.Applet 1.2

Java graphics api_icon.gif
  • 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.

  • AudioClip getAudioClip(URL url)

    returns an AudioClip object, which stores the sound file specified by the URL. Use the play method to actually play the file.

java.applet.AppletContext 1.2

Java graphics api_icon.gif
  • 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 string to identify the target frame. The target string can be one of the following: "_self" (show in current frame, equivalent to the first form of the method), "_parent" (show in parent frame), "_top" (show in topmost frame), and "_blank" (show in new, unnamed, top-level window). Or, the target string can be the name of a frame.

Java graphics exclamatory_icon.gif

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

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 tutorialmarks. When you select any of the tutorialmarks, the applet then goes to the corresponding web page and displays it on the right (see Screenshot-8).

Screenshot-8. A tutorialmark applet

Java graphics 10fig08.jpg


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 src="left.html"
 7. margin margin
 8. scrolling="no" noresize="noresize"/>
 9. <frame src="right.html"
10. margin margin
11. scrolling="yes" noresize="noresize"/>
12. </frameset>
13. </html>


We will 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 (Example 10-7) loads a file that we called Left.html, which loads the applet into the left frame. It simply specifies the applet and the tutorialmarks. You can customize this file for your own web page by changing the tutorialmarks.

Example 10-7 Left.html
 1. <html>
 2. <title>A Bookmark Applet</title>
 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" >
10. <param name="link.1" value="http://java.oracle.com"/>
11. <param name="link.2" value="http://www.gamelan.com"/>
12. <param name="link.3" value="http://www.zhongwen.com"/>
13. <param name="link.4" value="http://www.horstmann.com"/>
14. <param name="link.5" value="http://www.prenhall.com"/>
15. <param name="link.6" value="http://usps.com"/>
16. <param name="link.7" value="http://www.netscape.com"/>
17. </applet>
18. </body>
19. </html>


The right frame (Example 10-8) loads a dummy file that we called Right.html. (Netscape did not approve when we left the right frame blank, so we gave it a dummy file for starters.)

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


The code for the tutorialmark 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
32. // the "right" frame
33. button.addActionListener(new
34. ActionListener()
35. {
36. public void actionPerformed(ActionEvent event)
37. {
38. AppletContext context = getAppletContext();
39. context.showDocument(url, "right");
40. }
41. });
42. }
43. catch(MalformedURLException exception)
44. {
45. exception.printStackTrace();
46. }
47.
48. i++;
49. }
50.
51. Container contentPane = getContentPane();
52. contentPane.add(box);
53. }
54. }


It's an Applet. It's an app. 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 will show you how to write a Java program that is both an applet and an app. 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 interpreter. 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 app and viewed inside the applet viewer as an applet.

Screenshot-9. The calculator as an app

Java graphics 10fig09.gif


Screenshot-10. The calculator as an applet

Java graphics 10fig10.gif


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

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


What can we put into main? Normally, we make an object of the class and invoke show on it. But this case is not so simple. You cannot show a naked applet. The applet must be placed inside a frame. And once it is inside the frame, its init method needs to be called. To provide a frame, we create the class AppletFrame, like this:

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


The constructor of the frame puts the applet (which derives from Component) inside the frame. In the main method of the applet/app, we make a new frame of this kind.

class MyAppletapp extends JApplet
{
 public void init() { . . . }
 . . .
 public static void main(String args[])
 {
 AppletFrame frame
 = new AppletFrame(new MyAppletapp());
 frame.setTitle("MyAppletapp");
 frame.setSize(WIDTH, HEIGHT);
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 frame.show();
 }
}


There is one catch. If the program is started with the Java interpreter 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;
}


Java graphics notes_icon.gif

When you compile this file with the SDK 1.3 compiler, you will get a warning that java.awt.Window also has a method called isActive that has package visibility. Since this 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 object is accessed 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 app simultaneously. Rather than moving the methods of the CalculatorApplet class into the CalculatorAppletapp class, we will just use inheritance. Here is the code for the class that does this.

public class CalculatorAppletapp 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 need to do is derive a class MyAppletapp 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 app. 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 app:

appletviewer CalculatorAppletapp.java java CalculatorAppletapp


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. Container contentPane = getContentPane();
16. contentPane.add(applet);
17. applet.setStub(this);
18. }
19.
20. public void show()
21. {
22. applet.init();
23. super.show();
24. applet.start();
25. }
26.
27. // AppletStub methods
28. public boolean isActive() { return true; }
29. public URL getDocumentBase() { return null; }
30. public URL getCodeBase() { return null; }
31. public String getParameter(String name) { return ""; }
32. public AppletContext getAppletContext() { return this; }
33. public void appletResize(int width, int height) {}
34.
35. // AppletContext methods
36. public AudioClip getAudioClip(URL url) { return null; }
37. public Image getImage(URL url) { return null; }
38. public Applet getApplet(String name) { return null; }
39. public Enumeration getApplets() { return null; }
40. public void showDocument(URL url) {}
41. public void showDocument(URL url, String target) {}
42. public void showStatus(String status) {}
43. public void setStream(String key, InputStream stream) {}
44. public InputStream getStream(String key) { return null; }
45. public Iterator getStreamKeys() { return null; }
46.
47. private Applet applet;
48. }


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


Screenshot

Java ScreenShot
     
Top
 

Comments