A JApplet
is a Swing JPanel
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.”
The javax.swing.JApplet
class
defines the core functionality of an applet. (java.awt.Applet
is the
older, AWT-based form.)
Structurally, an applet is a wrapper for your Java code. In contrast
to a standalone graphical Java application, which starts up from a
main()
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 JFrame
to hold your GUI, you stuff your
application inside a JApplet
(which
itself extends Container
) and let the
browser add your applet to the page.
Applets are placed on web pages with the <applet>
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:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
></
applet
>
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.
A JApplet
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
Panel
objects. As Figure 23-1 shows, an applet is a kind of
Panel
. Like any other Panel
, a JApplet
can contain user interface components
and use all the basic drawing and event-handling capabilities of the
Component
class. You can draw on a
JApplet
by overriding its paint()
method and
respond to events in the JApplet
’s
display area by providing the appropriate event listeners. Applets also
have additional structure that helps them interact with the browser
environment.
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.
The Applet
class
contains four methods that can be overridden to guide it through its
lifecycle. The init()
, start()
, stop()
, and destroy()
methods are
called by the appletviewer
or web
browser to direct the applet’s behavior. init()
is called once, after the applet is
created. The init()
method is where
you perform basic setup such as parsing parameters, building a user
interface, and loading resources.
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 JApplet
class and
do its initialization in the init()
method.
The start()
method is called
whenever the applet becomes visible; it shouldn’t be a surprise then
that the stop()
method is called
whenever the applet becomes invisible. init()
is called only once in the life of an
applet, but start()
and stop()
can be called any number of times
(although always in the logical sequence). The start()
method is called when the applet is
displayed, such as when it scrolls onto the screen; stop()
will be called if the applet scrolls
off the screen, or the viewer leaves the document. start()
tells the applet it should be active.
The applet may want to create threads, animate, or otherwise perform
useful (or annoying) activity. stop()
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.
Finally, the destroy()
method
gives the applet a last chance to clean up before it’s removed—some time
after the last call to stop()
. For example, an
applet might want to gracefully close down suspended communications
channels at this time. Exactly when destroy()
is called
depends on the browser; Netscape calls destroy()
just prior to deleting the applet
from its cache. This means that although an applet can cling to life
after being told to stop()
, 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
stop()
(see Applet persistence and navigation).
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 Chapter 9, we created a simple clock applet, and in
Chapter 13, we used an applet to send packets
of information from a web browser. Now let’s try a simple Swing-based
example using JApplet
. The following
example, ShowApplet
, shown in Figure 23-2, 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.
import
javax.swing.*
;
import
java.awt.event.*
;
public
class
ShowApplet
extends
JApplet
{
JTextArea
text
=
new
JTextArea
();
int
startCount
;
public
void
init
()
{
JButton
button
=
new
JButton
(
"Press Me"
);
button
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
e
)
{
text
.
append
(
"Button Pressed!\n"
);
}
}
);
getContentPane
().
add
(
"Center"
,
new
JScrollPane
(
text
)
);
JPanel
panel
=
new
JPanel
();
panel
.
add
(
button
);
getContentPane
().
add
(
"South"
,
panel
);
text
.
append
(
"Java Version: "
+
System
.
getProperty
(
"java.version"
)+
"\n"
);
text
.
append
(
"Applet init()\n"
);
}
public
void
start
()
{
text
.
append
(
"Applet started: "
+
startCount
++
+
"\n"
);
}
public
void
stop
()
{
text
.
append
(
"Applet stopped.\n"
);
}
}
After compiling the applet, we have to create an HTML page in which to embed it. The following will do:
<
html
><
head
><
title
>
ShowApplet
</
title
></
head
>
<
body
>
<
applet
code
=
"ShowApplet"
width
=
"300"
height
=
"300"
>
Your
browser
does
not
understand
Java
.</
applet
>
</
body
>
</
html
>
We’ll discuss the applet
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
showapplet.html. 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:
file:
///Users/somedir/showapplet.html
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 start()
and stop()
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.
Applets are quarantined within the browser by an applet
SecurityManager
. The
SecurityManager
is part of the web
browser or appletviewer
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.
Most browsers impose the following restrictions on untrusted applets:
Untrusted applets can’t read or write files on the local host.
Untrusted applets can open network connections (sockets) only to the server from which they originated.
Untrusted applets can’t start other processes on the local host.
Untrusted applets can’t have native methods.
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.
We’ve been using the term untrusted applet, so it should come as no surprise that it is also possible to have such a thing as a trusted applet. Applets become trusted through the use of digital signatures, by signing 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.
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 “extras” page for this book, where we post additional material not included in the book as well as the example source code.
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 AppletStub
and
AppletContext
interfaces, provided by the browser.
An applet can get configuration parameters from
<param>
tags
placed inside the <applet>
tag in the HTML document, as we’ll describe later. You can retrieve
these parameters using Applet
’s
getParameter()
method. For example, the following code reads parameters called
imageName
and sheep
from its HTML page:
String
imageName
=
getParameter
(
"imageName"
);
try
{
int
numberOfSheep
=
Integer
.
parseInt
(
getParameter
(
"sheep"
)
);
}
catch
(
NumberFormatException
e
)
{
/* use default */
}
There is an API that allows an applet to provide information
(help) about the parameters it accepts. The applet’s getParameterInfo()
can return an array of
string arrays, listing and describing the applet’s parameters.
However, it’s unclear that anyone uses this API.
An applet can find out where it lives using the getDocumentBase()
and getCodeBase()
methods. getDocumentBase()
returns the base URL of the document in which the applet appears;
getCodeBase()
returns the base URL
of the Applet
’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 getImage()
method
takes a URL and asks for an image from the viewer environment. The
image may be cached or loaded when later used. The getAudioClip()
method, similarly, retrieves sound clips.
The following example uses getCodeBase()
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:
Properties
props
=
new
Properties
();
try
{
URL
url
=
new
URL
(
getCodeBase
(),
"appletConfig.props"
);
props
.
load
(
url
.
openStream
()
);
}
catch
(
IOException
e
)
{
/* failed */
}
A better way to load resources is by calling the getResource()
and
getResourceAsStream()
methods of the Class
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:
Properties
props
=
new
Properties
();
try
{
props
.
load
(
getClass
().
getResourceAsStream
(
"appletConfig.props"
)
);
}
catch
(
IOException
e
)
{
/* failed */
}
An applet can ask its viewer to retrieve an image by calling the
getImage()
method. The location of
the image to be retrieved is given as a URL, either absolute or
fetched from an applet’s resources:
public
class
MyApplet
extends
javax
.
swing
.
JApplet
{
public
void
init
()
{
try
{
// absolute URL
URL
monaURL
=
new
URL
(
"http://myserver/images/mona_lisa.gif"
);
Image
monaImage
=
getImage
(
monaURL
);
// applet resource URL
URL
daffyURL
=
getClass
().
getResource
(
"cartoons/images/daffy.gif"
);
Image
daffyDuckImage
=
getImage
(
daffyURL
);
}
catch
(
MalformedURLException
e
)
{
// unintelligable url
}
}
// ...
}
Again, using getResource()
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.)
The status line 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 showStatus()
method. (The browser isn’t
required to do anything in response to this call, but most browsers
will oblige you.)
An applet can also ask the browser to show a new document. To do
this, the applet makes a call to the showDocument(url)
method of the AppletContext
. You
can get a reference to the AppletContext
with
the applet’s getAppletContext()
method. Calling showDocument(url)
replaces the currently showing document, which means that your
currently running applet will be stopped.
Another version of showDocument()
takes an additional String
argument to tell the browser where to
display the new URL:
getAppletContext
().
showDocument
(
url
,
name
);
The name
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, name
can
have one of the following special values:
Both showStatus()
and
showDocument()
requests may be
ignored by a cold-hearted viewer or web browser. Nothing in
browser-land is ever certain.
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 getApplet()
method of
the applet context looks for an applet by name:
Applet
clock
=
getAppletContext
().
getApplet
(
"theClock"
);
Give an applet a name within your HTML document using the
name
attribute of the <applet>
tag. Alternatively, you can
use the getApplets()
method
to enumerate all the available applets in the pages.
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 http://foo.bar.com/mypages/ should share a class loader and should be able to see each other. This includes documents such as mypages/foo.html and mypages/bar.html, but not mypages/morestuff/foo.html.
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.
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 ShowApplet
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.
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 AppletContext
to
support short-term applet persistence: setStream()
and
getStream()
. 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:
getAppletContext
.
setStream
(
"myStream"
,
new
ByteArrayInputStream
(
"This is some test data..."
.
getBytes
()
)
);
Later, the stream data can be retrieved:
InputStream
in
=
getAppletContext
.
getStream
(
"myStream"
);
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.
Applets are embedded in HTML documents with the <applet>
tag. The <applet>
tag resembles the HTML <img>
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.[48]
The standard image tag sizing and alignment attributes, such as
height
and width
, can be used inside the applet tag.
However, unlike images, applets have both an opening <applet>
and a closing </applet>
tag. Sandwiched between these
can be any number of <param>
tags that contain configuration data to be passed to the
applet:
<
applet
attribute
attribute
...
>
<
param
parameter
>
<
param
parameter
>
...
</
applet
>
Attributes are name/value pairs that are interpreted by a
web browser or applet viewer. Attributes of the <applet>
tag specify general features
that apply to any applet, such as size and alignment. The definition of
the <applet>
tag lists a fixed
set of recognized attributes; specifying an incorrect or nonexistent
attribute should be considered an HTML error.
Three attributes are required in the <applet>
tag. Two of these attributes,
width
and height
, specify the
space that the applet occupies on the screen. The third required
attribute must be either code
or object
; you must supply one of these
attributes, and you can’t specify both. The code
attribute specifies the class file from
which the applet is loaded; the object
attribute specifies a serialized
representation of an applet. Most often, you’ll use the code
attribute.
The following is an HTML fragment for a simple clock applet that takes no parameters and requires no special HTML layout:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
></
applet
>
The HTML file that contains this <applet>
tag must be stored in the same
directory as the AnalogClock.class 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:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
>
</
applet
>
Parameters are analogous to command-line arguments; they
provide a way to pass information to an applet. Each <param>
tag
contains a name and a value that are passed as string values to the
applet:
<
param
name
=
"parameter_name"
value
=
"parameter_value"
>
Parameters provide a means of embedding application-specific data
and configuration information within an HTML document. Our AnalogClock
applet, for example, might accept
a parameter that selects between local and universal time:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
>
<
param
name
=
"zone"
value
=
"GMT"
>
</
applet
>
Presumably, this AnalogClock
applet is designed to look for a parameter named zone
with a possible value of GMT
.
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.
Web browsers are supposed to ignore tags they don’t understand; if
the web browser doesn’t know about the <applet>
or <param>
tags, we would expect them to
disappear, and any HTML between the <applet>
and </applet>
tags to appear normally. By
convention, Java-enabled web browsers ignore any extra HTML between the
<applet>
and </applet>
tags. Combined, this means we
can place some alternative HTML inside the <applet>
tag, which is displayed only by
web browsers that can’t run the applet.
For our AnalogClock
example, we
could display a small text explanation and an image of the clock applet
as a teaser:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
>
<
param
name
=
"zone"
value
=
"GMT"
>
<
strong
>
If
you
see
this
,
you
don
'
t
have
a
Java
-
enabled
Web
browser
.
Here
'
s
a
picture
of
what
you
are
missing
.</
strong
>
<
img
src
=
"clockface.gif"
>
</
applet
>
We’ll now spell out the complete syntax for the <applet>
tag:
<
applet
code
=
class_name
or:
object
=
serialized_applet_name
width
=
pixels_high
height
=
pixels_wide
[
codebase
=
location_URL
]
[
archive
=
comma_separated_list_of_archive_files
]
[
name
=
applet_instance_name
]
[
alt
=
alternate_text
]
[
align
=
style
]
[
vspace
=
vertical
pad
pixels
]
[
hspace
=
horizontal
pad
pixels
]
>
[
<
param
name
=
parameter_name
value
=
parameter_value
>
]
[
<
param
...
]
[
HTML
code
for
non
-
Java
-
aware
browsers
]
</
applet
>
Either the code
attribute or
the object
attribute must be present
to specify the applet to run. The code
attribute specifies the applet’s class
file; you’ll see this most frequently. The object
attribute specifies a serialized
representation of an applet. When you use the object
attribute to load an applet, the
applet’s init()
method is not called.
However, the serialized applet’s start()
method is called.
The width
, height
, align
, vspace
, and hspace
attributes determine the preferred
size, alignment, and padding, respectively. The width
and height
attributes are required.
The codebase
attribute
specifies the base URL to be searched for the applet’s class files. If
this attribute isn’t present, the browser looks in the same location as
the HTML file. The archive
attribute
specifies a list of JAR or ZIP files in which the applet’s class files
are located. To put two or more files in the list, separate the
filenames with commas; for example, the following attribute tells the
browser to load and search three archives for the applet’s
classes:
archive
=
"Part1.jar,Part2.jar,Utilities.jar"
The archive files listed by the archive
tag are loaded from the codebase URL.
When searching for classes, a browser checks the archives before
searching any other locations on the server.
The alt
attribute specifies
alternate text that is displayed by browsers that understand the
<applet>
tag and its attributes
but have Java disabled or don’t run applets. This attribute can also
describe the applet because in this case, any alternate HTML between
<applet>
and </applet>
is, by convention, ignored by
Java-enabled browsers.
The name
attribute
specifies an instance name for the executing applet. This is a name
specified as a unique label for each copy of an applet on a particular
HTML page. For example, if we include our clock twice on the same page
(using two applet tags), we should give each instance a unique name to
differentiate them:
<
applet
code
=
"AnalogClock"
name
=
"bigClock"
width
=
"300"
height
=
"300"
>
</
applet
>
<
applet
code
=
"AnalogClock"
name
=
"smallClock"
width
=
"50"
height
=
"50"
>
</
applet
>
Applets can use instance names to recognize and communicate with
other applets on the same page. We could, for instance, create a “clock
setter” applet that knows how to set the time on an AnalogClock
applet and pass it the instance
name of a particular target clock on this page as a parameter. This
might look something like:
<
applet
code
=
"ClockSetter"
>
<
param
name
=
"clockToSet"
value
=
"bigClock"
>
</
applet
>
The code
attribute of
the <applet>
tag
should specify the name of an applet. This is either a simple class name
or a package path and class name. For now, let’s look at simple class
names; we’ll discuss packages in a moment. By default, the Java runtime
system looks for the class file in the same location as the HTML
document that contains it. This location is known as the base
URL for the document.
Consider an HTML document, clock.html, that contains our clock applet example:
<
applet
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
></
applet
>
Let’s say we retrieve the document at the following URL:
http:
//www.time.ch/documents/clock.html
Java tries to retrieve the applet class file from the same base location:
http:
//www.time.ch/documents/AnalogClock.class
The codebase
attribute of the
<applet>
tag specifies an
alternative base URL for the class file search. Let’s say our HTML
document now specifies codebase
, as
in the following example:
<
applet
codebase
=
"http://www.joes.ch/stuff/"
code
=
"AnalogClock"
width
=
"100"
height
=
"100"
>
</
applet
>
Java now looks for the applet class file at:
http:
//www.joes.ch/stuff/AnalogClock.class
For “loose” applet class files that are not packaged into archives, Java uses the standard package name to directory path mapping to locate files on the server. The only difference is that the requests are not local file lookups, but instead are requests to the web server at the applet’s codebase URL. Before a class file is retrieved from a server, its package name component is translated by the client into a relative pathname under the applet’s codebase.
Let’s suppose that our AnalogClock
has been placed into a package
called time.clock
(a subordinate
package for clock-related classes, within a package for time-related
classes). The fully qualified name of our class is time.clock.AnalogClock
. Our simple <applet>
tag would now look like:
<
applet
code
=
"time.clock.AnalogClock"
width
=
"100"
height
=
"100"
></
applet
>
Let’s say the clock.html document is once again retrieved from:
http:
//www.time.ch/documents/clock.html
Java now looks for the class file in the following location:
http:
//www.time.ch/documents/time/clock/AnalogClock.class
The same is true when specifying an alternative codebase
:
<
applet
codebase
=
"http://www.joes.ch/stuff/"
code
=
"time.clock.AnalogClock"
width
=
"100"
height
=
"100"
>
</
applet
>
Java now tries to find the class in the corresponding path under this base URL:
http:
//www.joes.ch/stuff/time/clock/AnalogClock.class
The Java SDK comes with an applet viewer program, aptly
called appletviewer. To use
appletviewer, specify the URL of the document on
the command line. For example, to view our (still only theoretical)
AnalogClock
at the URL shown earlier,
use the following command:
%
appletviewer
http:
//www.time.ch/documents/clock.html
appletviewer retrieves all applets in the specified document and displays each one in a separate window. appletviewer isn’t a web browser; it doesn’t attempt to display HTML. It was primarily useful before the Java Plug-in as a way to test an applet in a specific version of the Java runtime.
[48] If you aren’t familiar with HTML or other markup languages, you may want to refer to HTML & XHTML: The Definitive Guide by Chuck Musciano and Bill Kennedy (O’Reilly) for a complete reference on HTML and structured web documents.
Get Learning Java, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.