This chapter introduces you to the Applet Wizard. The Applet Wizard is the first of many wizards that Microsoft has built into Visual J++ to help simplify Java development. In this chapter you learn how to jump start your development effort by using Applet Wizard to create an initial applet for you. You also learn how to add to and customize this applet.
The Visual J++ Applet Wizard creates a skeleton applet. A skeleton applet is aptly named because, although it's fully functional, there is little meat on its bones. Using a skeleton applet created by Applet Wizard, however, can be a great way to get a project started on the right foot. Applets created by Applet Wizard include all the code necessary to run the applet from within an HTML page. Additionally, Applet Wizard includes five pages of customization options that control if and how the skeleton applet makes use of features such as multithreading, animation, event handling, and applet parameters.
Because your first goal is to create a typical Hello World application, you'll instruct Applet Wizard to leave most of the advanced features out the first time through. To create a Hello World applet, you will perform the following steps (each of which is explained in more detail in the sections that follow):
Every Visual J++ project you create must reside in what is known as a project workspace. A project workspace groups a project's code with its configuration and builds information as a way to help you manage the project. Therefore, the first step in creating a new applet is creating a new project workspace. To do this, select File | New from the menu, and you will be presented with the New file dialog as shown in Figure 2.1. In this dialog select Project Workspace and select the OK button.
Figure 2.1 : Creating a new project workspace.
After following the first step, you will be presented with the New Project Workspace dialog shown in Figure 2.2. In this dialog you need to select Java Applet Wizard. You can then change the name of the applet and its location. Once you've done this, select the Create button to start the Applet Wizard.
Figure 2.2 : Starting the Applet Wizard.
The Java Applet Wizard itself is a set of five screens that are displayed sequentially and can be used to determine which features will initially be included in the applet. In the first Applet Wizard screen, shown in Figure 2.3, you should select the radio button labeled "As an applet and as an application."
Figure 2.3 : The first screen of options in the Applet Wizard.
Selecting this option tells the Wizard to include startup code in the applet so that it can also be run as a stand-alone Java application. When ready, select the Next button to move to the next page of the Applet Wizard, as shown in Figure 2.4.
Figure 2.4 : The second screen of options in the Applet Wizard.
| NOTE |
Remember an applet is a Java program run within a browser, and an application is a stand-alone program that is run using the Java interpreter |
For this sample applet, you can leave the fields on the second page with their default values and move to the third page by selecting the Next button. Because the goal of your first applet is only to display "Hello World," your applet does not need to be multithreaded. This means you can select the "No, thank you" radio button when asked this question on the third page, as shown in Figure 2.5.
Figure 2.5 : The third screen of options in the Applet Wizard.
You should notice that when you tell Applet Wizard that you do not want to create a multithreaded applet, it disables the answers for whether you want support for animation. This is because Applet Wizard provides animation through the use of threads. If you disable multithreaded support, you are implicitly disabling animation.
This page of the Applet Wizard also enables you to trap various mouse actions by adding event handlers to your applet. If you want to install handlers for whenever the mouse button is pressed or released, select the mouseDown(), mouseUp() check box. To install handlers for mouse dragging or movement notification, select the mouseDrag(), mouseMove() check box. Finally, if the applet needs notification whenever the mouse enters or leaves the area covered by the applet on the screen, select the mouseEnter(), mouseExit() check box shown in Figure 2.5.
Once you've correctly set the options on this screen, select the Next button to move to the fourth options screen of the Applet Wizard. On this screen, which is shown in Figure 2.6, you can specify any parameters that your applet will read at runtime. Applet parameters are stored in the HTML file in which a Java applet is contained and can be used by an applet similar to how command-line parameters are used by a conventional program. The applet you're starting with doesn't need any applet parameters, so simply press the Next button to move to the fifth screen of the Applet Wizard.
Figure 2.6 : The fourth screen of options in the Applet Wizard.
The fifth and final options screen of Applet Wizard is shown in Figure 2.7. In this screen you can enter whatever text you would like the applet to respond with when queried by the getAppInfo method. By default, it should show your name and the version of Visual J++ that was used, as shown in Figure 2.7. When you've finished with this screen, press the Finish button to tell the Applet Wizard that you are done setting options.
Figure 2.7 : The fifth screen of options in the Applet Wizard.
After you select the Finish button, you are presented with the New Project Information dialog, as shown in Figure 2.8. This dialog gives you a final chance to confirm that you made the correct selections in the Applet Wizard.
Figure 2.8 : The New Project Information dialog allows you to confirm your Applet Wizard selections.
| TIP |
You can select the Finish button from any of the options pages of the Java Applet Wizard. If you wanted to accept the default for all pages after the first, you could have selected Finish directly from the first page |
Once you've confirmed that you want the Applet Wizard to create
the applet, select the OK button. Doing so will create the files
necessary for the new applet and the new project workspace. Table
2.1 summarizes the files that are created by the Applet Wizard.
| Filename | Purpose |
| EX02A.java | This file contains the main class for the applet. |
| EX02AFRAME.java | This file contains a frame class that is used to provide a top-level window for when the program is run as a stand-alone application. |
| EX02A.html | This is an HTML file in which the applet is embedded. |
| EX02A.mak | This is the make file that Visual J++ uses to know how to build the applet. |
| EX02A.ncp | This is the program database that is used by Visual J++. You do not need to directly manipulate this file. |
| EX02A.mdp | This is the project workspace file. It contains various configuration settings and switches that can be set in the Visual J++ Developer Studio. |
Now that you've successfully generated the applet, you need to set some Visual J++ options so that you can run the applet and view your masterpiece. To do this, select Settings from the Build menu. This will display the Project Settings dialog, which will be similar to Figure 2.9.
Figure 2.9 : Setting options on the Debug page of the Project Settings dialog.
The Project Settings dialog lets you set options for a debug version
of your applet as well as for a release version. To simultaneously
set options for both versions, ensure that both versions are selected
in the tree at the left of this dialog. Select the Debug page
and the General category on the page. Indicate that you want to
execute the applet under the stand-alone interpreter.
| TIP |
As with many Windows controls, you can select multiple items by holding the Ctrl key down while selecting an item with the left mouse button |
You've now generated the applet source code and have configured Visual J++ to run the applet under the stand-alone interpreter. There's no point in giving the applet a trial run yet, however, because we haven't told the applet to do anything. At this point you need to add the code that will display the Hello World message.
The easiest way to do this is to use the ClassView pane of the
Developer Studio. The ClassView can be accessed by selecting the
first tab at the bottom of the Project Workspace window. The ClassView
will display a tree of the classes in the project. Classes can
be expanded to show their members by clicking the plus (+) symbols
to the left of each class name.
| NOTE |
Use of the Project Workspace window is fully described in Chapter 3 "Using the Developer Studio." The current chapter covers just enough so that you can edit, build, and run your first project. A full explanation of the Developer Studio is deferred until the next chapter |
Your ClassView should show two classes: one representing the applet itself and a second representing the frame that will house the applet when it is run outside a browser. If you fully expand the applet class your ClassView should appear similar to the one shown in Figure 2.10.
Figure 2.10 : The ClassView of the Project Workspace with the applet class fully expanded.
Listed beneath the class are its members. If you double-click a method, the right pane of the Project Workspace will be repositioned to the declaration of that method. Try this on the paint method and modify that method so that it appears as follows:
public void paint(Graphics g)
{
g.drawString("Hello, World", 10, 10);
}
This line will draw the string "Hello, World" at position 10, 10 in the window represented by g.
At this point, all that's left to do is to build and execute the applet. To do this, select Execute from the Build menu. You will be asked to confirm that you want to build the project. After the project is built, the JVIEW.EXE interpreter will automatically start and will run your application. The results will appear as shown in Figure 2.11.
Figure 2.11 : The Hello World applet, EX02A, running in the JView interpreter.
Because the Applet Wizard generates the initial applet source code for you, you may be tempted to ignore the generated code. However, because this code serves as the foundation of your applet, it is well worth examining. In this section, you'll dissect the generated code and see exactly what using the Applet Wizard has saved you.
The Applet Wizard generated two Java source code files and one HTML file. The first Java file is EX02A.java and is shown in Listing 2.1. This file contains the definition of class EX02A, which extends the Applet class. This class contains definitions for the following methods:
Listing 2.1. EX02A.java.
//****************************************************************
// EX02A.java: Applet
//
//****************************************************************
import java.applet.*;
import java.awt.*;
import EX02AFrame;
//================================================================
// Main Class for applet EX02A
//
//================================================================
public class EX02A extends Applet
{
// STANDALONE APPLICATION SUPPORT:
// m_fStandAlone will be set to true if applet is run
// standalone
//------------------------------------------------------------
boolean m_fStandAlone = false;
// STANDALONE APPLICATION SUPPORT
// The main() method acts as the applet's entry point when it
// is run as a standalone application. It is ignored if the
// applet is run from within an HTML page.
//------------------------------------------------------------
public static void main(String args[])
{
// Create Toplevel Window to contain applet EX02A
//--------------------------------------------------------
EX02AFrame frame = new EX02AFrame("EX02A");
// Must show Frame before we size it so insets() will
// return valid values
//--------------------------------------------------------
frame.show();
frame.hide();
frame.resize(frame.insets().left+frame.insets().right +320,
frame.insets().top+frame.insets().bottom+240);
// The following code starts the applet running within the
// frame window. It also calls GetParameters() to retrieve
// parameter values from the command line, and sets
// m_fStandAlone to true to prevent init() from trying to
// get them from the HTML page.
//--------------------------------------------------------
EX02A applet_EX02A = new EX02A();
frame.add("Center", applet_EX02A);
applet_EX02A.m_fStandAlone = true;
applet_EX02A.init();
applet_EX02A.start();
frame.show();
}
// EX02A Class Constructor
//------------------------------------------------------------
public EX02A()
{
// TODO: Add constructor code here
}
// APPLET INFO SUPPORT:
// The getAppletInfo() method returns a string describing the
// applet's author, copyright date, or miscellaneous
// information.
//------------------------------------------------------------
public String getAppletInfo()
{
return "Name: EX02A\r\n" +
"Author: Mike Cohn\r\n" +
"Created with Microsoft Visual J++ Version 1.0";
}
// The init() method is called by the AWT when an applet is
// first loaded or reloaded. Override this method to perform
// whatever initialization your applet needs, such as
// initializing data structures, loading images or fonts,
// creating frame windows, setting the layout manager, or
// adding UI components.
//------------------------------------------------------------
public void init()
{
// If you use a ResourceWizard-generated "control creator"
// class to arrange controls in your applet, you may want
// to call its CreateControls() method from within this
// method. Remove the following call to resize() before
// adding the call to CreateControls(); CreateControls()
// does its own resizing.
//--------------------------------------------------------
resize(320, 240);
// TODO: Place additional initialization code here
}
// Place additional applet clean up code here. destroy() is
// called when when your applet is terminating and being
// unloaded.
//------------------------------------------------------------
public void destroy()
{
// TODO: Place applet cleanup code here
}
// EX02A Paint Handler
//------------------------------------------------------------
public void paint(Graphics g)
{
g.drawString("Hello, World", 10, 10);
}
// The start() method is called when the page containing the
// applet first appears on the screen. The AppletWizard's
// initial implementation of this method starts execution of
// the applet's thread.
//------------------------------------------------------------
public void start()
{
// TODO: Place additional applet start code here
}
// The stop() method is called when the page containing the
// applet is no longer on the screen. The AppletWizard's
// initial implementation of this method stops execution of
// the applet's thread.
//------------------------------------------------------------
public void stop()
{
}
// TODO: Place additional applet code here
}
The class EX02A includes a variable, m_fStandalone, which is used to indicate whether the code is being run from within a browser (as a true applet) or from within a stand-alone interpreter as an application. If m_fStandalone is true, the main method will be invoked. When run in stand-alone mode, the program cannot rely on the browser to provide a window in which it can run. Because of this, the main method creates a frame window in which the program will run. It sizes the window as appropriate and starts the program by calling the applet's init and start methods.
Because no special processing is required when an instance of EX02A is created, an empty constructor is provided. Similarly, the destroy method that is called when the applet is terminated is provided but is empty. The getAppletInfo method simply returns the string message that was entered when Applet Wizard was run.
The init method resizes the window. You'll alter this method when displaying one of Visual J++'s control creator classes. You've already seen the paint method because you added the call to drawString to display "Hello, World." Finally, empty start and stop methods are provided in case you need to supply code for them.
The second Java file created by the Applet Wizard is EX02AFRAME.java and is shown in Listing 2.2. This class is a very simple descendant of Java's Frame class. This class provides a window in which the program can run when it is run outside of a browser as a stand-alone application.
Listing 2.2. EX02AFRAME.java.
//*************************************************************************
// EX02AFrame.java:
//
//*************************************************************************
import java.awt.*;
//=========================================================================
// STAND-ALONE APPLICATION SUPPORT
// This frame class acts as a top-level window in which the applet appears
// when it's run as a stand-alone application.
//=========================================================================
class EX02AFrame extends Frame
{
// EX02AFrame constructor
//--------------------------------------------------------------------
public EX02AFrame(String str)
{
// TODO: Add additional construction code here
super (str);
}
// The handleEvent() method receives all events generated within the
// frame window. You can use this method to respond to window events.
// To respond to events generated by menus, buttons, etc. or other
// controls in the frame window but not managed by the applet, override
// the window's action() method.
//--------------------------------------------------------------------
public boolean handleEvent(Event evt)
{
switch (evt.id)
{
// Application shutdown (e.g. user chooses Close from the
// system menu).
//------------------------------------------------------------
case Event.WINDOW_DESTROY:
// TODO: Place additional clean up code here
dispose();
System.exit(0);
return true;
default:
return super.handleEvent(evt);
}
}
}
Only two methods are needed in the EX02AFrame class: a constructor and handleEvent. The constructor is passed a String that will appear on the title bar of the frame. The handleEvent method catches the WINDOW_DESTROY message that is generated when the user closes the application.
Finally, the Applet Wizard also created an HTML file that will host the applet when run under a browser. Listing 2.3 shows the contents of EX02A.html, which is a very simple HTML page that uses the applet tag and specifies the name of the applet and its dimensions.
Listing 2.3. EX02A.html.
<html>
<head>
<title>EX02A</title>
</head>
<body>
<hr>
<applet
code=EX02A.class
id=EX02A
width=320
height=240 >
</applet>
<hr>
<a href="EX02A.java">The source.</a>
</body>
</html>,
Example EX02A is a very stripped-down example of what the Applet Wizard can do. To create this sample applet, you disabled multitasking and animation. What would Applet Wizard have done if you hadn't disabled them? If you had left animation enabled when generating the applet, Applet Wizard would have created an applet that displayed an animated view of the Earth rotating, as shown in Figure 2.12.
Figure 2.12 : An animated applet generated by the Applet Wizard.
This applet is provided on the CD-ROM as EX02B, but to create it yourself, start Applet Wizard and create a new Project Workspace as before. On the first step of the Applet Wizard, tell the Wizard to create the program as an applet and an application. At this point, select the Finish button instead of using the Next buttons to move through the remaining Applet Wizard steps. If you're satisfied with the defaults (and animation is on by default), there is no need to move through each step.
This will create the program, but before running it, remember to use the Build | Settings menu item to indicate that you want to run the program through the stand-alone interpreter instead of through a browser. Finally, to run your program, select Execute from the Build menu.
Listing 2.4 shows the source code for the applet class of example EX02B. As you can tell from this listing, the Applet Wizard is capable of doing much more work for you than was done in the Hello, World example of EX02A. Taking advantage of this can save you hours at the start of a project.
Listing 2.4. EX02B.java.
//****************************************************************
// EX02B.java: Applet
//
//****************************************************************
import java.applet.*;
import java.awt.*;
import EX02BFrame;
//================================================================
// Main Class for applet EX02B
//
//================================================================
public class EX02B extends Applet implements Runnable
{
// THREAD SUPPORT:
// m_EX02B is the Thread object for the applet
//------------------------------------------------------------
Thread m_EX02B = null;
// ANIMATION SUPPORT:
// m_Graphics used for storing the applet's Graphics context
// m_Images[] the array of Image objects for the animation
// m_nCurrImage the index of the next image to be displayed
// m_ImgWidth width of each image
// m_ImgHeight height of each image
// m_fAllLoaded indicates whether all images have been loaded
// NUM_IMAGES number of images used in the animation
//------------------------------------------------------------
private Graphics m_Graphics;
private Image m_Images[];
private int m_nCurrImage;
private int m_nImgWidth = 0;
private int m_nImgHeight = 0;
private boolean m_fAllLoaded = false;
private final int NUM_IMAGES = 18;
// STANDALONE APPLICATION SUPPORT:
// m_fStandAlone will be set to true if applet is run
// standalone
//------------------------------------------------------------
boolean m_fStandAlone = false;
// STANDALONE APPLICATION SUPPORT
// The main() method acts as the applet's entry point when it
// is run as a standalone application. It is ignored if the
// applet is run from within an HTML page.
//------------------------------------------------------------
public static void main(String args[])
{
// Create Toplevel Window to contain applet EX02B
//--------------------------------------------------------
EX02BFrame frame = new EX02BFrame("EX02B");
// Must show Frame before we size it so insets() will
// return valid values
//--------------------------------------------------------
frame.show();
frame.hide();
frame.resize(frame.insets().left+frame.insets().right+320,
frame.insets().top+frame.insets().bottom+240);
// The following code starts the applet running within the
// frame window. It also calls GetParameters() to retrieve
// parameter values from the command line, and sets
// m_fStandAlone to true to prevent init() from trying to
// get them from the HTML page.
//--------------------------------------------------------
EX02B applet_EX02B = new EX02B();
frame.add("Center", applet_EX02B);
applet_EX02B.m_fStandAlone = true;
applet_EX02B.init();
applet_EX02B.start();
frame.show();
}
// EX02B Class Constructor
//------------------------------------------------------------
public EX02B()
{
// TODO: Add constructor code here
}
// APPLET INFO SUPPORT:
// The getAppletInfo() method returns a string describing the
// applet's author, copyright date, or miscellaneous
// information.
//------------------------------------------------------------
public String getAppletInfo()
{
return "Name: EX02B\r\n" +
"Author: Mike Cohn\r\n" +
"Created with Microsoft Visual J++ Version 1.0";
}
// The init() method is called by the AWT when an applet is
// first loaded or reloaded. Override this method to perform
// whatever initialization your applet needs, such as
// initializing data structures, loading images or fonts,
// creating frame windows, setting the layout manager, or
// adding UI components.
//------------------------------------------------------------
public void init()
{
// If you use a ResourceWizard-generated "control creator"
// class to arrange controls in your applet, you may want
// to call its CreateControls() method from within this
// method. Remove the following call to resize() before
// adding the call to CreateControls(); CreateControls()
// does its own resizing.
//--------------------------------------------------------
resize(320, 240);
// TODO: Place additional initialization code here
}
// Place additional applet clean up code here. destroy() is
// called when when your applet is terminating and being
// unloaded.
//------------------------------------------------------------
public void destroy()
{
// TODO: Place applet cleanup code here
}
// ANIMATION SUPPORT:
// Draws the next image, if all images are currently loaded
//------------------------------------------------------------
private void displayImage(Graphics g)
{
if (!m_fAllLoaded)
return;
// Draw Image in center of applet
//--------------------------------------------------------
g.drawImage(m_Images[m_nCurrImage],
(size().width - m_nImgWidth) / 2,
(size().height - m_nImgHeight) / 2, null);
}
// EX02B Paint Handler
//------------------------------------------------------------
public void paint(Graphics g)
{
// ANIMATION SUPPORT:
// The following code displays a status message until all
// the images are loaded. Then it calls displayImage to
// display the current image.
//--------------------------------------------------------
if (m_fAllLoaded)
{
Rectangle r = g.getClipRect();
g.clearRect(r.x, r.y, r.width, r.height);
displayImage(g);
}
else
g.drawString("Loading images...", 10, 20);
// TODO: Place additional applet Paint code here
}
// The start() method is called when the page containing the
// applet first appears on the screen. The AppletWizard's
// initial implementation of this method starts execution of
// the applet's thread.
//------------------------------------------------------------
public void start()
{
if (m_EX02B == null)
{
m_EX02B = new Thread(this);
m_EX02B.start();
}
// TODO: Place additional applet start code here
}
// The stop() method is called when the page containing the
// applet is no longer on the screen. The AppletWizard's
// initial implementation of this method stops execution of
// the applet's thread.
//------------------------------------------------------------
public void stop()
{
if (m_EX02B != null)
{
m_EX02B.stop();
m_EX02B = null;
}
// TODO: Place additional applet stop code here
}
// THREAD SUPPORT
// The run() method is called when the applet's thread is
// started. If your applet performs any ongoing activities
// without waiting for user input, the code for implementing
// that behavior typically goes here. For example, for an
// applet that performs animation, the run() method controls
// the display of images.
//------------------------------------------------------------
public void run()
{
m_nCurrImage = 0;
// If re-entering the page, then the images have already
// been loaded.
// m_fAllLoaded == TRUE.
//--------------------------------------------------------
if (!m_fAllLoaded)
{
repaint();
m_Graphics = getGraphics();
m_Images = new Image[NUM_IMAGES];
// Load in all the images
//----------------------------------------------------
MediaTracker tracker = new MediaTracker(this);
String strImage;
// For each image in the animation, this method first
// constructs a string containing the path to the
// image file; then it begins loading the image into
// the m_Images array. Note that the call to getImage
// will return before the image is completely loaded.
//----------------------------------------------------
for (int i = 1; i <= NUM_IMAGES; i++)
{
// Build path to next image
//------------------------------------------------
strImage = "images/img00" + ((i < 10) ? "0" : "") +
i + ".gif";
if (m_fStandAlone)
m_Images[i-1] =
Toolkit.getDefaultToolkit().getImage(strImage);
else
m_Images[i-1] = getImage(getDocumentBase(),
strImage);
tracker.addImage(m_Images[i-1], 0);
}
// Wait until all images are fully loaded
//----------------------------------------------------
try
{
tracker.waitForAll();
m_fAllLoaded = !tracker.isErrorAny();
}
catch (InterruptedException e)
{
// TODO: Place exception-handling code here in
// case an InterruptedException is thrown by
// Thread.sleep(), meaning that another thread
// has interrupted this one
}
if (!m_fAllLoaded)
{
stop();
m_Graphics.drawString("Error loading images!", 10,
40);
return;
}
// Assuming all images are same width and height.
//----------------------------------------------------
m_nImgWidth = m_Images[0].getWidth(this);
m_nImgHeight = m_Images[0].getHeight(this);
}
repaint();
while (true)
{
try
{
// Draw next image in animation
//------------------------------------------------
displayImage(m_Graphics);
m_nCurrImage++;
if (m_nCurrImage == NUM_IMAGES)
m_nCurrImage = 0;
// TODO: Add additional thread-specific code here
Thread.sleep(50);
}
catch (InterruptedException e)
{
// TODO: Place exception-handling code here in case
// an InterruptedException is thrown by
// Thread.sleep(), meaning that another thread has
// interrupted this one
stop();
}
}
}
// TODO: Place additional applet code here
}
This chapter introduced you to the Java Applet Wizard, the first of a handful of helpful Wizards you'll encounter when using Visual J++. You learned how to use the Applet Wizard to generate source code that would run both as an applet and an application. You studied the generated source code and learned how to use the ClassView to modify the code so that you could say "Hello, World". Finally, you generated a more powerful applet that included support for multithreading and animation. You did all of this work within the Visual J++ Developer Studio, a powerful integrated development environment. In the next chapter you will learn more about the Developer Studio and the time-saving features it provides.