17.22 JAVA APPLETS


17.22 JAVA APPLETS

A JApplet in Swing and an Applet in AWT are graphical objects that can be embedded in a web page and viewed at a remote site when a web browser points to the web page. Practically any graphical application in Java can be converted into an applet. While a generic web page shows mostly textual information and images, you can use applets to show animated clips, play sound files, and so on, and, to elicit information from the viewer of a web page. When an applet is used for displaying animated clips or playing sound files, the computing that is required for doing so is carried out on the local machine where the web page is viewed. Since such computing may require access to other Java classes (for example, the math classes that are often needed for graphical rendering and animation of 3D scenes) and system resources on the local machine, an important issue concerning applets is security regarding the level of access available to an applet.

That a graphical application in Java, written for command line execution, can be converted very simply into an applet is a consequence of the fact that Applet is a subclass of the AWT class Panel and the Swing class JApplet is a subclass of Applet. That makes an applet an AWT/Swing component, just like a button, a text area, and so on, with the difference that an applet is meant to be executed by a special version of the Java Virtual Machine that is embedded in a Java-enabled web browser. The reason that a special version of JVM is needed for executing applets is because, unlike regular AWT/Swing classes, an applet should be executable without the function main and because of the security issues that surround the invocation of applets.

There are basically four steps to go through to convert a graphical application that is invoked from a command line into an applet that is invoked automatically by a web browser at a remote workstation:

  1. Change the header of the class so that the class now extends JApplet or Applet as opposed to, say, JFrame or Frame. If you plan to use Swing components in your applet, you must extend JApplet.

  2. The code that was in the constructor is now placed in init. What a constructor does for a regular Java graphical program, init does for an applet-it carries out the initializations needed when the applet is first loaded in.

  3. Eliminate the function main.[36] The work that was done by main now gets distributed. The job of creating a frame object in main is now carried out implicitly by the web browser. The sizing as established by the invocation of setSize is now taken care of by assigning values to the WIDTH and the HEIGHT fields of the APPLET tag in an associated HTML file that we will discuss shortly. The location of the display on the screen, as established by the invocation of setLocation, is now left to the discretion of the web browser, determined mostly by the value of the ALIGN field of the APPLET tag in the HTML file.

  4. Declare the applet class public so that the program that runs the applet, which will either be a browser JVM or the appletviewer tool, can access it.

17.22.1 Life Cycle of an Applet

The Applet class provides the following methods that can be used to control the different phases of an applet:

      init()      start()      stop()      destroy() 

As mentioned before, the init method is used to carry out the sort of initializations for an applet that a constructor carries out for an AWT/Swing application. The other three methods become important when an applet is used for displaying animation or for playing a sound file, activities that require continuous computations.

The start method is called automatically after the init method. It is also called automatically whenever a user revisits the page containing the applet. The start method is therefore useful for starting, for example, animation threads after they have been initialized by the init method.[37]

If an applet needs a start method, in most situations it would also need a stop method. The stop is invoked automatically if the applet becomes invisible for some reason, such as when it is iconified or when the user goes off to another web page. The stop methods can therefore be used for suspending the threads of computations needed for animation, sounds, and so on. When the applet is made visible again, the start method will again be automatically invoked to restart the suspended threads. There is almost never a reason to invoke the stop method directly. That is, its invocation is at the discretion of the browser.

The destroy method is invoked automatically when the browser gets ready to shut down normally. For most applets you would not need to override the destroy method since the stop method that will always be invoked prior to the destroy method would have stopped the execution of the applet anyway. This method has been provided in case an applet needs to free up other system resources.

17.22.2 The Applet Tag

To embed an applet in a web page, you need to invoke the applet class within the <APPLET> and </APPLET> HTML tags. As shown below, the <APPLET> tag comes with a number of attributes, some of which are mandatory and other optional, the latter kind are shown bracketed:

      < APPLET              [CODEBASE = codebaseURL]              CODE = appletFile              [ALT = alternateText]              [NAME = appletInstanceName]              WIDTH = pixels              HEIGHT = pixels              [ALIGN = alignment]             [VSPACE = pixels]             [HSPACE = pixels]      >      [< PARAM NAME = appletParameter1 VALUE = value >]      [< PARAM NAME = appletParameter2 VALUE = value >]      [alternateHTML]      </APPLET> 

The CODE, WIDTH, and HEIGHT attributes of the <APPLET> tag are mandatory, in the sense that they must be specified in an HTML file.

Although we have shown all the attributes, such as CODEBASE, CODE, and so on, in uppercase, they can be in any mixture of uppercase and lowercase. The CODEBASE attribute can be used to specify the base URL of the applet. By default, the browser that displays the applet looks for the applet code in the same directory (of the remote host) that contains the HTML file containing the applet tag. But sometimes it is more convenient for the applet code to be stored elsewhere. By giving a value to CODEBASE, you can tell the browser where to find the code for the applet. The value given to CODEBASE can be either relative or absolute. A relative value is a pathname with respect to the location of the folder that contains the HTML file. When the value of CODEBASE is a full http address, it is called absolute. With an absolute value, you could use an applet situated anywhere on the web in your HTML file.

When the applet code is in the same directory as the HTML file that invokes it, the value of the required attribute CODE is just the name of the applet class. However, if the applet code is in some other directory, the value of the CODE attribute must be the full pathname to the file containing the applet code. So if your applet class file is in a subdirectory of the directory containing the HTML file, that fact can be made known to the browse either via the CODEBASE attribute or via the CODE attribute. But note that while CODEBASE is allowed to be absolute, making possible retrieval of applets from virtually anywhere on the web, CODE can only be relative with respect to the base URL of the applet, meaning the http address of the HTML file invoking the applet.

The optional attribute ALT specifies text that will be displayed if the browser understands the <APPLET> tag but is not equipped to run the Java applet.

The optional attribute NAME can be used to associate a handle with the applet. Such handles permit inter-applet communication between applets running in the same web page.

The required attributes WIDTH and HEIGHT are used to specify in pixels the width and the height of the applet.

The optional attributes ALIGN, VSPACE, and HSPACE work the same way as they do for the <IMG> HTML tag. ALIGN cap be used to help the browser decide where to place the applet in relation to the rest of the material on the web page. The various possible values for the ALIGN attribute are: left, right, top, texttop, middle, absmiddle, baseline, bottom, absbottom. The attributes VSPACE and HSPACE control the amount space in pixels to be left above, below, and to the sides of an applet.

The <PARAM> tag can be used to put the same applet program to multiple uses, each with a different set of parameters that characterize different aspects of the information displayed in the applet. For example, the parameters may specify image locations and their sizes, locations and sizes of graphical objects displayed in the applet, URL's of web resources to be downloaded and displayed, and so on. The PARAM tag if used must appear immediately after the APPLET tag. The parameter values are always strings even if they are not specified as strings in the HTML file. The following usage shows how the parameters are interpreted in the applet code:

     String boxWidthString = getParameter( "BOX.WIDTH" );           //(A)     if ( boxWidthString != null )                                  //(B)         boxWidth = Integer.parseInt( boxWidthString );             //(C)         else boxWidth = 200;                                       //(D) 

In line (A), the method getParameter gets from the HTML file the value of the parameter BOX_WIDTH. Since the returned value is always a string, it is used to instantiate a String variable boxWidthString. To make sure that a value for this parameter was indeed specified in the HTML file, we compare the value of boxWidthString against null in line (B). If non-null, we convert it into an integer in line (C), which then becomes the value of the variable boxWidth in the applet program. We also provide a default value in line (D) just in case a value for the parameter BOX_WIDTH was not specified in the HTML file.

For browsers that do not understand the <APPLET> tag, it is useful to include some HTML code, referred to by alternateHTML in the syntax specification shown above, to inform the viewer as to the nature of the applet that the browser is not able to display. Java enabled browsers will ignore this additional HTML.

17.22.3 An Applet Example

We will now design an applet that does the following:

  1. The applet should display a sequence of images to a user whose browser has invoked the applet at a remote site. The nature of the display should be as if the user was watching a slide show presentation on his/her browser. For that reason, the applet will be called SlideShowApplet.

  2. Since it can take a while to load all the images into the browser Java Virtual Machine, the applet should display status messages like "Loading image i" for different value of i as the ith image is loaded in.

  3. The images should be displayed a fixed time interval apart. The time interval between successive images should be a parameter value supplied by the HTML code associated with the applet.

  4. If an image is larger than the size of the applet window as specified in the HTML file, then the image should appear with scrollbars so that all parts of the image can be examined.

The program below shows an applet that meets the above specifications. The special features of the program are as follows:

  • Use of the Timer class to display the images at fixed intervals.

  • The loading of images into the program in a separate thread of computation. (What's meant by a separate thread of computation will be made clear in the next chapter.)

  • Use of the ImageIcon class (as opposed to the Image class) for representing the images.

  • The use of a JLabel as a Scrollable object for displaying scrollable images when the image size is larger than the size of the applet window.

In what follows, each of these features will be discussed separately.

In order to show the images at fixed time intervals, the program uses the Timer class, the first argument to whose constructor is the time interval between the successive images:

    Timer timer;                                                   //(A1)    ....    timer = new Timer( pause, new ActionListener() {               //(A2)              public void actionPerformed( ActionEvent evt ) {     //(A3)                        ....                        contentPane.repaint();                     //(A4)                         }                           });    timer.setInitialDelay( 0 );                                    //(A5)    timer.setCoalesce(false);                                      //(A6)    ....    timer.start();                                                 //(A7)    ....    timer.stop();                                                  //(A8)    ....    timer.restart();                                               //(A9) 

The second argument to the Timer constructor in line (A2) is an ActionListener object whose actionPerformed method traps the timing signals issued after every interval equal to the value of pause in milliseconds. Note that pause is the first argument to the constructor invocation in line (A2).

If contentPane is the content pane of the applet, then the invocation of contentPane. repaint can be used to paint a new image in the applet window at the receipt of a timing signal, as we do in line (A4). The invocations setInitialDelay in line (A5) and setCoalesce in line (A6) are further initializations of the timer before the timing action is actually started by calling start. By default, a timer issues its first timing signal after a delay equal to the value of pause; but the exact moment of this first signal can be controlled by invoking setlnitialDelay. The invocation setCoalesce deals with the situation of multiple pending invocations of actionPerformed, corresponding to consecutive timing signals, getting bunched up because the system was too busy to trap each timing signal separately. When the argument to setCoalesce is true, all the pending invocations of actionPerformed are coalesced into a single call. This is the default behavior. However, when the argument is false, any pending invocations of actionPerformed will be processed separately no matter what.

About the other calls shown above, we have already mentioned that the timer is started by invoking start, as in line (A7). It is stopped by invoking stop, as in line (A8). After stopping, the timer can be restarted by invoking restart, as in line (A9). A restart cancels any timing signals between the moment the timer was stopped and the moment it is restarted. After a restart, the first timing signal is issued after the delay specified by setInitialDelay.

That brings us to the subject of image loading, which in the program shown below is carried out by the loadImages method, defined in the program at line (O). Note how this method is run in a separate thread in init in line (M):

      new Thread() {          public void run() {             loadImages();      }     }.start(); 

The syntax used for creating a new thread of computation will become clear in the next chapter. Suffice it to say here that without running the loading of images in a separate thread, the viewer of the applet may not be able to see the load status messages in the applet window.[38]

The applet program shown below uses the ImageIcon class for representing images, as opposed to the Image class. As was mentioned earlier in Section 17.9, the advantage of the former is that it automatically uses a MediaTracker for image loading. So, unless there is a need to keep track of the progress of loading for each image, it is more efficient to use ImageIcon for image representation.

To deal with the requirement that images larger than the applet window show up with scrollbars, the program SlideShowApplet.java "paints" each image inside a JLabel object. A JLabel is a Scrollable object, and can therefore be displayed in a JScrollPane. Shown below is the part of the applet program that first loads an image into a JLabel object and then places the JLabel object inside a JScrollPane (see line (E)). The images are stored in an ImageIcon array called images (see program line (I)).

      ImageIcon[] images[numImages];      ....      JScrollPane scrollableImage;      ....      scrollableImage =           new JScrollPane(new JLabel(images[ frameIndex - 1 ],                          JLabel.CENTER));      scrollableImage.setPreferredSize( new Dimension( displayWidth,                                         displayHeight - 8)); 

Each scrollable image formed in this manner is painted in the content pane of the applet by the following override definition of the paintComponent method (see line (D)):

 public void paintComponent(Graphics g) {      super.paintComponent(g);      ....      ....      if (scrollableImage != null) {           contentPane.removeAll();           contentPane.add(scrollableImage);      }      contentPane.revalidate();      contentPane.setVisible(true);      .... } 

As you'd expect, the call to removeAll removes the previous image from the content pane of the applet and the call to add inserts the next image. The invocation of revalidate is a request to the layout manager to do its job again with regard to the newly inserted or modified component.

Recall that the paintComponent method will be invoked by the Timer object at the issuance of each timing signal. So all we have to do is to increment image index variable frameIndex to load a fresh image into the content pane. This is done in line (H) of the program.

Finally, the reader should note in the loadImages method in line (L) the syntax of the command used for loading the images from the web site where the applet is posted. The code for this method is reproduced here:

 public void loadImages() {      String prefix = dir + "/flower";      for (int i = 0; i < numImages; i++) {           ....           ....           try {                images[i] = new ImageIcon(new URL(getCodeBase() +                                                   prefix + (i+1) + ".jpg"));                } catch(MalformedURLException m) {                     System.out.println(                          "Couldn't create image: badly formed URL");                }           }           ....           .... } 

Note in particular the invocation:

      images[i] = new ImageIcon(                new URL(getCodeBase() + prefix + (i+1) + ".jpg")); 

For command line applications, it is possible to construct an ImageIcon object simply by

      String imageFileName;      ImageIcon image = new ImageIcon(imageFileName); 

but an applet needs the more elaborate invocation because the image loader in the web browser JVM must establish a communication link with the site hosting the applet and the associated images. This requires that the ImageIcon constructor be supplied with a URL object containing the network address of the site hosting the applet. The method getCodeBase plays a critical role in this, as it is this method that supplies the base URL to the directory containing the applet web page.

Shown below is the program for the applet:

 
//SlideShowApplet.java import javax.swing.*; import java.awt.*; //for Graphics, Color, Dimension, etc. import java.awt.event.*; import java.net.*; //for URL needed for image loading public class SlideShowApplet extends JApplet { //(B) int frameIndex = 0; //current frame number String dir; //directory relative to the codebase Timer timer; //timer for sequencing through images int pause; //time interval between images int numImages; //number of images to display int width; //width of the applet int height; //height of the applet int displayWidth; int displayHeight; JComponent contentPane; //the applet's content pane ImageIcon images[]; //the images boolean finishedLoading = false; JLabel statusLabel; JScrollPane scrollableImage; boolean newFrameAvailable = false; public void init() { //(C) //Get the applet parameters. String at = getParameter("dir"); dir = (at != null) ? at : "images/slideshow"; at = getParameter("pause"); pause = (at != null) ? Integer.valueOf(at).intValue() : 2000; at = getParameter("numImages"); numImages = (at != null) ? Integer.valueOf(at).intValue() : 10; width = getWidth(); height = getHeight(); displayWidth = width - getInsets().left - getInsets().right; displayHeight = height - getInsets().top - getInsets().bottom; contentPane = new JPanel() { public void paintComponent(Graphics g) { //(D) super.paintComponent(g); if (finishedLoading && newFrameAvailable) { scrollableImage = new JScrollPane( new JLabel( images[frameIndex - 1], //(E) JLabel.CENTER)); scrollableImage.setPreferredSize( new Dimension( displayWidth, displayHeight - 8)); } if ( scrollableImage != null) { contentPane.removeAll() ; contentPane.add(scrollableImage); } contentPane.revalidate(); contentPane.setVisible(true); newFrameAvailable = false; } }; contentPane.setBackground(Color.white); //(F) setContentPane(contentPane); statusLabel = new JLabel("Loading Images...", JLabel.CENTER); statusLabel.setForeground(Color.red); contentPane.add(statusLabel); timer = new Timer(pause, new ActionListener() { //(G) public void actionPerformed(ActionEvent evt) { frameIndex++; //(H) if (frameIndex == numImages) frameIndex = 1; newFrameAvailable = true; contentPane.repaint(); } }); timer.setInitialDelay(0); timer.setCoalesce(false); images = new ImageIcon[numImages]; //(I) new Thread() { //(J) public void run() { loadImages(); } }.start(); } public void start() { //(K) if ( finishedLoading) timer.restart(); } public void loadImages() { //(L) String prefix = dir + "/flower"; for (int i = 0; i < numImages; i++) { statusLabel.setText("loading image " + (i + 1)); try { images [i] = //(M) new ImageIcon( new URL(getCodeBase() + prefix + (i+1) + ".jpg")); } catch(MalformedURLException m) { System.out.println( "Couldn't create image: badly formed URL"); } } finishedLoading = true; statusLabel.setText(null); timer.start(); } public void stop() { //(N) timer.stop(); } public String getAppletInfo() { //(O) return "Title: A SlideShow Applet\n"; } public String[][] getParameterInfo() { //(P) String[][] info = { {"dir", "String", "the directory containing the images to loop"}, {"pause", "int", "the time interval between successive frames"}, {"numImages", "int", "the number of images to display; default is 10 " }, }; return info; } }

The applet shown above also includes code for the methods getAppletInfo in line (O) and getParameterInfo in line (P). Presumably, browsers of the future will use the former for giving the viewer a brief description of what the applet does and the latter for helping the viewer set interactively the values of the various applet parameters.

To embed this applet in a web page, we need to invoke the SlideShowApplet class within the <APPLET> and </APPLET> HTML tags as shown by the HTML code below. This code is placed in file that is conveniently named SlideShowApplet.html:

 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Run Slide Show</title> <body> <APPLET CODE = "SlideShowApplet.class" WIDTH = "600" HEIGHT = "500" > <PARAM NAME = "numImages" VALUE ="21"> <PARAM NAME = "pause" VALUE ="8000"> <PARAM NAME = "dir" VALUE ="images/slideshow"> Your browser is completely ignoring the <APPLET> tag! </APPLET> </body> </html>

If you move the code compiled from the SlideShowApplet.java file and the SlideShowApplet.html file into a directory available for HTTP access, a remote user downloading the SlideShowApplet.html page would be able to watch the slide show.[39] However, for code development, it is more convenient to use the appletviewer tool for testing applets on your local machine without having to invoke them through a web browser. To use the appletviewer for the above example, we'd say

     appletviewer SlideShowApplet.html

The window created by the applet with one of the images displayed therein is shown in Figure 17.42.

click to expand
Figure 17.42

17.22.4 Dual-Purpose Programming for Applets

It is interesting and useful to note that it is possible to write an applet program in such a way that the same program can be used as an application, executable with the command-line application launcher java, and as an applet that would be viewable at a remote workstation through a web browser (or locally with the appletviewer tool). Evidently, for command-line invocation, a class must have main since that's the function which is invoked when you execute a class. But one has to be careful when one writes main for a Java program that must serve both as an applet and as a command-line executable graphical application.

In this subsection, we will use the SlideShowApplet.java program of the previous subsection as an example and show how such a program must be modified if it is to run both as an applet and as a standalone command-line executable graphical application.

As we mentioned already, one has to exercise care in writing a main that could be embedded in an applet program so that it can be executed with the java tool. For example, it would not work if we added the following main to the code for SlideShowApplet.java:

      public static void main(String[] args) //WRONG      {           SlideShowApplet s = new SlideShowApplet();           s.setSize( 600, 500 );           s.setVisible(true);      } 

That's because a JApplet is merely a Panel and a Panel object cannot be displayed on a terminal unless it is embedded in a JFrame. To get around this difficulty, we must create a JFrame in main, as we do in line (A) below, and then embed the applet panel in the frame, as in line (D):

 //needed for running SlideShowApplet as a //stand-alone application      public static void main(String[] args) {           JFrame f = new JFrame("slide show");                      //(A)           f.addWindowListener(new WindowAdapter() {           public void windowClosing(WindowEvent e) {           System.exit(0);      }    });           Container cPane = f.getContentPane();                    //(B)           SlideShowApplet slideshow = new SlideShowApplet();       //(C)           cPane.add(slideshow, BorderLayout.CENTER);               //(D)           f.pack();           f.setSize(600, 500);           f.setVisible(true);      } 

There is also the issue of the constructor: While a graphical application needs a constructor, the work of the constructor will most likely be done by init for an applet. To get around this problem, we can include the following constructor in the code shown for SlideShowApplet.java. Note that the constructor in line (E) calls the init method in line (G). In this manner, the browser JVM can use the code in the init method directly for constructing the applet and the regular JVM will use the constructor.

       //constructor needed to run SlideShowApplet.java       //as a stand-alone application       public SlideShowApplet() {                                   //(E)      inApplet = false;                                             //(F)      init();                                                       //(G) } 

The boolean variable inApplet that makes its appearance in line (F) is to control the behavior of init in the two separate modes in which it will be invoked-directly by the browser JVM and indirectly by the above constructor in line (G). For the goals of this subsection, the class SlideShowApplet would be defined with this boolean variable default-initialized to true as follows:

 public class SlideShowApplet extends JApplet {     boolean inApplet = true;   //needed to switch between                                //execution as an applet and                                //as a stand-alone application     // the rest of the data     // members the same as     // before        ..... 

The following implementation for the new dual-use init method should now make sense:

     public void init() {          //check if running as an applet          //or as a stand-alone application          if (inApplet) {                                              //(H)                String at = getParameter("dir");                dir = (at != null) ? at: "images/slideshow";                at = getParameter("pause");                pause =                     (at != null) ? Integer.valueOf(at).intValue() : 15000;                at = getParameter("numImages");                numImages =                     (at != null) ? Integer.valueOf(at).intValue() : 21;                width = getWidth();                height = getHeight();          }          else {                                                      //(I)                dir = "images/slideshow";                pause = 15000;                numImages = 21;                width = 600;                height = 500;          }          // the rest of the code for init() remains the same as before          ....          .... 

So when init is called directly by a browser JVM, the if block starting in line (H) will be executed. This is the same code that you saw in the beginning section of init in SlideShowApplet.java. On the other hand, if init is called indirectly by the constructor of line (E) above when the class SlideShowApplet is executed as a command-line application, it is the else block starting in line (I) that will be executed.

The last change we need to make is to the loadImages method of SlideShowApplet.java. Recall that this method loaded each image into an ImageIcon object and that the ImageIcon constructor was supplied with the network address of the site hosting the images for the applet. That is obviously unnecessary when the same program is run as a standalone application. Shown below is modified implementation for loadImages whose behavior is again controlled by the boolean flag inApplet. When the modified SlideShowApplet.java is run as an applet, the code in the if block starting in line (J) will be executed. And when run as a standalone application, the simpler invocation of the ImageIcon constructor in the else block in line (K) will be used.

 public void loadImages() {      String prefix = dir + "/flower";      for (int i = 0; i < numImages; i++) {           statusLabel.setText("loading image" + (i+1));           //check if running as an applet or           //as a standalong application:           if (inApplet) {                                            //(J)                try {                     images[i] = new ImageIcon( new URL(getCodeBase() +                                               prefix + (i+1) + ".jpg"));                } catch(MalformedURLException m) {                     System.out.println("badly formed URL");                }           }           else {                                                     //(K)                images[i] = new ImageIcon(prefix + (i+1) + ".jpg");           }      }      finishedLoading = true;      statusLabel.setText(null);      timer.start(); } 

With all these changes, the code of SlideShowAppliet.java can be made to run both as an applet and as a standalone command-line graphical application.

17.22.5 The AppletContext Interface

There is an applet context of type AppletContext associated with a Java applet. AppletContext is defined as an interface in the java.applet package. The context refers to the document containing the applet. An object of type AppletContext is constructed by invoking the following method that is defined for the class Applet:

     getAppletContext() 

The interface AppletContext declares many useful methods that an applet can call to get a list of all the applets referred to in the same web page, to get by name a specific applet in the same web page, to fetch other documents and multi-media information available on the web, and so on.

This subsection shows how an applet can use the AppletContext object to pull in other web pages available on the web. This we will do by designing a frame-based web page that pulls in some of the on-line GUI tutorials. The format of the page will be as shown in Figure 17.43. Each of the three frames of the browser window has a name, shown double-quoted in the figure. In the frame named "top" will go the title of the web page. The frame named "left" will show a list of items, each associated with a URL. The display in the "left" frame will be created by an applet. The applet will respond to double clicks on the items of the list by displaying in the "right" frame the document corresponding to that item.

click to expand
Figure 17.43

We will first show the HTML code needed to split the web browser window into three frames. We will place this code in a file called GUITutorials.html in an HTTP accessible directory.

 
<!doctype html public "html2.0"> <html> <head> <title>Experimental HomePage</title> <meta name="Author" content="Ehtee Emel"> <meta name="security" content="public"> </head> <FRAMESET ROWS="90,*"> <FRAME NAME="top" src="/books/1/422/1/html/2/top.html" MARGINHEIGHT=2 MARGINWIDTH=2 SCROLLING="no" NORESIZE> <FRAMESET COLS="180,*"> <FRAME NAME="left" src="/books/1/422/1/html/2/Left.html" MARGINHEIGHT=2 MARGINWIDTH=2 SCROLLING="yes" NORESIZE> <FRAME NAME="right" src="/books/1/422/1/html/2/Right.html" MARGINHEIGHT=2 MARGINWIDTH=2 SCROLLING="yes" NORESIZE> </FRAMESET> </FRAMESET> </HTML>

Each statement that begins with the tag FRAMESET sets up a division of the web page at that point. For example, the first such statement

      <FRAMESET ROWS="90,*"> 

says that the rest of the window is to be divided horizontally, with the top portion of height 90 pixels and the bottom portion of height that can be arbitrary. Next, we must declare a name and an HTML file associated with each of these divisions. The statement

      <FRAME NAME="top" src="/books/1/422/1/html/2/top.html" MARGINHEIGHT=2           MARGINWIDTH=2 SCROLLING="no" NORESIZE> 

says that the top frame of the horizontally divided window will be called "top" and that its contents will be controlled by the file "top.html". What follows are the values for the various parameters of this frame. We can choose whether or not to make this frame scrollable and whether or not to make it resizable.

If all we wanted to do was to divide the browser window into two frames horizontally, the next statement in GUITutorials. html would be similar to the one we just showed, except that it would refer to the bottom portion of the horizontally divided window. But we now want to create a vertical division. This we do with another FRAMESET statement:

      <FRAMESET COLS="180,*"> 

This statement says that the rest of the window is to be divided vertically into two frames. The left frame will be 180 pixels wide, and the width of the right frame is arbitrary. The next two statements in the GUITutorials. html file do for each of the partitions created by the vertical division what we showed previously for the "top" frame.

As was mentioned before, the purpose of the "top" frame is to show the purpose of the page. So the contents of the file top. html could be something like this:

 
<HTML> <! --- <body bgcolor="#ffffdd"> ----> <BODY BGCOLOR="#aadddd"> <font size=4> <B>Online GUI Tutorials</B> </font> <pre> </pre> </BODY> </HTML>

By comparison, the file left. html for the "left" frame is a bit more complicated because it must invoke the applet Left.Java. The way this HTML file is set up, the GUI tutorial names and their associated URL's are all contained in this file in the form of parameters declared by PARAM tags. For example, the first item we'd like to show in the left frame is "Swing Tutorial". This is our "item_1". Following the declaration of this item, we have another parameter, "url_1", whose value is a web address of where the Swing tutorial is located. We repeat this paired declarations for two more items-for "Qt Tutorial" and for "GTK+ Tutorial". In this manner, all of the items that need to be displayed in the left frame and their associated URL's stay in the HTML file itself.

 
<HTML> <TITLE>A Trial Applet</TITLE> <BODY BGCOLOR="#ffffff"> <pre> </pre> <font size=2> <para> <APPLET CODE="Left.class" WIDTH=180 HEIGHT=480> <PARAM NAME=item_1 VALUE="Swing Tutorial"> <PARAM NAME=url_1 VALUE= "http: // java.sun.com/docs/books/tutorial/uiswing/index.html"> <PARAM NAME=item_2 VALUE="Qt Tutorial"> <PARAM NAME=url_2 VALUE= "http://doc.trolltech.com/2.3/tutorial.html"> <PARAM NAME=item_3 VALUE="GTK+ Tutorial"> <PARAM NAME=url_3 VALUE="http://www.gtk.org/tutorial/"> </APPLET> </BODY> </HTML>

The purpose of the applet Left.java invoked in the above HTML file is to actually show a list of the names of the tutorials in the left frame and then to be responsive to mouse clicks on the names for displaying the corresponding web pages in the right frame. We will show the tutorial names in the form of a list by using the AWT component List that will be constructed by the invocation:

       private List links = new List(3, false); 

for the three tutorials whose names we want displayed. (If a List component contains more items than the integer that is the first argument in the constructor, the displayed list is made scrollable.) The second argument, a boolean, specifies whether the user is allowed to select more than one item at a time from the list. By making it false, the user will be able to select only one item at a time. Every time the user selects an item, by double-clicking on it, Java generates an ActionEvent that when trapped can be used to determine the identity of the item clicked on. In the following code, the applet itself is a listener for ActionEvents because it implements the ActionListener interface.

 
//Left.Java import java.awt.*; import java.awt.event.*; import java.applet.*; import java.net.*; import java.io.*; public class Left extends Applet implements ActionListener { private List links = new List(3, false); public void init() { setLayout(new BorderLayout() ); setBackground(Color.red); Font f = new Font("SansSerif", Font.BOLD, 14); setFont(f); Panel p = new Panel(); p.setLayout(new BorderLayout() ); p.add(links, "Center"); links.addActionListener(this); int i = 1; String s; while ( (s = getParameter( "item_" + i) ) != null) { links.add(s); i++; } add(p, "Center"); } public void actionPerformed(ActionEvent evt) { try { String str = evt.getActionCommand(); AppletContext context = getAppletContext(); int i = 1; String s; while ( ( s = getParameter( "item_" + i) ) != null) { if ( str.equals( s) ) { URL u = new URL( getParameter( "url_" + i) ); context.showDocument( u, "right"); } i++; } } catch( Exception e) { showStatus("Error" + e); } } }

In order to download a web document, the above applet first constructs an object of Java class URL by

     URL u = new URL(getParameter("url_" + i) ); 

where the argument to the URL constructor is the actual web address that is returned by the getParameter method. The web document is then downloaded into the right frame by

     AppletContext context = getAppletContext();     context.showDocument(u, "right"); 

It is through the AppletContext object context that the showDocument method becomes aware of the fact that "right" is the name of the right frame. The method then proceeds to show the web document in that frame.

That leaves only the file Right.html yet to be described. Since the right frame's sole function is to display the web documents when a user clicks on the items in the left frame, the contents of this file can be as simple as

 <HTML> <TITLE> Web pages will be displayed here </TITLE> <BODY BGCOLOR="#dddddd";> double click on any of the items on the left </BODY> </HTML> 

17.22.6 Security Issues Related to Applets

As was mentioned earlier, security is an important issue related to applets since they are downloaded from remote hosts and require local computing resources. So it becomes an important issue as to what local resources an applet can gain access to. The security considerations are different depending on whether an applet is viewed through a web browser or by using the appletviewer tool. For obvious reasons, the security restrictions are more stringent when an applet is viewed through a browser.

In general, an applet loaded into a browser cannot read a local file or write into a local file, nor can it execute a local executable file. An applet is not allowed to even check for the existence of a local file, or rename a local file, or check a file's size, or create a directory on the local disk, and so on. However, when an applet is viewed with appletviewer, the applet can be allowed to read files and directories, provided that those files and directories are named in the acl.read property in the /.hotjava/properties file. An applet viewed with appletviewer is also allowed to write into files provided such files are named in acl.write property in the /.hotjava/properties file.

An applet, when viewed either through a browser or with appletviewer, can read the following system properties by invoking System. getProperty(String key) or System.getProperty (String key, String default) where the string key stands for one of the following arguments on the left:[40]

   key                 meaning ------------         ------------------    Java.version        Java version number   java.vendor         Java vendor-specific string   java.vendor.url     Java vendor URL   java.class.version  Java class version number   os.name             Operating system name   os.arch             Operating system architecture   os.version          Operating system version   file.separator      File separator (eg, "/")   path.separator      Path separator (eg, ":")   line.separator      Line separator 

Applets, when viewed either through a web browser or with appletviewer, are prevented by default from reading these system properties:

   key                 meaning ------------         ------------------     key                meaning    java.home          Java installation directory    java.class.path    Java classpath    user.name          User account name    user.home          User home directory    user.dir           User's current working directory 

However, this default behavior, with regard to both the access and the denial of access to the various system properties, can be gotten around for the case when an applet is loaded into an appletviewer by suitable changes to the /.hotjava/properties file.

Applets, regardless of whether they are loaded into a browser or an appletviewer, are not allowed to open network connections to any computer except for the host that supplied the class file for the applet.

[36]Actually, it is not even necessary to eliminate main, but in general it would need to be modified. Later we will see how by embedding a suitable main inside an applet, we can use the same program as a graphical application that can be invoked from a command line and as an applet that would be viewable from a remote workstation through a web browser.

[37]In the next chapter we will discuss how to write applets for displaying animation.

[38]The reason has to do with the priorities accorded to the different threads by a browser JVM. If the applet has to load images in the main thread, then it is a matter of the priority of the main thread vis-à-vis the priority of what's known as the Event Dispatch Thread that we will discuss in detail in the next chapter. The Event Dispatch Thread handles tasks related to the display of information in the applet window and the user interaction with the display.

[39]The reader should note that many browsers were not Swing-enabled as of the middle of 2002. For obvious reasons, downloading and executing a JApplet can be a problem for users of such browsers. There are two options to deal with this situation: Either you must create purely AWT-based applets or, for a solution that would work for a vast majority of Netscape Navigator and Microsoft Internet Explorer users, you can get the users to deploy automatically a Java Plug-in to run Swing applets. A Java Plug-in enables a browser to use the Sun's Java 2 JRE (Java Runtime Environment) when encountering an applet, rather than the default JRE that comes with the browser. However, the JRE supplied by a Java Plug-in will only be invoked if the applet is included in an HTML page with the <OBJECT> tag for the Internet Explorer browsers and with the <EMBED> tag for the Netscape Navigator browsers. Sun provides an HTML converter tool, called HTMLConverter, that automatically converts a regular HTML file with <APPLET> tags into a file with both <OBJECT> and <EMBED> tags so that with the converted HTML file an applet would run on both Netscape Navigator and Internet Explorer browsers.

[40]Both of the tables shown are reproduced here from http://www.java.sun.com.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net