Before Java, you used HTML (the hypertext markup language) to describe the layout of a web page. HTML is simply a vehicle to indicate elements of a hypertext page. For example, <title> indicates the title of the page, and any text that follows this tag becomes the title of the page. You indicate the end of the title with the </title> tag. (This is one of the general rules for tags: a slash followed by the name of the element indicates the end of the element.) The basic idea of how to use applets in a web page is simple: the HTML page must tell the browser which applets to load and then where to put each applet on the web page. As you might expect, the tag needed to use an applet must tell the browser the following:
- From where to get the class files;
- How the applet sits on the web page (size, location, and so on).
The browser then retrieves the class files from the internet (or from a directory on the user's machine) and automatically runs the applet, using an external Java Runtime Environment or its built-in Java Virtual Machine. In addition to the applet itself, the web page can contain all the other HTML elements you have seen in use on web pages: multiple fonts, bulleted lists, graphics, links, and so on. Applets are just one part of the hypertext page. It is always worth keeping in mind that the Java coding language is not a tool for designing HTML pages; it is a tool for bringing them to life. This is not to say that the GUI design elements in a Java applet are not important, but that they must work with (and, in fact, are subservient to) the underlying HTML design of the web page.
When applets were first developed, you had to use Sun's HotJava browser to view web pages that contain applets. Naturally, few users were willing to use a separate browser just to enjoy a new web feature. Java applets became really popular when Netscape included a Java Virtual Machine in its Navigator browser. Microsoft Internet Explorer soon followed suit. Unfortunately, then two problems happened. Netscape didn't keep up with more modern versions of Java, and Microsoft vacillated between reluctantly supporting outdated Java versions and dropping Java support altogether. To overcome this problem, Sun released a tool called the "Java Plug-In". Using the various extension mechanisms of Internet Explorer or Navigator, it seamlessly plugs into both Netscape and Internet Explorer and allows both browsers to execute Java applets by using an external Java Runtime Environment that Sun supplies. By keeping the Plug-In up-to-date, you can always take advantage of the latest and greatest features of Java.
We do not cover general HTML tags at all; we assume that you know—or are working with someone who knows—the basics of HTML. Only a few special HTML tags are needed for Java applets. We do, of course, cover those later in this chapter. As for learning HTML, there are dozens of HTML tutorials at your local tutorialstore. One that covers what you need and will not insult your intelligence is HTML: The Definitive Guide by Chuck Musciano and Bill Kennedy from Oracle.
To run the applets in this chapter in a browser, you need to install the current version of the Plug-In, and make sure your browser is connected with the Plug-In. Go to http://java.oracle.com/getjava/ for download and configuration information.
A Simple Applet
For tradition's sake, let's write a NotHelloWorld program as an applet. Before we do that, we want to point out that, from a coding point of view, an applet isn't very strange. An applet is simply a Java class that (ultimately) extends the java.applet.Applet class. Note that although the java.applet package is not part of the AWT package, an applet is an AWT component, as the inheritance chain shown in Screenshot-1 illustrates. In this tutorial, we will use the Swing set to implement applets. All of our applets will extend the JApplet class, the superclass for Swing applets. As you can see in Screenshot-1, JApplet is an immediate subclass of the ordinary Applet class.
Screenshot-1. Applet inheritance hierarchy
Example 10-1 shows the code for an applet version of "Not Hello World." Notice how similar this is to the corresponding program from . However, because the applet lives inside a web page, there is no need to specify a method for exiting the applet.
If your applet contains Swing components, you must extend the JApplet class. Swing components inside a plain Applet don't paint correctly.
Example 10-1 NotHelloWorldApplet.java
1. import java.awt.*;
2. import javax.swing.*;
4. public class NotHelloWorldApplet extends JApplet
6. public void init()
8. Container contentPane = getContentPane();
9. JLabel label = new JLabel("Not a Hello, World applet",
Viewing an Applet
To execute the applet, you need to carry out two steps:
Compile your source files into class files.
Create an HTML file that tells the browser which class file to load first and how to size the applet.
It is customary (but not necessary) to give the HTML file the same name as that of the applet class inside. So, following this tradition, we will call the file NotHelloWorldApplet.html. Here are the contents of the file:
Before viewing the applet in a browser, it is a good idea to test it in the applet viewer program that is a part of the Java SDK. To use the applet viewer in our example, enter
at the command line. The command line for the applet viewer program is the name of the HTML file, not the class file. Screenshot-2 shows the applet viewer, displaying this applet.
Screenshot-2. Viewing an applet in the applet viewer
You can also run applets from inside your editor or integrated environment. In Emacs, select JDE -> Run Applet from the menu. In TextPad, choose Tools -> Run Java Applet or use the CTRL+3 keyboard shortcut. You will be presented with a dialog that lists all HTML files in the current directory. If you press ESC, TextPad automatically creates a minimal HTML file for you. In Forte, you simply load the HTML page with the applet tags. Forte contains a simple browser that shows the applet running inside the web page. Alternatively, you can right-click on the source file and set the value of the "Executor" property in the Execution tab to "Applet Execution."
The applet viewer is good for the first stage of testing, but at some point you need to run your applets in a browser to see them in the same way a user might use them. In particular, the applet viewer program shows you only the applet, not the surrounding HTML text. If an HTML file contains multiple applets, the applet viewer pops up multiple windows. To properly view the applet, you need a Java 2 enabled browser. After installing and configuring the Java Plug-In, simply load the HTML file into the browser (see Screenshot-3). If the applet doesn't show up, your browser probably uses its built-in virtual machine, and you need to configure it to use the Java Plug-In instead.
Here is a weird trick to avoid the additional HTML file. Add an applet tag as a comment inside the source file:
<applet code="MyApplet.class" >
public class MyApplet extends JApplet
. . .
Then run the applet viewer with the source file as its command line argument:
We aren't recommending this as standard practice, but it can come in handy if you want to minimize the number of files that you need to worry about during testing.
Screenshot-3. Viewing an applet in a browser
If you make a change to your applet and recompile, you need to restart the browser so that it loads the new class files. Simply refreshing the HTML page will not load the new code. This is a hassle when debugging an applet. You can avoid the painful browser restart if you launch the Java console and issue the x command which clears the classloader cache. Then you can reload the HTML page, and the new applet code is used. You can launch the Java console in Netscape and Mozilla from the menu. Under Windows, click on the Java Plug-in icon in the control panel and request that the Java console be displayed.
Converting apps to Applets
It is easy to convert a graphical Java app (that is, an app that uses the AWT and that you can start with the java command-line interpreter) into an applet that you can embed in a web page. Essentially, all of the user interface code can stay the same. Here are the specific steps for converting an app to an applet.
Make an HTML page with the appropriate tag to load the applet code.
Supply a subclass of the JApplet class. Make this class public. Otherwise, the applet cannot be loaded.
Eliminate the main method in the app. Do not construct a frame window for the app. Your app will be displayed inside the browser.
Move any initialization code from the frame window constructor to the init method of the applet. You don't need to explicitly construct the applet object—the browser instantiates it for you and calls the init method.
Remove the call to setSize; for applets, sizing is done with the width and height parameters in the actual HTML file.
Remove the call to setDefaultCloseOperation. An applet cannot be closed; it terminates when the browser exits.
If the app calls setTitle, eliminate the call to the method. Applets cannot have title bars. (You can, of course, title the web page itself, using the HTML title tag.)
Don't call show. The applet is displayed automatically.
As an example of this transformation, we will change the calculator app from into an applet. In Screenshot-4, you can see how it looks, sitting inside a web page.
Screenshot-4. A calculator applet
Example 10-2 shows the HTML page. Note that there is some text in addition to the applet tags.
Example 10-2 Calculator.html
2. <title>A Calculator</title>
4. Here is a calculator, just in case you can't find yours.
5. <applet code="CalculatorApplet.class"
Example 10-3 is the code for the applet. We introduced a subclass of JApplet, placed the initialization code into the init method, and removed the calls to setTitle, setSize, setDefaultCloseOperation and show . The CalculatorPanel class did not change at all, and its code is omitted.
Example 10-3 CalculatorApplet.java
1. import java.awt.*;
2. import javax.swing.*;
4. public class CalculatorApplet extends JApplet
6. public void init()
8. Container contentPane = getContentPane();
9. CalculatorPanel panel = new CalculatorPanel();
- void init()
is called when the applet is first loaded. Override this method and place all initialization code here.
- void resize(int width, int height)
requests that the applet be resized. This would be a great method if it worked on web pages; unfortunately, it does not work in current browsers because it interferes with their page-layout mechanisms.
Life Cycle of an Applet
Four methods in the Applet class give you the framework on which you build any serious applet: init, start, stop, destroy. What follows is a short description of these methods, when these methods are called, and what code you should place into them.
This method is used for whatever initialization is needed for your applet. This works much like a constructor—it is automatically called by the system when Java launches the applet for the first time. Common actions in an applet include processing param values and adding user interface components.
Applets can have a default constructor, but it is customary to perform all initialization in the init method instead of the default constructor.
This method is automatically called after Java calls the init method. It is also called whenever the user returns to the page containing the applet after having gone off to other pages. This means that the start method can be called repeatedly, unlike the init method. For this reason, put the code that you want executed only once in the init method, rather than in the start method. The start method is where you usually restart a thread for your applet, for example, to resume an animation. If your applet does nothing that needs to be suspended when the user leaves the current web page, you do not need to implement this method (or the stop method).
This method is automatically called when the user moves off the page on which the applet sits. It can, therefore, be called repeatedly in the same applet. Its purpose is to give you a chance to stop a time-consuming activity from slowing down the system when the user is not paying attention to the applet. You should not call this method directly. If your applet does not perform animation, play audio files, or perform calculations in a thread, you do not usually need this method.
This method is only called when the browser shuts down normally. Since applets are meant to live on an HTML page, you should not normally leave resources behind after a user stops viewing the page that contains the applet. But if you do, then you can close down the resources by overriding the destroy method.
- void start()
Override this method for code that needs to be executed every time the user visits the browser page containing this applet. A typical action is to reactivate a thread.
- void stop()
Override this method for code that needs to be executed every time the user leaves the browser page containing this applet. A typical action is to deactivate a thread.
- void destroy()
Override this method for code that needs to be executed when the user exits the browser.
Because applets are designed to be loaded from a remote site and then executed locally, security becomes vital. If a user enables Java in the browser, the browser will download all the applet code on the web page and execute it immediately. The user never gets a chance to confirm or to stop individual applets from running. For this reason, applets (unlike apps) are restricted in what they can do. The applet security manager throws a SecurityException whenever an applet attempts to violate one of the access rules. (See Volume 2 for more on security managers.) What can applets do on all platforms? They can show images and play sounds, get keystrokes and mouse clicks from the user, and send user input back to the host from which they were loaded. That is enough functionality to show facts and figures or to get user input for placing an order. The restricted execution environment for applets is often called the "sandbox." Applets playing in the "sandbox" cannot alter the user's system or spy on it. In this chapter, we will look only at applets that run inside the sandbox. In particular, when running in the sandbox:
- Applets can never run any local executable program.
- Applets cannot communicate with any host other than the server from which they were downloaded; that server is called the originating host. This rule is often called "applets can only phone home." This protects applet users from applets that might try to spy on intranet resources.
- Applets cannot read from or write to the local computer's file system.
- Applets cannot find out any information about the local computer, except for the Java version used, the name and version of the operating system, and the characters used to separate files (for instance, / or \), paths (such as : or ;), and lines (such as \n or \r\n). In particular, applets cannot find out the user's name, e-mail address, and so on.
- All windows that an applet pops up carry a warning message.
All this is possible only because applets are interpreted by the Java Virtual Machine and not directly executed by the CPU on the user's computer. Because the interpreter checks all critical instructions and program areas, a hostile (or poorly written) applet will almost certainly not be able to crash the computer, overwrite system memory, or change the privileges granted by the operating system. These restrictions are too strong for some situations. For example, on a corporate intranet, you can certainly imagine an applet wanting to access local files. To allow for different levels of security under different situations, you can use signed applets. A signed applet carries with it a certificate that indicates the identity of the signer. Cryptographic techniques ensure that such a certificate cannot be forged. If you trust the signer, you can choose to give the applet additional rights. (We cover code signing in Volume 2.) The point is that if you trust the signer of the applet, you can tell the browser to give the applet more privileges. You can, for example, give applets in your corporate intranet a higher level of trust than those from www.hacker.com. The configurable Java security model allows the continuum of privilege levels you need. You can give completely trusted applets the same privilege levels as local apps. Programs from vendors that are known to be somewhat flaky can be given access to some, but not all, privileges. Unknown applets can be restricted to the sandbox.
To sum up, Java has three separate mechanisms for enforcing security:
Java Web Start apps (discussed later in this chapter) have a slightly more versatile sandbox. It is possible to access some system resources, provided the program user agrees.
Program code is interpreted by the Java Virtual Machine, not executed directly.
A security manager checks all sensitive operations in the Java runtime library.
Applets can be signed to identify their origin.
In contrast, the security model of the ActiveX technology by Microsoft relies solely on the third option. If you want to run an ActiveX control at all, you must trust it completely. That model works fine when you deal with a small number of trusted suppliers, but it simply does not scale up to the World Wide Web. If you use Internet Explorer, you will see the ActiveX mechanism at work. You'll need to accept Sun's certificate to install the Java Plug-In on Internet Explorer. The certificate tells you that the code came from Sun. It doesn't tell you anything about the quality of the code. Once you accept the installation, the program runs without any further security checks.
Pop-Up Windows in Applets
An applet sits embedded in a web page, in a frame of a size that is fixed by the width and height values in the applet tags of the HTML page. This can be quite limiting. Many programmers wonder whether they can have a pop-up window to make better use of the available space. It is indeed possible to create a pop-up frame. Here is a simple applet with a single button labeled Calculator. When you click on the button, a calculator pops up in a separate window. The pop-up is easy to do. Simply use a JFrame, but don't call setDefaultCloseOperation.
frame = new CalculatorFrame();
When the user clicks the button, toggle the frame so that it is shown if it isn't visible and hidden if it is. When you click on the calculator button, the dialog box pops up and floats over the web page. When you click on the button again, the calculator goes away.
JButton calcButton = new JButton("Calculator");
public void actionPerformed(ActionEvent evt)
if (frame.isVisible()) frame.setVisible(false);
There is, however, a catch that you need to know about before you put this applet on your web page. To see how the calculator looks to a potential user, load the web page from a browser, not the applet viewer. The calculator will be surrounded by a border with a warning message (see Screenshot-5).
Screenshot-5. A pop-up window inside a browser
In early browser versions, that message was very ominous: "Untrusted Java Applet Window." Every successive version of the SDK watered down the warning a bit—"Unauthenticated Java Applet Window," or "Warning: Java Applet Window." Now it is simply "Java Applet Window." This message is a security feature of all web browsers. The browser wants to make sure that your applet does not launch a window that the user might mistake for a local app. The fear is that an unsuspecting user could visit a web page, which automatically launches the applets on it, and mistakenly type in a password or credit card number, which the applet would send back to its host. To avoid any possibility of shenanigans like this, all pop-up windows launched by an applet bear a warning label. You can configure the Java Plug-In to omit the warning message for pop-up windows that are spawned by signed applets. Example 10-4 shows the code for the PopupCalculatorApplet class. The code for the CalculatorPanel is unchanged from and is not shown.
Example 10-4 PopupCalculatorApplet.java
1. import java.awt.*;
2. import java.awt.event.*;
3. import javax.swing.*;
5. public class PopupCalculatorApplet extends JApplet
7. public void init()
9. // create a frame with a calculator panel
11. frame = new JFrame();
13. frame.setSize(200, 200);
14. frame.getContentPane().add(new CalculatorPanel());
16. // add a button that pops up or hides the calculator
18. JButton calcButton = new JButton("Calculator");
24. public void actionPerformed(ActionEvent evt)
26. if (frame.isVisible()) frame.setVisible(false);
27. else frame.show();
32. private JFrame frame;