Novell is now a part of Micro Focus

Anatomy of a Java Applet, Part 2

Articles and Tips: article

STEVEN C. JONES
Senior Research Engineer
Developer Information

01 Feb 1997


Discusses Java's Abstract Toolkit (AWT) and its event handling capabilities. Illustrates Java component integration and even handling with the construction on a sample applet.

Introduction

This DevNote is the second in a series covering the anatomy of Java Applets. This is a follow-up article to "Anatomy of a Java Applet--Part 1" published in August of 1996. We begin with a review of applet basics followed by some information useful for deciding if and when you may want to add java applets to your web site. Java applets are now easier than ever to build with the recent introduction of rapid application development (RAD) tools. Additionally, with support for applets available in most popular browsers, a large, rapidly growing market exists for applet solutions. Users are increasingly expecting "application-like" functionality from web sites that can't be provided with static HTML. Applets provide one alternative for creating dynamic solutions on the web.

The DevNote centers on a discussion of Java's Abstract Window Toolkit (AWT) and its event handling capabilities. The AWT package has the set of component and event handing classes that are utilized in the construction of Java applets and applications. The DevNote will illustrate Java component integration and event handling with the construction of a sample applet.

This DevNote is written for developers who are relatively new to Java and Java applet development. If you're a webmaster/developer type and have experience with Visual Basic, Delphi, C, or C++ and you are interested in getting up to speed quickly on Java applet development, this article should prove useful. The article assumes some basic knowledge of object-oriented programming concepts.

Applets in Review

Before we jump into sample code, let's review some applet basics. Applets are a special type of Java program. Java applets like Java programs consist of one or more class definitions. Once compiled, these classes are stored as files with a .class extension and they consist of Java bytecode. Java bytecode is created by a Java-compatible compiler. Unlike Java applications that typically are executed by a Java-compatible interpreter, applets are executed within a Java-enabled web browser that includes an integrated bytecode interpreter. Applets are embedded within an HTML document via the APPLET tag that references the Java applet's compiled .class file.

Why Write Java Applets?

The software development industry is going through a paradigm shift. Desktop-centric monolithic applications are being complemented if not replaced by network web-centric solutions. Applets, with support from many of today's popular browsers, provide a methodology for providing such solutions. Applets leverage the fastest growing phenomenon in computing history-the web. Popular browsers with associated technologies such as Java and ActiveX are providing the next wave in development platforms. Applets can embrace and extend the existing functionality of a browser. Applets are supported by many popular web browsers including Netscape's Navigator, Microsoft's Internet Explorer, NCSA Mosaic, and others.

Applets, as the name implies, are more granular than today's applications. They should be "tight" with features and functions. In this paradigm, you should leverage the typical browser's basic functionality including managing the HTML display, managing communications via HTTP, caching, navigation, etc. Functionality in an applet sits "inside" the content rather than the reverse, as seen in traditional applications where the content is displayed inside the application. The paradigm lends itself to solving problems with "just enough" code rather than large amounts of redundant code. Features and functionality can be combined at granularity levels that provide for more efficient, intuitive network computing. Once you have decided to build an applet, you may want to look for tools beyond the basic JDK from Sun.

Java Meets RAD

One of the most exciting developments in Java's brief history is currently under way-the anxiously awaited marriage of Java and rapid application development (RAD) tools. Many tool providers have or soon will be releasing RAD tools for Java. Here is a partial list:


Company Name
Tool Name

Sun

Java Workshop

Symantec

Visual Cafe

Borland

Jbuilder

Microsoft

Visual J++

Penumbra

Mojo

Rogue Wave

JFactory

It will be interesting to see which products become winners in the market. RAD tools for Java help you to design Java applets and applications visually with much of the code being generated as you move through the visual design process. Use of these tools still requires knowledge of object-oriented programming; however, the tools dramatically reduce the amount of time spent doing tedious line-by-line coding. This combined with a few royalty-free, pre-built widgets that might be offered in addition to the base Java classes can dramatically increase development productivity.

Many of the tools offer integrated features developers have come to expect, including editing that can be configured to work like your favorite editor, sophisticated debuggers, class browsers, class hierarchy editors, and more.

Some of you may later recognize that most of the code for the sample application was generated from Symantec's Visual Cafe v.1.0. Here is a screen shot of the Visual Cafe environment taken while developing the sample applet.

Figure 1: Symantec's Visual Cafe RAD environment.

Visual Cafe eases development by providing code generation for components you drop in from a component palette. Code is generated to instantiate the object and give it a default state based on the attributes you edit in the tool's attribute editor. The tool also generates an event framework by using Interaction Agents that walk you through the creation of interactions amongst GUI components. Event handling methods can also be generated by selecting events supplied in a list box integrated into the source editor. This works very similar to the way Delphi's Object Inspector generates event handling methods.

Event handling is one of the most tedious aspects of development, especially in the area of GUI development. RAD tools dramatically reduce the complexity and the time required for development of your applet's interface. Since events and components are handled by the AWT, understanding GUI development and event handling in Java begins with a deeper understanding of the toolkit. Before examining the AWT and before we start coding, let's describe our sample applet.

Sample Applet Description

The applet will be an image map applet that allows for linking from "hot spots" on an image to specified URLs. In order to jazz it up a bit, the applet will also offer pop-up balloon help (using a textField component from the AWT) that displays a description of the designated URL when the mouse pointer enters one of the hot zones.

The background image and the hot spots will be fairly easy to implement since we will use a couple of widgets supplied with Visual Cafe. We will use their ImageViewer to hold the background image and their InvisibleButton component for the hot spots.

The image file to be used for the map is a .jpg rendered 3D view of a space ship command center-appropriate for this type of thing. Since we want to emphasize the browser running this applet as a central navigational "room," we will design the applet so that the designated URLs are loaded in a new instance of the default browser. Therefore, the instance of the browser running the applet remains open after the user clicks in a hot spot.

Here are a couple of screen shots of the finished applet running in Netscape Navigator. The first demonstrates the balloon help when the mouse is over an invisible button.

Figure 2: Applet in Navigator with balloon help visible.

The second shot demonstrates what happens when a user clicks on one of the invisibleButton components or hot spots.

Figure 3: Environment after invisible button has been pressed.

Now that we have a spec for our sample applet, let's begin by exploring those portions of the AWT we will need to utilize to construct our applet.

The Abstract Window Toolkit

Java provides a package of classes for basic GUI development know as the Abstract Window Toolkit (AWT). You may have also heard it referred to as the "Alternative Window Toolkit," or affectionately as the "awkward Window Toolkit." The platform independent toolkit is considered somewhat primitive or low level by many. The AWT contains classes that make up your user interface in addition to event handling classes to control flow of execution. In the AWT, components are placed in containers. Text fields, list boxes, and other GUI elements including containers can be placed in containers.

For development of sophisticated interfaces, knowledge of the layout managers provided by the AWT or knowledge of how to create a custom layout manager is important. Java provides the following layout managers: flow, border, card, grid, and grid-bag. Layout managers, however, are beyond the scope of this DevNote. For more information on layout managers, explore one of the many books now available covering Java. Future DevNotes may also cover the topic if there is sufficient interest. For now, let's explore the fundamental usage of the AWT with the construction of an applet.

Building the Applet

Recall that applets provide four primary methods that give you a framework upon which you can build, including init(), start(), stop(), and destroy(). Much of code for our sample applet will be placed in the init() method that is overridden. Visual Cafe generates most of the code for you when you visually add objects to your project. Code is generated to create the instance for each component, initialize their state, and add them inside their container.

We begin constructing the applet by dropping in four components-an imageViewer, a textField, and two invisibleButton components. After naming the objects in the attribute editor and setting other appropriate attributes using the RAD tool, the applet's basic structure is generated, ncluding its init() method. Here is another screen shot of Visual Cafe taken during the construction of our sample applet.

Figure 4: A view of Visual Cafe's class browser and hierarchy editor.

Notice the component project window, the class browser, the hierarchy editor, and the source editor. Let's take a look at some of the code; here is look at just the code for init() method- part of the code that has been generated so far:

public void init() {

   super.init();

      // Take out this line if you don't usesymantec.itools.net.RelativeURL symantec.itools.lang.Context.setDocumentBase(getDocumentBase());



   //{{INIT_CONTROLS

   setLayout(null);

   addNotify();

   Resize(636,465);



   imageViewerCmdCtrMap = new symantec.itools.multimedia.ImageViewer();

   imageViewerCmdCtrMap.reshape(0,0,640,468);

   add(imageViewerCmdCtrMap);

   try {

      imageViewerCmdCtrMap.setURL(symantec.itools.net.RelativeURL.getURL("Spacewld.gif"));

   } catch (java.net.MalformedURLException error) {

   }



   textFieldStatusLine = new

   java.awt.TextField();

   textFieldStatusLine.hide();

   textFieldStatusLine.reshape(0,0,156,24);

   add(textFieldStatusLine);



   invisibleButtonAnthology = new symantec.itools.awt.InvisibleButton();

   invisibleButtonAnthology.reshape(36,108,87,111);

   add(invisibleButtonAnthology);



   invisibleButtonAbout = new symantec.itools.awt.InvisibleButton();

   invisibleButtonAbout.reshape(276,288,93,96);

   add(invisibleButtonAbout);

   //}}

   }

Notice that after the applet does a couple of initializations on itself, code is added to instantiate, initialize, and add the GUI components to the default container. Code is also generated for handling the exception if the .jpg file can't be loaded from the specified URL into the imageViewer component. If an exception does occur, a message will be displayed by the status line of Netscape Navigator. Once componentshave been added to the applet, events must be handled to make the applet functional.

Event Handling in Java

Java, like Windows or X Windows programming is event driven. Although control flow follows a particular pattern, the system must generate messages that the developer can trap to in order to execute desired methods based on particular events.

In the AWT, the Event object is a platform independent class that encapsulates events from the graphical user interface(GUI) platform on the local OS. The AWT will generate an Event object when any event occurs inside a Java applet or application. Event objects capture events from the local OS and make them available. The AWT has a generic event handler method called handleEvent().

The handleEvent() Method

For the sample, the event framework is started with generated code that overrides the handleEvent() method. When you override this method, none of the other default event handling procedures will be called unless you explicitly call them in the body of your handleEvent() method. Visual Cafe places by default a call to super.handleEvent(), the superclass that defines handleEvent(), so that if you do override any of the default events, those methods will still get called. Here is a look at the template code before any events are captured.

public boolean handleEvent(Event event) {

   return super.handleEvent(event);

Each event has an event ID which you can test for. Based on that event you can call other event handling methods or handle it in the handleEvent() method. Interactive agents and other means within Visual Cafe allow for generating additional custom individual event handling methods. These are called from the handleEvent() method-thus creating the event framework for the applet. In our sample, the handleEvent() method will mainly consist of a series of if-then statements that will capture the events we decide upon. For example, here is the code for the handleEvent()method after we create one custom event handling method that captures a mouse event-the mouse entering the hot region of one of the invisibleButtons.

void invisibleButtonAbout_MouseEnter(Event event) {

   //{{CONNECTION

   // method called when mouse enters area of button...



   //}}



public boolean handleEvent(Event event) {

   if (event.target == invisibleButtonAnthology && event.id == Event.MOUSE_ENTER) {

      invisibleButtonAnthology_MouseEnter(event);

      return true;

   }

   return super.handleEvent(event);

}

Recall that our sample applet calls for balloon help that uses a textField component to display information about the hot link. Once this above code is generated, we manually add the code to place (reshape) the textField, set its text with a string description, and call the show method since we set up the textField to be hidden by default. We also want the balloon help to display at a location just offset from our mouse pointer. We can use the event object's x and y information for locating the textField. The code for this looks like this:

textFieldStatusLine.reshape(event.x + 25,event.y + 25,156,24);

textFieldStatusLine.setText("About Novell Research");

textFieldStatusLine.show();

The mouse exit code needs to be somewhat of a mirror image of this. It needs to hide the component and move the component out of the way with its text cleared. The code looks like this:

textFieldStatusLine.hide();

textFieldStatusLine.setText("");

textFieldStatusLine.reshape(0,0,156,24);

The Action event code, code that is called when the user clicks on one of the invisible buttons, needs to load another instance of the browser with the specified URL. We use a URL object, and the getDocumentBase() and showDocument() methods to accomplish this task. Here is a look at the code for this.

try {

    AppletContext context = getAppletContext();

    URL u = new URL(getDocumentBase(),"about.htm");

    context.showDocument(u, "_blank");

    } catch (java.net.MalformedURLException error) {

}

Now that we have accomplished each of the tasks specified, the rest is repetition. Here is a look at the source code for the entire applet with two hot spots Awired" and ready. The applet consists of the init() method, the handleEvent() method, and the other custom event methods we generated.

/*

    A basic extension of the java.applet.Applet class

 */



import java.awt.*;

import java.applet.*;

import java.net.*;



public class NRCommandCtr extends Applet {

   void invisibleButtonAnthology_Action(Event event) {



   //{{CONNECTION

   // Load a new instance of browser with specified URL...

   try {

       AppletContext context = getAppletContext();

       URL u = new URL(getDocumentBase(),"anthology.htm");

       context.showDocument(u, "_blank");

       } catch (java.net.MalformedURLException error) {

   }

   //}}

}



void invisibleButtonAnthology_MouseExit(Event event) {



   //{{CONNECTION

   // Hide, empty, and move the textField used as baloon help...

   textFieldStatusLine.hide();

   textFieldStatusLine.setText("");

   textFieldStatusLine.reshape(0,0,156,24);

   //}}

   }



void invisibleButtonAnthology_MouseEnter(Event event) {



   //{{CONNECTION

   // Set the text for TextField used as baloon help...

   textFieldStatusLine.reshape(event.x + 25,event.y + 25,156,24);

   textFieldStatusLine.setText("Novell Research Library");

   textFieldStatusLine.show();

 

   //}}

}



void invisibleButtonAbout_MouseExit(Event event) {



   //{{CONNECTION

   // Hide, empty, and move the textField used as balloon help... 

   textFieldStatusLine.hide();

   textFieldStatusLine.setText("");

   textFieldStatusLine.reshape(0,0,156,24);

   //}}

}



void invisibleButtonAbout_MouseEnter(Event event) {



   //{{CONNECTION

   // Set the text for TextField used as balloon help...

   textFieldStatusLine.reshape(event.x + 25,event.y + 25,156,24);

   textFieldStatusLine.setText("About Novell Research");

   textFieldStatusLine.show();

 

   //}}

}



void invisibleButtonAbout_Action(Event event) {



   //{{CONNECTION

   // Load a new instance of browser with specified URL...

   try {

      AppletContext context = getAppletContext();

      URL u = new URL(getDocumentBase(),"about.htm");

      context.showDocument(u, "_blank");

      } catch (java.net.MalformedURLException error) {

   }

   //}}

}



public void init() {

   super.init();



   // Take out this line if you don't use symantec.itools.net.RelativeURL

   symantec.itools.lang.Context.setDocumentBase(getDocumentBase());



   //{{INIT_CONTROLS

   setLayout(null);

   addNotify();

   resize(636,465);

   imageViewerCmdCtrMap = new symantec.itools.multimedia.ImageViewer();

   imageViewerCmdCtrMap.reshape(0,0,640,468);

   add(imageViewerCmdCtrMap);

   try {

      imageViewerCmdCtrMap.setURL(symantec.itools.net.RelativeURL.getURL("Spacewld.gif"));

   } catch (java.net.MalformedURLException error) {

   textFieldStatusLine = new java.awt.TextField();

   textFieldStatusLine.hide();

   textFieldStatusLine.reshape(0,0,156,24);

   add(textFieldStatusLine);



   invisibleButtonAnthology = new symantec.itools.awt.InvisibleButton();

   invisibleButtonAnthology.reshape(36,108,87,111);

   add(invisibleButtonAnthology);



   invisibleButtonAbout = new symantec.itools.awt.InvisibleButton();

   invisibleButtonAbout.reshape(276,288,93,96);

   add(invisibleButtonAbout);

   //}}

}



public boolean handleEvent(Event event) {

   if (event.target == invisibleButtonAbout && event.id == Event.ACTION_EVENT) {

      invisibleButtonAbout_Action(event);

      return true;

   }

   if (event.target == invisibleButtonAbout && event.id == Event.MOUSE_ENTER) {             

   //   notice == "" ) {

      invisibleButtonAbout_MouseEnter(event);

      return true;

   }

   if (event.target == invisibleButtonAbout && event.id == Event.MOUSE_EXIT) {

      invisibleButtonAbout_MouseExit(event);

      return true;

   }

   if (event.target == invisibleButtonAnthology && event.id == Event.MOUSE_ENTER) {

      invisibleButtonAnthology_MouseEnter(event);

      return true;

   }

   if (event.target == invisibleButtonAnthology && event.id == Event.MOUSE_EXIT) {

      invisibleButtonAnthology_MouseExit(event);

      return true;

   }

   if (event.target == invisibleButtonAnthology && event.id == Event.ACTION_EVENT) {

      invisibleButtonAnthology_Action(event);

      return true;

   }

   return super.handleEvent(event);

}



   //{{DECLARE_CONTROLS

   symantec.itools.multimedia.ImageViewer imageViewerCmdCtrMap;

   java.awt.TextField textFieldStatusLine;

   symantec.itools.awt.InvisibleButton invisibleButtonAnthology;

   symantec.itools.awt.InvisibleButton invisibleButtonAbout;

   //}}

}

Here is a full screen shot of the finished applet running in Netscape Navigator after the user has clicked in two of the hot spots and has the mouse over one of the hot spots in the "main" browser.

Figure 5: Environment after two invisible buttons have been pressed.

Possible Enhancements

This applet may be useful for some situations but suffers from limitations. Much of the content is hard-coded, limiting the applet's general usefulness. One potential enhancement would be to make the applet more general purpose by using applet parameters in the HTML applet tag to pass information to the applet, such as the URL for the image to be used for the map, the location and size for n number of invisible buttons, the text for display in the balloon help, and the relative URLs to used for each hot spot.

This information could also be passed in or dynamically loaded in some other way with a little work. Parameter passing was discussed in the DevNote "Anatomy of a Java Applet-Part 1."These enhancements would create a general purpose image map applet that could be used in any number of situations and configured by non-developer types.

The applet as it stands also doesn't do anything that can't be done with an HTML client-side image map. However, consider the extensibility of an applet versus a client-side image map. Additional functionality could be easily added, such as gathering user metrics, security enhancements, or whatever else you can think of that can be coded.

Final Thoughts

The intent of this DevNote was to help you get familiar with the fundamentals portions of the AWT and its event handling capabilities. Knowledge of these concepts is a critical step in becoming an efficient Java developer. The sample application illustrated event handling, including generating an event framework for an applet based on events such a keystrokes and mouse interaction.

Look for future DevNotes on Java and Java applets that extend this discussion. If you would like to comment directly on this article or hear more on a particular Java subject, please e-mail me at scjones@novell.com.

For More Information

If you are looking for the latest information, please refer to the following Novell developer resources: "Exploring the NetWare Web Server," Novell Application Notes, Feb. 1996. "Exploring the NetWare Web Server-Part 2," Novell Application Notes, Mar. 1996. "Exploring the NetWare Web Server-Part 3," Novell Application Notes, Sep. 1996. "Introduction to Java and the Java Infrastructure for NetWare," Novell Developer Notes, June, 1996. "NetWare SDK for the Java Platform," Novell Developer Notes, June, 1996. "Java on NetWare Takes Shape," Novell Developer Notes, Jul. 1996. "Anatomy of a Java Applet-Part 1," Novell Developer Notes, Aug. 1996. "The Java Development Kit for NetWare," Novell Developer Notes, Nov. 1996.

Novell Research web site at URL http://www.novell.com/research/ Novell IntranetWare SDK for Java Download page http://developer.novell.com/net2000/java/ Novell's DeveloperNet web site at URL: http://developer.novell.com/ Sun's Java web site at http://java.sun.com/

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates