UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

376 lines (373 loc) 70.1 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>The JApplet Class</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="The JApplet Class"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-23-SECT-2"/>The JApplet Class</h1></div></div></div><p>A <code class="literal">JApplet</code> is a Swing <code class="literal">JPanel</code> with a mission. It is a GUI container that has some extra structure to allow it to be used in the “alien” environment of a web browser. Applets also have a lifecycle that lets them act more like an application than a static component. Although applets tend to be relatively simple, there’s no inherent restriction on their complexity other than the issues of downloading and caching their content. Historically, applets have tended to be small “widgets.”</p><p>The <code class="literal">javax.swing.JApplet</code> class defines the core functionality of an applet. (<a id="I_indexterm23_id824930" class="indexterm"/><code class="literal">java.awt.Applet</code> is the older, AWT-based form.)</p><p>Structurally, an applet is a wrapper for your Java code. In contrast to a standalone graphical Java application, which starts up from a <code class="literal">main()</code> method and creates a GUI, an applet itself is a component that expects to be dropped into someone else’s GUI. Thus, an applet can’t run by itself; it runs in the context of a web browser or a special applet-viewer program (which we’ll talk about later). Instead of having your application create a <code class="literal">JFrame</code> to hold your GUI, you stuff your application inside a <code class="literal">JApplet</code> (which itself extends <code class="literal">Container</code>) and let the browser add your applet to the page.</p><p>Applets are placed on web pages with the <a id="I_indexterm23_id824974" class="indexterm"/><code class="literal">&lt;applet&gt;</code> HTML tag, which we’ll cover later in this chapter. At its simplest, you just specify the name of the applet class and a size in pixels for the applet:</p><a id="I_23_tt1243"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">applet</code> <code class="n">code</code><code class="o">=</code><code class="s">"AnalogClock"</code> <code class="n">width</code><code class="o">=</code><code class="s">"100"</code> <code class="n">height</code><code class="o">=</code><code class="s">"100"</code><code class="o">&gt;&lt;/</code><code class="n">applet</code><code class="o">&gt;</code></pre><p>Pragmatically, an applet is an intruder into someone else’s environment and therefore has to be treated with suspicion. The web browsers that run applets impose restrictions on what the applet is allowed to do. The restrictions are enforced by an applet security manager. The browser provides everything the applet needs through an applet context—the API the applet uses to interact with its environment.</p><p>A <code class="literal">JApplet</code> expects to be embedded in a page and used in a viewing environment that provides it with resources. In all other respects, however, applets are just ordinary <code class="literal">Panel</code> objects. As <a class="xref" href="ch23s03.html#learnjava3-CHP-23-FIG-1" title="Figure 23-1. The java.applet package">Figure 23-1</a> shows, an applet is a kind of <code class="literal">Panel</code>. Like any other <code class="literal">Panel</code>, a <code class="literal">JApplet</code> can contain user interface components and use all the basic drawing and event-handling capabilities of the <code class="literal">Component</code> class. You can draw on a <code class="literal">JApplet</code> by overriding its <a id="I_indexterm23_id825061" class="indexterm"/><code class="literal">paint()</code> method and respond to events in the <code class="literal">JApplet</code>’s display area by providing the appropriate event listeners. Applets also have additional structure that helps them interact with the browser environment.</p><p>Aside from the top-level structure and the security restrictions, there is no difference between an applet and an application. If your application can live within the limits imposed by a browser’s security manager, you can structure it to function as both an applet and a standalone application. Normally, you’ll use your applet class itself only as a thin wrapper to manage the lifecycle and appearance of your application—create the GUI, start, and stop. So, the bulk of your code should be easily adaptable to either a standalone or applet deployment.</p><div class="figure"><a id="learnjava3-CHP-23-FIG-1"/><div class="figure-contents"><div class="mediaobject"><a id="I_23_tt1244"/><img src="httpatomoreillycomsourceoreillyimages1707714.png" alt="The java.applet package"/></div></div><p class="title">Figure 23-1. The java.applet package</p></div><div class="sect2" title="Applet Lifecycle"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.1"/>Applet Lifecycle</h2></div></div></div><p><a id="idx11174" class="indexterm"/> <a id="idx11181" class="indexterm"/>The <code class="literal">Applet</code> class contains four methods that can be overridden to guide it through its lifecycle. The <a id="I_indexterm23_id825151" class="indexterm"/><code class="literal">init()</code>, <a id="I_indexterm23_id825164" class="indexterm"/><code class="literal">start()</code>, <a id="I_indexterm23_id825174" class="indexterm"/><code class="literal">stop()</code>, and <a id="I_indexterm23_id825184" class="indexterm"/><code class="literal">destroy()</code> methods are called by the <code class="literal">appletviewer</code> or web browser to direct the applet’s behavior. <code class="literal">init()</code> is called once, after the applet is created. The <code class="literal">init()</code> method is where you perform basic setup such as parsing parameters, building a user interface, and loading resources.</p><p>By convention, applets don’t provide an explicit constructor to do any setup. The reason for this is that the constructor is meant to be called by the applet’s environment, for simple creation of the applet. This might happen before the applet has access to certain resources, such as information about its environment. Therefore, an applet doesn’t normally do any work there; instead it should rely on the default constructor for the <code class="literal">JApplet</code> class and do its initialization in the <code class="literal">init()</code> method.</p><p>The <code class="literal">start()</code> method is called whenever the applet becomes visible; it shouldn’t be a surprise then that the <code class="literal">stop()</code> method is called whenever the applet becomes invisible. <code class="literal">init()</code> is called only once in the life of an applet, but <code class="literal">start()</code> and <code class="literal">stop()</code> can be called any number of times (although always in the logical sequence). The <code class="literal">start()</code> method is called when the applet is displayed, such as when it scrolls onto the screen; <code class="literal">stop()</code> will be called if the applet scrolls off the screen, or the viewer leaves the document. <code class="literal">start()</code> tells the applet it should be active. The applet may want to create threads, animate, or otherwise perform useful (or annoying) activity. <code class="literal">stop()</code> is called to let the applet know it should go dormant. Applets should cease CPU-intensive or wasteful activity when they are stopped and resume when (and if) they are restarted. However, there’s no requirement that an invisible applet stop computing; in some applications, it may be useful for the applet to continue running in the background. Just be considerate of your user, who doesn’t want an invisible applet dragging down system performance.</p><p>Finally, the <code class="literal">destroy()</code> method gives the applet a last chance to clean up before it’s removed—some time after the last call to <a id="I_indexterm23_id825307" class="indexterm"/><code class="literal">stop()</code>. For example, an applet might want to gracefully close down suspended communications channels at this time. Exactly when <a id="I_indexterm23_id825319" class="indexterm"/><code class="literal">destroy()</code> is called depends on the browser; Netscape calls <code class="literal">destroy()</code> just prior to deleting the applet from its cache. This means that although an applet can cling to life after being told to <code class="literal">stop()</code>, how long it can go on is unpredictable. If you want to maintain an applet as the user progresses through other pages of activities, you may have to put it in an HTML frame, so that it remains visible and won’t be told to <code class="literal">stop()</code> (see <a class="xref" href="ch23s03.html#learnjava3-CHP-23-SECT-2.3.5" title="Applet persistence and navigation">Applet persistence and navigation</a>).</p><p>If you’ve read this entire book up until now, you’ve already seen a couple of applets that snuck in among other topics. In <a class="xref" href="ch09.html" title="Chapter 9. Threads">Chapter 9</a>, we created a simple clock applet, and in <a class="xref" href="ch13.html" title="Chapter 13. Network Programming">Chapter 13</a>, we used an applet to send packets of information from a web browser. Now let’s try a simple Swing-based example using <code class="literal">JApplet</code>. The following example, <code class="literal">ShowApplet</code>, shown in <a class="xref" href="ch23s03.html#learnjava3-CHP-23-FIG-2" title="Figure 23-2. ShowApplet">Figure 23-2</a>, does nothing special, but you can use it to test the version of Java that’s running in your browser (and see if the Plug-in is installed) and to see when the applet is started and stopped. It’s a good reference.</p><a id="I_23_tt1245"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">java.awt.event.*</code><code class="o">;</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">ShowApplet</code> <code class="kd">extends</code> <code class="n">JApplet</code> <code class="o">{</code> <code class="n">JTextArea</code> <code class="n">text</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JTextArea</code><code class="o">();</code> <code class="kt">int</code> <code class="n">startCount</code><code class="o">;</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">init</code><code class="o">()</code> <code class="o">{</code> <code class="n">JButton</code> <code class="n">button</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Press Me"</code><code class="o">);</code> <code class="n">button</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">new</code> <code class="n">ActionListener</code><code class="o">()</code> <code class="o">{</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code> <code class="n">ActionEvent</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="n">text</code><code class="o">.</code><code class="na">append</code><code class="o">(</code><code class="s">"Button Pressed!\n"</code><code class="o">);</code> <code class="o">}</code> <code class="o">}</code> <code class="o">);</code> <code class="n">getContentPane</code><code class="o">().</code><code class="na">add</code><code class="o">(</code> <code class="s">"Center"</code><code class="o">,</code> <code class="k">new</code> <code class="n">JScrollPane</code><code class="o">(</code> <code class="n">text</code> <code class="o">)</code> <code class="o">);</code> <code class="n">JPanel</code> <code class="n">panel</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JPanel</code><code class="o">();</code> <code class="n">panel</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="n">button</code> <code class="o">);</code> <code class="n">getContentPane</code><code class="o">().</code><code class="na">add</code><code class="o">(</code> <code class="s">"South"</code><code class="o">,</code> <code class="n">panel</code> <code class="o">);</code> <code class="n">text</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="s">"Java Version: "</code> <code class="o">+</code><code class="n">System</code><code class="o">.</code><code class="na">getProperty</code><code class="o">(</code><code class="s">"java.version"</code><code class="o">)+</code><code class="s">"\n"</code> <code class="o">);</code> <code class="n">text</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="s">"Applet init()\n"</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">start</code><code class="o">()</code> <code class="o">{</code> <code class="n">text</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="s">"Applet started: "</code><code class="o">+</code> <code class="n">startCount</code><code class="o">++</code> <code class="o">+</code><code class="s">"\n"</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">stop</code><code class="o">()</code> <code class="o">{</code> <code class="n">text</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="s">"Applet stopped.\n"</code> <code class="o">);</code> <code class="o">}</code> <code class="o">}</code></pre><div class="figure"><a id="learnjava3-CHP-23-FIG-2"/><div class="figure-contents"><div class="mediaobject"><a id="I_23_tt1246"/><img src="httpatomoreillycomsourceoreillyimages1707715.png" alt="ShowApplet"/></div></div><p class="title">Figure 23-2. ShowApplet</p></div><p>After compiling the applet, we have to create an HTML page in which to embed it. The following will do:</p><a id="I_23_tt1247"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">html</code><code class="o">&gt;&lt;</code><code class="n">head</code><code class="o">&gt;&lt;</code><code class="n">title</code><code class="o">&gt;</code><code class="n">ShowApplet</code><code class="o">&lt;/</code><code class="n">title</code><code class="o">&gt;&lt;/</code><code class="n">head</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">body</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">applet</code> <code class="n">code</code><code class="o">=</code><code class="s">"ShowApplet"</code> <code class="n">width</code><code class="o">=</code><code class="s">"300"</code> <code class="n">height</code><code class="o">=</code><code class="s">"300"</code><code class="o">&gt;</code> <code class="n">Your</code> <code class="n">browser</code> <code class="n">does</code> <code class="n">not</code> <code class="n">understand</code> <code class="n">Java</code><code class="o">.&lt;/</code><code class="n">applet</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">body</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">html</code><code class="o">&gt;</code></pre><p>We’ll discuss the <code class="literal">applet</code> tag and other issues related to embedding applets in documents in detail later in this chapter. For now, just save this in a file called <span class="emphasis"><em>showapplet.html</em></span>. Load the file with your favorite web browser and see what happens. (We’re assuming you have installed Java on your computer by this point; you may have to enable Java in your browser to see the applet if it is disabled by default.) If you have access to a web server, you can use it. Otherwise, you can open the file locally using either the browser’s Open File menu option or a URL such as:</p><a id="I_23_tt1248"/><pre class="programlisting"> <code class="nl">file:</code><code class="c1">///Users/somedir/showapplet.html</code></pre><p>The applet shows the version of Java running it and prints messages when its button is pressed. If you have installed the latest Java Plug-in you should see “Java version: 1.7” in the box, regardless of which browser you are using (including Microsoft Internet Explorer). The applet prints messages when its <code class="literal">start()</code> and <code class="literal">stop()</code> methods are called, along with a count. You can use this to experiment with different browsers and page-layout configurations to see when your applet is reloaded or restarted. If your browser fails to display the applet with the correct version of Java, don’t worry. Later in this chapter, we’ll talk about how to convert the HTML to force the browser to use the Java Plug-in explicitly.<a id="I_indexterm23_id825493" class="indexterm"/><a id="I_indexterm23_id825500" class="indexterm"/></p></div><div class="sect2" title="The Applet Security Sandbox"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.2"/>The Applet Security Sandbox</h2></div></div></div><p><a id="I_indexterm23_id825514" class="indexterm"/> <a id="idx11186" class="indexterm"/>Applets are quarantined within the browser by an applet <a id="I_indexterm23_id825538" class="indexterm"/><code class="literal">SecurityManager</code>. The <code class="literal">SecurityManager</code> is part of the web browser or <code class="literal">appletviewer</code> application. It is installed before the browser loads any applets and implements the basic restrictions that let the user run untrusted applets (loaded over the Internet) safely. Remember, there are no inherent security restrictions on a standalone Java application. It is the browser that limits what applets are allowed to do using a security policy.</p><p>Most browsers impose the following restrictions on untrusted applets:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>Untrusted applets can’t read or write files on the local host.</p></li><li class="listitem"><p>Untrusted applets can open network connections (sockets) only to the server from which they originated.</p></li><li class="listitem"><p>Untrusted applets can’t start other processes on the local host.</p></li><li class="listitem"><p>Untrusted applets can’t have native methods.</p></li></ul></div><p>The motivation for these restrictions should be fairly obvious: you clearly wouldn’t want a program coming from some random Internet site to access your files or run arbitrary programs. Although untrusted applets can’t directly read and write files on the client side or talk to arbitrary hosts on the network, applets can work with servers to store data and communicate. For example, an applet can use Java’s RMI facility to do processing on its server. An applet can communicate with other applets on the Net by proxy through its server.</p><div class="sect3" title="Trusted applets"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.2.1"/>Trusted applets</h3></div></div></div><p>We’ve been using the term <span class="emphasis"><em>untrusted applet</em></span>, so it should come as no surprise that it is also possible to have such a thing as a <span class="emphasis"><em>trusted applet</em></span>. Applets become trusted through the use of digital signatures, by <a id="I_indexterm23_id825610" class="indexterm"/><span class="emphasis"><em>signing</em></span> the JAR file containing your applet code. Because a signature identifies the applet’s origin unambiguously, the user can distinguish between trusted applets (i.e., applets that come from a site or person you trust not to do anything harmful) and run-of-the-mill untrusted applets. In browser environments that support signing, trusted applets can be granted permission to “go outside” of the applet security sandbox. Trusted applets can be allowed to do all of the things that standalone Java applications can do: read and write files, open network connections to arbitrary machines, and interact with the local operating system by starting processes. Trusted applets still can’t have native methods, but including native methods in an applet would destroy its portability anyway.</p><p>Because signed applets are now a fairly niche topic, we no longer cover them in this chapter. If you need more details on them, please visit the <a class="ulink" href="http://oreil.ly/Java_4E">“extras” page</a> for this book, where we post additional material not included in the book as well as the example source code.<a id="I_indexterm23_id825651" class="indexterm"/></p></div></div><div class="sect2" title="Getting Applet Resources"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.3"/>Getting Applet Resources</h2></div></div></div><p><a id="idx11175" class="indexterm"/>An applet must communicate with its browser or applet viewer. For example, it may need configuration parameters from the HTML document in which it appears. An applet may also need to load images, audio clips, and other items. It may also want to ask the viewer about other applets on the same HTML page in order to communicate with them. To get resources from the environment, applets use the <a id="I_indexterm23_id825683" class="indexterm"/><code class="literal">AppletStub</code> and <a id="I_indexterm23_id825694" class="indexterm"/><code class="literal">AppletContext</code> interfaces, provided by the browser.</p><div class="sect3" title="Applet parameters"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.3.1"/>Applet parameters</h3></div></div></div><p><a id="I_indexterm23_id825712" class="indexterm"/>An applet can get configuration parameters from <a id="I_indexterm23_id825724" class="indexterm"/><code class="literal">&lt;param&gt;</code> tags placed inside the <code class="literal">&lt;applet&gt;</code> tag in the HTML document, as we’ll describe later. You can retrieve these parameters using <code class="literal">Applet</code>’s <a id="I_indexterm23_id825750" class="indexterm"/><code class="literal">getParameter()</code> method. For example, the following code reads parameters called <code class="literal">imageName</code> and <code class="literal">sheep</code> from its HTML page:</p><a id="I_23_tt1249"/><pre class="programlisting"> <code class="n">String</code> <code class="n">imageName</code> <code class="o">=</code> <code class="n">getParameter</code><code class="o">(</code> <code class="s">"imageName"</code> <code class="o">);</code> <code class="k">try</code> <code class="o">{</code> <code class="kt">int</code> <code class="n">numberOfSheep</code> <code class="o">=</code> <code class="n">Integer</code><code class="o">.</code><code class="na">parseInt</code><code class="o">(</code> <code class="n">getParameter</code><code class="o">(</code> <code class="s">"sheep"</code> <code class="o">)</code> <code class="o">);</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code> <code class="n">NumberFormatException</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="cm">/* use default */</code> <code class="o">}</code></pre><p>There is an API that allows an applet to provide information (help) about the parameters it accepts. The applet’s <code class="literal">getParameterInfo()</code> can return an array of string arrays, listing and describing the applet’s parameters. However, it’s unclear that anyone uses this API.</p></div><div class="sect3" title="Applet resources"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.3.2"/>Applet resources</h3></div></div></div><p>An applet can find out where it lives using the <code class="literal">getDocumentBase()</code> and <code class="literal">getCodeBase()</code> methods. <a id="I_indexterm23_id825814" class="indexterm"/><code class="literal">getDocumentBase()</code> returns the base URL of the document in which the applet appears; <code class="literal">getCodeBase()</code> returns the base URL of the <code class="literal">Applet</code>’s class files (these two are often the same). An applet can use these methods to construct relative URLs from which to load other resources from its server, such as images, sounds, and other data. The <a id="I_indexterm23_id825838" class="indexterm"/><code class="literal">getImage()</code> method takes a URL and asks for an image from the viewer environment. The image may be cached or loaded when later used. The <a id="I_indexterm23_id825850" class="indexterm"/><code class="literal">getAudioClip()</code> method, similarly, retrieves sound clips.</p><p>The following example uses <code class="literal">getCodeBase()</code> to construct a URL and load a properties configuration file, located in the same remote directory on the web server as the applet’s class file:</p><a id="I_23_tt1250"/><pre class="programlisting"> <code class="n">Properties</code> <code class="n">props</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Properties</code><code class="o">();</code> <code class="k">try</code> <code class="o">{</code> <code class="n">URL</code> <code class="n">url</code> <code class="o">=</code> <code class="k">new</code> <code class="n">URL</code><code class="o">(</code> <code class="n">getCodeBase</code><code class="o">(),</code> <code class="s">"appletConfig.props"</code> <code class="o">);</code> <code class="n">props</code><code class="o">.</code><code class="na">load</code><code class="o">(</code> <code class="n">url</code><code class="o">.</code><code class="na">openStream</code><code class="o">()</code> <code class="o">);</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code> <code class="n">IOException</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="cm">/* failed */</code> <code class="o">}</code></pre><p>A better way to load resources is by calling the <a id="I_indexterm23_id825885" class="indexterm"/><code class="literal">getResource()</code> and <a id="I_indexterm23_id825895" class="indexterm"/><code class="literal">getResourceAsStream()</code> methods of the <code class="literal">Class</code> class, which search the applet’s JAR files (if any) as well as its codebase, which is an extension of the classpath for applets. The following code loads the same properties file in a more portable way:</p><a id="I_23_tt1251"/><pre class="programlisting"> <code class="n">Properties</code> <code class="n">props</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Properties</code><code class="o">();</code> <code class="k">try</code> <code class="o">{</code> <code class="n">props</code><code class="o">.</code><code class="na">load</code><code class="o">(</code> <code class="n">getClass</code><code class="o">().</code><code class="na">getResourceAsStream</code><code class="o">(</code> <code class="s">"appletConfig.props"</code><code class="o">)</code> <code class="o">);</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code> <code class="n">IOException</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="cm">/* failed */</code> <code class="o">}</code></pre><p>An applet can ask its viewer to retrieve an image by calling the <code class="literal">getImage()</code> method. The location of the image to be retrieved is given as a URL, either absolute or fetched from an applet’s resources:</p><a id="I_23_tt1252"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">MyApplet</code> <code class="kd">extends</code> <code class="n">javax</code><code class="o">.</code><code class="na">swing</code><code class="o">.</code><code class="na">JApplet</code> <code class="o">{</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">init</code><code class="o">()</code> <code class="o">{</code> <code class="k">try</code> <code class="o">{</code> <code class="c1">// absolute URL</code> <code class="n">URL</code> <code class="n">monaURL</code> <code class="o">=</code> <code class="k">new</code> <code class="nf">URL</code><code class="o">(</code> <code class="s">"http://myserver/images/mona_lisa.gif"</code><code class="o">);</code> <code class="n">Image</code> <code class="n">monaImage</code> <code class="o">=</code> <code class="n">getImage</code><code class="o">(</code> <code class="n">monaURL</code> <code class="o">);</code> <code class="c1">// applet resource URL</code> <code class="n">URL</code> <code class="n">daffyURL</code> <code class="o">=</code> <code class="n">getClass</code><code class="o">().</code><code class="na">getResource</code><code class="o">(</code><code class="s">"cartoons/images/daffy.gif"</code><code class="o">);</code> <code class="n">Image</code> <code class="n">daffyDuckImage</code> <code class="o">=</code> <code class="n">getImage</code><code class="o">(</code> <code class="n">daffyURL</code> <code class="o">);</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code> <code class="n">MalformedURLException</code> <code class="n">e</code> <code class="o">)</code> <code class="o">{</code> <code class="c1">// unintelligable url</code> <code class="o">}</code> <code class="o">}</code> <code class="c1">// ...</code> <code class="o">}</code></pre><p>Again, using <code class="literal">getResource()</code> is preferred; it looks for the image in the applet’s JAR file (if there is one), before looking elsewhere in the applet’s classpath on the server. (We’ll talk more later about how classes are located for applets.)</p></div><div class="sect3" title="Driving the browser"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.3.3"/>Driving the browser</h3></div></div></div><p><a id="idx11182" class="indexterm"/>The <span class="emphasis"><em>status line</em></span> is a blurb of text that usually appears somewhere in the web browser’s display, indicating a current activity. An applet can request that some text be placed in the status line with the <code class="literal">showStatus()</code> method. (The browser isn’t required to do anything in response to this call, but most browsers will oblige you.)</p><p>An applet can also ask the browser to show a new document. To do this, the applet makes a call to the <a id="I_indexterm23_id826001" class="indexterm"/><code class="literal">showDocument(url)</code> method of the <code class="literal">AppletContext</code>. You can get a reference to the <a id="I_indexterm23_id826018" class="indexterm"/><code class="literal">AppletContext</code> with the applet’s <a id="I_indexterm23_id826030" class="indexterm"/><code class="literal">getAppletContext()</code> method. Calling <code class="literal">showDocument(url)</code> replaces the currently showing document, which means that your currently running applet will be stopped.</p><p>Another version of <code class="literal">showDocument()</code> takes an additional <code class="literal">String</code> argument to tell the browser where to display the new URL:</p><a id="I_23_tt1253"/><pre class="programlisting"> <code class="n">getAppletContext</code><code class="o">().</code><code class="na">showDocument</code><code class="o">(</code> <code class="n">url</code><code class="o">,</code> <code class="n">name</code> <code class="o">);</code></pre><p>The <code class="literal">name</code> argument can be the name of an existing labeled HTML frame; the document referenced by the URL is displayed in that frame. You can use this method to create an applet that “drives” the browser to new locations dynamically but keeps itself active on the screen in a separate frame. This is common for applets that act like navigation controls or menus. If the named frame doesn’t exist, the browser creates a new top-level window to hold it. Alternatively, <code class="literal">name</code> can have one of the following special values:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">self</code></span></dt><dd><p><a id="I_indexterm23_id826100" class="indexterm"/>Show in the current frame</p></dd><dt><span class="term"><code class="literal">_parent</code></span></dt><dd><p><a id="I_indexterm23_id826115" class="indexterm"/>Show in the parent of our frame</p></dd><dt><span class="term"><code class="literal">_top</code></span></dt><dd><p><a id="I_indexterm23_id826132" class="indexterm"/>Show in outermost (top-level) frame</p></dd><dt><span class="term"><code class="literal">_blank</code></span></dt><dd><p><a id="I_indexterm23_id826150" class="indexterm"/>Show in a new top-level browser window</p></dd></dl></div><p>Both <code class="literal">showStatus()</code> and <code class="literal">showDocument()</code> requests may be ignored by a cold-hearted viewer or web browser. Nothing in browser-land is ever certain.<a id="I_indexterm23_id826172" class="indexterm"/></p></div><div class="sect3" title="Inter-applet communication"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.3.4"/>Inter-applet communication</h3></div></div></div><p><a id="idx11183" class="indexterm"/>Although it’s not very common, applets that are embedded in documents loaded from the same location on a website can use a simple mechanism to locate one another and coordinate their activities on a page. Once an applet has a reference to another applet, it can communicate with it just as with any other object, by invoking methods and sending events. The <a id="I_indexterm23_id826207" class="indexterm"/><code class="literal">getApplet()</code> method of the applet context looks for an applet by name:</p><a id="I_23_tt1254"/><pre class="programlisting"> <code class="n">Applet</code> <code class="n">clock</code> <code class="o">=</code> <code class="n">getAppletContext</code><code class="o">().</code><code class="na">getApplet</code><code class="o">(</code><code class="s">"theClock"</code><code class="o">);</code></pre><p>Give an applet a name within your HTML document using the <code class="literal">name</code> attribute of the <code class="literal">&lt;applet&gt;</code> tag. Alternatively, you can use the <a id="I_indexterm23_id826241" class="indexterm"/><code class="literal">getApplets()</code> method to enumerate all the available applets in the pages.</p><p>The tricky thing with applet communications is that applets run inside the security sandbox. An untrusted applet can “see” and communicate only with objects that were loaded by the same class loader. Currently, the only reliable criterion for when applets share a class loader is when they share a common base URL. For example, all the applets contained in web pages loaded from the base URL of <span class="emphasis"><em>http://foo.bar.com/mypages/</em></span> should share a class loader and should be able to see each other. This includes documents such as <span class="emphasis"><em>mypages/foo.html</em></span> and <span class="emphasis"><em>mypages/bar.html</em></span>, but not <span class="emphasis"><em>mypages/morestuff/foo.html</em></span>.</p><p>When applets do share a class loader, other techniques are possible, too. As with any other class, you can call static methods in applets by name. So you could use static methods in one of your applets as a “registry” to coordinate your activities.</p></div><div class="sect3" title="Applet persistence and navigation"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-23-SECT-2.3.5"/>Applet persistence and navigation</h3></div></div></div><p><a id="I_indexterm23_id826296" class="indexterm"/>One of the biggest shortcomings of the Applet API is the lack of a real context for coordinating their activities during navigation across a multipage document or web application. The Applet API simply wasn’t designed for this. Although an applet’s life cycle is well defined in terms of its API, it is not well defined in terms of management by the browser or scope of visibility. As we described in the previous section, applets loaded from the same codebase can rendezvous at runtime using their name attributes. But there are no guarantees about how long an applet will live—or whether it will be stopped as opposed to being destroyed—once it is out of view. If you experiment with our <code class="literal">ShowApplet</code> in various browsers and in the Java Plug-in (which we’ll discuss later), you’ll see that, in some cases, the applet is stopped and restarted when the user leaves the page, but more often the applet is reinitialized from scratch. This makes designing multipage applications that work in all browsers difficult.</p><p>One solution has been to use static methods as a shared “registry,” as mentioned earlier. However, the details governing how classes loaded by applets are managed are even less well-defined than the management of the applets themselves. In Java 1.4, a pair of methods was added to the <a id="I_indexterm23_id826335" class="indexterm"/><code class="literal">AppletContext</code> to support short-term applet persistence: <a id="I_indexterm23_id826346" class="indexterm"/><code class="literal">setStream()</code> and <a id="I_indexterm23_id826357" class="indexterm"/><code class="literal">getStream()</code>. With these methods, an applet can ask the context to save a stream of byte data by a key value and return it later. The notion of providing the state to the context as a stream is a little odd, but easy enough to accommodate. Here is an example:</p><a id="I_23_tt1255"/><pre class="programlisting"> <code class="n">getAppletContext</code><code class="o">.</code><code class="na">setStream</code><code class="o">(</code><code class="s">"myStream"</code><code class="o">,</code> <code class="k">new</code> <code class="nf">ByteArrayInputStream</code><code class="o">(</code> <code class="s">"This is some test data..."</code><code class="o">.</code><code class="na">getBytes</code><code class="o">()</code> <code class="o">)</code> <code class="o">);</code></pre><p>Later, the stream data can be retrieved:</p><a id="I_23_tt1256"/><pre class="programlisting"> <code class="n">InputStream</code> <code class="n">in</code> <code class="o">=</code> <code class="n">getAppletContext</code><code class="o">.</code><code class="na">getStream</code><code class="o">(</code> <code class="s">"myStream"</code> <code class="o">);</code></pre><p>Currently, the data is retained only as long as the browser is running. If you need more complex state and navigation capabilities, you might consider using a signed applet to write to a file or taking advantage of the Java Web Start API to install your application locally.<a id="I_indexterm23_id826396" class="indexterm"/></p></div></div><div class="sect2" title="The &lt;applet&gt; Tag"><div class="titlepage"><div><div><h2 class="title"><a id="id2136142"/>The &lt;applet&gt; Tag</h2></div></div></div><p><a id="idx11173" class="indexterm"/> <a id="idx11180" class="indexterm"/>Applets are embedded in HTML documents with the <code class="literal">&lt;applet&gt;</code> tag. The <code class="literal">&lt;applet&gt;</code> tag resembles the HTML <code class="literal">&lt;img&gt;</code> image tag. It contains attributes that identify the applet to be displayed and, optionally, give the web browser hints about how it should be shown.<sup>[<a id="learnjava3-CHP-23-FN-1" href="#ftn.learnjava3-CHP-23-FN-1" class="footnote">48</a>]</sup></p><p>The standard image tag sizing and alignment attributes, such as <code class="literal">height</code> and <code class="literal">width</code>, can be used inside the applet tag. However, unlike images, applets have both an opening <code class="literal">&lt;applet&gt;</code> and a closing <code class="literal">&lt;/applet&gt;</code> tag. Sandwiched between these can be any number of <code class="literal">&lt;param&gt;</code> tags that contain configuration data to be passed to the applet:<a id="I_indexterm23_id826515" class="indexterm"/><a id="I_indexterm23_id826522" class="indexterm"/></p><a id="I_23_tt1259"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">applet</code> <em class="replaceable"><code><code class="n">attribute</code></code></em><em class="replaceable"><code><code class="n">attribute</code></code></em> <code class="o">...</code> <code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">param</code> <em class="replaceable"><code><code class="n">parameter</code></code></em> <code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">param</code> <em class="replaceable"><code><code class="n">parameter</code></code></em> <code class="o">&gt;</code> <code class="o">...</code> <code class="o">&lt;/</code><code class="n">applet</code><code class="o">&gt;</code></pre></div><div class="sect2" title="Attributes"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.4"/>Attributes</h2></div></div></div><p><a id="idx11177" class="indexterm"/> <a id="I_indexterm23_id826572" class="indexterm"/>Attributes are name/value pairs that are interpreted by a web browser or applet viewer. Attributes of the <code class="literal">&lt;applet&gt;</code> tag specify general features that apply to any applet, such as size and alignment. The definition of the <code class="literal">&lt;applet&gt;</code> tag lists a fixed set of recognized attributes; specifying an incorrect or nonexistent attribute should be considered an HTML error.</p><p>Three attributes are required in the <code class="literal">&lt;applet&gt;</code> tag. Two of these attributes, <a id="I_indexterm23_id826603" class="indexterm"/><code class="literal">width</code> and <a id="I_indexterm23_id826613" class="indexterm"/><code class="literal">height</code>, specify the space that the applet occupies on the screen. The third required attribute must be either <a id="I_indexterm23_id826625" class="indexterm"/><code class="literal">code</code> or <code class="literal">object</code>; you must supply one of these attributes, and you can’t specify both. The <code class="literal">code</code> attribute specifies the class file from which the applet is loaded; the <code class="literal">object</code> attribute specifies a serialized representation of an applet. Most often, you’ll use the <code class="literal">code</code> attribute.</p><p>The following is an HTML fragment for a simple clock applet that takes no parameters and requires no special HTML layout:</p><a id="I_23_tt1260"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">applet</code> <code class="n">code</code><code class="o">=</code><code class="s">"AnalogClock"</code> <code class="n">width</code><code class="o">=</code><code class="s">"100"</code> <code class="n">height</code><code class="o">=</code><code class="s">"100"</code><code class="o">&gt;&lt;/</code><code class="n">applet</code><code class="o">&gt;</code></pre><p>The HTML file that contains this <code class="literal">&lt;applet&gt;</code> tag must be stored in the same directory as the <span class="emphasis"><em>AnalogClock.class</em></span> class file. The applet tag is not sensitive to spacing in the HTML, so the previous tag could be also be formatted a little more readably like so:<a id="I_indexterm23_id826686" class="indexterm"/></p><a id="I_23_tt1261"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">applet</code> <code class="n">code</code><code class="o">=</code><code class="s">"AnalogClock"</code> <code class="n">width</code><code class="o">=</code><code class="s">"100"</code> <code class="n">height</code><code class="o">=</code><code class="s">"100"</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">applet</code><code class="o">&gt;</code></pre></div><div class="sect2" title="Parameters"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.5"/>Parameters</h2></div></div></div><p><a id="I_indexterm23_id826710" class="indexterm"/> <a id="I_indexterm23_id826720" class="indexterm"/>Parameters are analogous to command-line arguments; they provide a way to pass information to an applet. Each <a id="I_indexterm23_id826730" class="indexterm"/><code class="literal">&lt;param&gt;</code> tag contains a name and a value that are passed as string values to the applet:</p><a id="I_23_tt1262"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">param</code> <code class="n">name</code> <code class="o">=</code> <em class="replaceable"><code><code class="s">"parameter_name"</code></code></em> <code class="n">value</code> <code class="o">=</code> <em class="replaceable"><code><code class="s">"parameter_value"</code></code></em><code class="o">&gt;</code></pre><p>Parameters provide a means of embedding application-specific data and configuration information within an HTML document. Our <code class="literal">AnalogClock</code> applet, for example, might accept a parameter that selects between local and universal time:</p><a id="I_23_tt1263"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">applet</code> <code class="n">code</code><code class="o">=</code><code class="s">"AnalogClock"</code> <code class="n">width</code><code class="o">=</code><code class="s">"100"</code> <code class="n">height</code><code class="o">=</code><code class="s">"100"</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">param</code> <code class="n">name</code><code class="o">=</code><code class="s">"zone"</code> <code class="n">value</code><code class="o">=</code><code class="s">"GMT"</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">applet</code><code class="o">&gt;</code></pre><p>Presumably, this <code class="literal">AnalogClock</code> applet is designed to look for a parameter named <code class="literal">zone</code> with a possible value of <code class="literal">GMT</code>.</p><p>Parameter names and values should be quoted and can contain spaces and other whitespace characters. The parameters a given applet expects are, of course, determined by the developer of that applet. There is no standard set of parameter names or values; it’s up to the applet to interpret the parameter name/value pairs that are passed to it. Any number of parameters can be specified, and the applet may choose to use or ignore them as it sees fit.</p></div><div class="sect2" title="¿Habla Applet?"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-23-SECT-2.6"/>¿Habla Applet?</h2></div></div></div><p>Web browsers are supposed to ignore tags they don’t understand; if