| Click here to support our advertisers

SHOPPING
JOB BANK
CLASSIFIEDS
DIRECTORIES
REFERENCE Online Library
LEARNING CENTER
JOURNAL
NEWS CENTRAL
DOWNLOADS
COMMUNITY
CALENDAR
ABOUT US
Journal:
Get the weekly email highlights from the most popular journal for developers! Current issue
> developer.com developerdirect.com htmlgoodies.com javagoodies.com jars.com intranetjournal.com javascripts.com | All Categories : Java — 4 —Java's Capabilities Visually Enhancing Pages (And Sound Too!) Clock Applets Juggling Applet Animator Applet SlideShow Applet Adding Functionality to Web Pages Curve Applet StockTrace Applet TeleRadiology Applet Interactive PC Scoreboard Applet The Player Piano Applet Summary # — 4 — Java's Capabilities As discussed previously, Java is a full-featured programming language that is capable of producing full-featured standalone applications. However, the innovations that Java brings to the World Wide Web have created the most interest in Java. This chapter focuses on the ways in which applets can enhance Web pages. Applets can add a variety of enhancements to any Web page, from a personal page to a business page. Within the restrictions placed on applets by browsers and security, you can create astounding applets. Applets can bring sound, animation, user interaction, and much more to your Web pages. ### Visually Enhancing Pages (And Sound Too!) The Web has come a long way since 1992. Now graphics are very common (and sometimes a bit annoying). With the release of Netscape, server-push animation became possible, although it was slow and awkward. This server-push animation is not practical for animations of any significant length and has never really been used for much other than novelty purposes. But with Java, the possibility for real-time animations is a reality. Visual enhancements are some of the simplest applets to program and use. Often these applets are simply variations of image viewers, but you can create surprisingly different applets using the techniques required to make an image viewer. For example, the following applets can be created by displaying and manipulating images: A clock A applet to create an interactive demonstration An interactive animation A photo viewer All these types of applets use image techniques; the clock moves hands to display the time, a demonstration applet shows diagrams, an animator flips a series of images for motion, and a photo viewer cycles through snapshots. All these applets contain a lot of similar code, yet all accomplish different tasks. The following sections examine some of these applets and how they enhance the appearance of Web pages. #### Clock Applets The Web is global entity and is certainly not limited to any specific geographic area or time zone. In fact, the global aspect of the Web is one of its most appealing factors. Java applets can help enhance the global nature of the Web. Many Web pages have begun to incorporate snapshots of the weather outside or other forms of local information. Silly as it may seem, the local time is one of the most basic forms of local information and can be a very useful navigation device. The following Java clocks can be used to show time information on your Web page:
> | Clock
> | Written by Nils Hedström
> | http://www-und.ida.liu.se/~d94nilhe/java/applets.html
> | WorldClock
> | Written by Vijay Vaidy
> | http://www.webpage.com/~vijay/java/wt/testwt.html
> The first clock uses graphic images to draw the hands of an analog clock (see Figure 4.1). The second clock has no graphical enhancements and displays the time and date information using text (see Figure 4.2). Figure 4.1. A clock is an example of an informative applet. Figure 4.2. A simple clock applet showing times at various locations around the world. Listing 4.1 shows some of the Java code used to produce the clock in Figure 4.1. Listing 4.1. Partial code for the Clock applet.
>     public class Clock extends java.applet.Applet implements Runnable

>     {

>       int width,height,num_lines,sleep,timezone,backgroundType;

>       Polygon clockBackground;

>       URL homepage;

>       private Needle hour,minute,second;

>       double pi=3.1415926535f;

>       Color clockBackground_col,clockBackgroundBorder_col,backgroundBorder_col,background_col;

>       Thread animate=null;

>       Image backBuffer;

>       Image backgroundImage;

>       Graphics backGC;

>     public void run() //Run the applet

>         {

>           while (true)

>             {

>               updateNeedles();

>               repaint();

>               try {Thread.sleep(sleep);} catch (InterruptedException e){}

>             }

>         }

>     public void makeClockBackground() // Creates a polygon-background with num_lines-corners

>         {

>           double add,count;

>           clockBackground=new Polygon();

>           add=2.*pi/num_lines;

>           for(count=0;count<=2.*pi;count+=add)

>             {

>               clockBackground.addPoint(size().width/2+(int)(size().width*Math.cos(count)/2.),

>                               size().height/2+(int)(size().height*Math.sin(count)/2.));

>             }

>         }

>       public void drawClockBackground(Graphics g) // Draws the background of the Clock

>         {

>           if(backgroundType!=1)

>             {

>               g.setColor(clockBackground_col);

>               g.fillPolygon(clockBackground);

>               g.setColor(clockBackgroundBorder_col);

>               g.drawPolygon(clockBackground);

>             }

>           if(backgroundType!=0)

>             {

>               int img_width=backgroundImage.getWidth(null);

>               int img_height=backgroundImage.getHeight(null);

>               int x=(size().width-img_width)/2;

>               int y=(size().height-img_height)/2;

>               if (x<0) x=0;

>               if(y<0) y=0;

>               if((img_width!=-1) && (img_height!=-1))

>                 g.drawImage(backgroundImage,x,y,null);

>             }

>         }

>       public void start()  // When the applet is started

>         {

>           if (animate == null) {

>             animate = new Thread(this);

>             animate.start();

>           }

>         }

>       public void stop() // When the applet is stopped

>         {

>           if (animate != null) {

>             animate.stop();

>             animate=null;

>           }

>         }
> A clock applet requires quite a bit of code. Listing 4.1 shows only a third of the code needed to produce the entire clock shown in Figure 4.1. The applet developer must also provide the images used to make up the clock face and hands and the animation that keeps the hands moving and keeping accurate time. The code shown in Listing 4.1 should give you an idea about what's involved in creating Java applets. Java applets are full-fledged programs, and as such, they require some time and planning to create them. #### Juggling Applet Applets can also be used for educational purposes or to inform users about how to accomplish tasks by means of demonstration. Rather than just listing a number of steps, applets can visually demonstrate how to do something. For some topics, a visual demonstration is far more effective than a verbal explanation. The following applet is an example of how you can use graphics and animation to demonstrate concepts (see Figure 4.3):
> | Juggling Applet
> | Written by Christopher Sequin
> | http://www.acm.uiuc.edu/webmonkeys/juggling/
> Figure 4.3. The Juggling Applet is an example of how applets can be used for interactive educational purposes. Listing 4.2 shows the code for the Juggling Applet. Keep in mind that this code does quite a bit. It lets the user configure the number of balls used in the demonstration, it animates the hands, and it animates the balls along the correct paths. Don't worry about compiling this code, the applet is included on the CD-ROM. The listing is just provided to give you an example of some real Java code. Listing 4.2. Code for the Juggling Applet.
>     /*

>      * @(#)Juggling.java                          1.0f 95/05/01 Chris Seguin

>      * E-mail:  seguin@uiuc.edu

>      *

>      * Copyright  1995 University of Illinois (UIUC)

>     */

>     import java.io.InputStream;

>     import java.awt.*;

>     import java.net.*;

>     /**

>      * JugglingImages class. This is a container for a list

>      * of images that are animated.

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     class JugglingImages {

>         /**

>          * The images.

>          */

>         Image imgs[];

>         /**

>          * The number of images actually loaded.

>          */

>         int nImagesCount = 0;

>         /**

>          * Load the images, from dir. The images are assumed to be

>          * named T1.gif, T2.gif...

>          */

>         JugglingImages(URL context, String dir, Juggling parent) {

>             nImagesCount = 0;

>             imgs = new Image[10];

>             int nWidth = 0;

>             for (int i = 1; i < imgs.length; i++) {

>                 Image im = parent.getImage(parent.getDocumentBase(),

>                                            dir + "/T" + i + ".gif");

>                 imgs[nImagesCount++] = im;

>             }

>         }

>     }

>     /**

>      * BallPaths class. This is a container for a path

>     * of juggling balls

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     class BallPaths {

>         /**

>          * Arrays containing the path of the balls

>          */

>         int pnX[] = {0};

>         int pnY[] = {0};

>         int nLength = 1;

>         /**

>          * LookupX - looks up the appropriate value of X

>          */

>         public int LookupX (int nIndex)

>         {

>         if ((nIndex > nLength) || (nIndex < 0))

>             return 0;

>         return pnX[nIndex];

>         }

>         /**

>          * LookupY - looks up the appropriate value of Y

>          */

>         public int LookupY (int nIndex)

>         {

>         if ((nIndex > nLength) || (nIndex < 0))

>             return 0;

>         return pnY[nIndex];

>         }

>         /**

>          * Length - the number of data points stored in the path

>          */

>         public int Length ()

>         {

>         return nLength;

>         }

>     }

>     /**

>      * CascadeBallPaths class. This is a container for a path

>     * of juggling balls, the balls are moving in a standard

>      * cascade pattern

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     class CascadeBallPaths extends BallPaths {

>         /**

>          * Arrays containing the path of the balls

>          */

>         int pnX[] = {     20,   24,   27,   31,   35,

>                           40,   45,   50,   55,   60,

>                           65,   70,   75,   80,   85,

>                           90,   95,  100,  105,  110,

>                          115,  120,  125,  130,  135,

>                          143,  144,  141,  138,  134,

>                          130,  126,  123,  119,  115,

>                          110,  105,  100,   95,   90,

>                           85,   80,   75,   70,   65,

>                           60,   55,   50,   45,   40,

>                           35,   30,   25,   20,   15,

>                            7,    6,    9,   12,   16

>                          };

>         int pnY[] = {     76,   78,   76,   70,   60,

>                           60,   50,   42,   34,   28,

>                           22,   18,   14,   12,   10,

>                           10,   10,   12,   14,   18,

>                           22,   28,   34,   42,   50,

>                           66,   68,   70,   72,   74,

>                           76,   78,   76,   70,   60,

>                           60,   50,   42,   34,   28,

>                           22,   18,   14,   12,   10,

>                           10,   10,   12,   14,   18,

>                           22,   28,   34,   42,   50,

>                           66,   68,   70,   72,   74

>                          };

>         /**

>          *  The length of the arrays

>          */

>         int nLength = 60;

>         /**

>          * LookupX - looks up the appropriate value of X

>          */

>         public int LookupX (int nIndex)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         return pnX[nIndex];

>         }

>         /**

>          * LookupY - looks up the appropriate value of Y

>          */

>         public int LookupY (int nIndex)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         return pnY[nIndex];

>         }

>         /**

>          * Length - the number of data points stored in the path

>          */

>         public int Length ()

>         {

>         return nLength;

>         }

>     }

>     /**

>      * ReverseCascadeBallPaths class. This is a container

>      * for a path of juggling balls, the balls are moving

>     * in a reverse cascade pattern

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     class ReverseCascadeBallPaths extends BallPaths {

>         /**

>          * Arrays containing the path of the balls

>          */

>         int pnX[] = {     12,    9,    6,    3,    0,

>                            0,    5,   10,   15,   20,

>                           25,   30,   35,   40,   45,

>                           50,   55,   60,   65,   70,

>                           75,   80,   85,   90,   95,

>                          100,  103,  106,  109,  112,

>                          115,  118,  121,  124,  127,

>                          130,  125,  120,  115,  110,

>                          105,  100,   95,   90,   85,

>                           80,   75,   70,   65,   60,

>                           55,   50,   45,   40,   35,

>                           27,   24,   21,   18,   15  };

>         int pnY[] = {     60,   60,   60,   60,   60,

>                           60,   51,   42,   35,   28,

>                           23,   18,   15,   12,   11,

>                           10,   11,   12,   15,   18,

>                           23,   28,   35,   42,   51,

>                           60,   60,   60,   60,   60,

>                           60,   60,   60,   60,   60,

>                           60,   51,   42,   35,   28,

>                           23,   18,   15,   12,   11,

>                           10,   11,   12,   15,   18,

>                           23,   28,   35,   42,   51,

>                           60,   60,   60,   60,   60 };

>         /**

>          *  The length of the arrays

>          */

>         int nLength = 60;

>         /**

>          * LookupX - looks up the appropriate value of X

>          */

>         public int LookupX (int nIndex)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         return pnX[nIndex];

>         }

>         /**

>          * LookupY - looks up the appropriate value of Y

>          */

>         public int LookupY (int nIndex)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         return pnY[nIndex];

>         }

>         /**

>          * Length - the number of data points stored in the path

>          */

>         public int Length ()

>         {

>         return nLength;

>         }

>     }

>     /**

>      * JugglingBall class. This is a juggling ball

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     class JugglingBall {

>         /**

>          * The location on the ball's path

>          */

>         int nCycleSlot;

>         /**

>          * The color of the ball - specified by an index into the ball array

>          */

>         int nBallColor;

>         /**

>          * The current location of the ball

>          */

>         int nX;

>         int nY;

>         /**

>          * The path to follow

>          */

>         BallPaths ptbpPath;

>         /**

>          * JugglingBall - creates a juggling ball

>          */

>         public JugglingBall (int nStartPos, int nStartColor, BallPaths ptbpThePath)

>         {

>         nCycleSlot = nStartPos;

>         nBallColor = nStartColor;

>         ptbpPath = ptbpThePath;

>         nX = ptbpPath.LookupX(nStartPos);

>         nY = ptbpPath.LookupY(nStartPos);

>         }

>         /**

>          * Move - moves the ball to the next location

>          */

>         public void Move ()

>         {

>         nCycleSlot++;

>         if ((nCycleSlot >= ptbpPath.Length ()) || (nCycleSlot <= 0)) {

>             nCycleSlot = 0;

>             }

>         nX = ptbpPath.LookupX(nCycleSlot);

>         nY = ptbpPath.LookupY(nCycleSlot);

>         }

>         /**

>          * XLoc - returns the x location

>     */

>         public int XLoc ()

>         {

>         return nX;

>         }

>         /**

>          * YLoc - returns the Y location

>          */

>         public int YLoc ()

>         {

>         return nY;

>         }

>         /**

>          * Color - returns the color

>          */

>         public int Color ()

>         {

>         return nBallColor;

>         }

>     }

>     /**

>      * HandPath class. This is a container for the paths of the hands

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 3, 1995

>      */

>     class HandPath {

>         /**

>          * Arrays containing the path of the hands

>          */

>         int pnLeftHandX[] = {

>                            7,    6,    9,   12,   16,

>                           20,   24,   27,   31,   35,

>                           35,   31,   27,   24,   20,

>                           16,   12,    9,    6,    7

>                          };

>         int pnRightHandX[] = {

>                          143,  144,  141,  138,  134,

>                          130,  126,  123,  119,  115,

>                          115,  119,  123,  126,  130,

>                          134,  138,  141,  144,  143

>                          };

>         int pnHandY[] = {

>                           73,   75,   77,   79,   81,

>                           83,   85,   83,   77,   67,

>                           67,   57,   51,   49,   51,

>                           53,   55,   57,   59,   61

>                          };

>         /**

>          *  The length of the arrays

>          */

>         int nLength = 60;

>         int nBalls = 0;

>         /**

>          * HandPath - creates a hand path

>          */

>         public HandPath (int nStartBalls)

>         {

>         nBalls = nStartBalls;

>         }

>         /**

>          * LookupX - looks up the appropriate value of X

>          */

>         public int LookupX (int nIndex, boolean bLeft)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         //  Limit the lookup to the range

>         if (nIndex >= 20 * nBalls)

>              nIndex = 19;

>         while (nIndex >= 20)

>              nIndex -= 20;

>         //  Look up the value

>         if (bLeft)

>             return pnLeftHandX[nIndex];

>         else

>             return pnRightHandX[nIndex];

>         }

>         /**

>          * LookupY - looks up the appropriate value of Y

>          */

>         public int LookupY (int nIndex)

>         {

>         if ((nIndex >= nLength) || (nIndex < 0))

>             return 0;

>         //  Limit the lookup to the range

>         if (nIndex >= 20 * nBalls)

>              nIndex = 19;

>         while (nIndex >= 20)

>              nIndex -= 20;

>         //  Look up the value

>         return pnHandY[nIndex];

>         }

>         /**

>          * Length - the number of data points stored in the path

>          */

>         public int Length ()

>         {

>         return nLength;

>         }

>     }

>     /**

>      * Hand class. This is a hand

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 3, 1995

>      */

>     class Hand {

>         /**

>          * The location on the ball's path

>          */

>         int nCycleSlot;

>         /**

>          * Whether this is the left hand

>          */

>         boolean bLeft;

>         /**

>          * The current location of the ball

>          */

>         int nX;

>         int nY;

>         /**

>          * The path to follow

>          */

>         HandPath phPath;

>         /**

>          * Hand - creates a hand

>          */

>         public Hand (int nStartPos, HandPath phThePath, boolean bStartLeft)

>         {

>         nCycleSlot = nStartPos;

>         bLeft = bStartLeft;

>         phPath = phThePath;

>         nX = phPath.LookupX(nStartPos, bLeft);

>         nY = phPath.LookupY(nStartPos);

>         }

>         /**

>          * Move - moves the ball to the next location

>          */

>         public void Move ()

>         {

>         nCycleSlot++;

>         if ((nCycleSlot >= phPath.Length ()) || (nCycleSlot <= 0)) {

>             nCycleSlot = 0;

>             }

>         nX = phPath.LookupX(nCycleSlot, bLeft);

>         nY = phPath.LookupY(nCycleSlot);

>         }

>         /**

>          * XLoc - returns the x location

>     */

>         public int XLoc ()

>         {

>         return nX;

>         }

>         /**

>          * YLoc - returns the Y location

>          */

>         public int YLoc ()

>         {

>         return nY;

>         }

>     }

>     /**

>      * A juggling demonstration program

>      *

>      * @author      Chris Seguin

>      * @version     1.0f, May 1, 1995

>      */

>     public class Juggling extends java.applet.Applet implements Runnable {

>         /**

>          * The path of the juggling balls

>          */

>         BallPaths pjbPaths;

>         /**

>          * The juggling balls

>          */

>         JugglingBall pjbBalls[] = {null, null, null};

>         /**

>          * The paths that the hands trace out

>          */

>         HandPath phHandPaths;

>         /**

>          * The hands

>          */

>         Hand phLeft;

>         Hand phRight;

>         /**

>          * The directory or URL from which the images are loaded

>          */

>         String dir;

>         /**

>          * The images used.

>          */

>         JugglingImages jbiImages;

>         /**

>          * The thread animating the images.

>          */

>         Thread kicker = null;

>         /**

>          * The delay between animation frames

>          */

>         int nSpeed;

>         /**

>          * Shape of the window

>          */

>         int nHeight = 0;

>         int nWidth = 0;

>         /**

>          * The number of balls in the demonstration

>          */

>         int nBalls = 0;

>         /**

>          * Parameter info.

>          */

>         public String[][] getParameterInfo() {

>             String[][] info = {

>                 {"balls",  "int",  "the number of balls to animate"},

>                 {"speed",  "int",  "the speed the balls move at"},

>                 {"img",    "urls", "the directory where the images are located"},

>             };

>             return info;

>         }

>         /**

>          * Initialize the applet.  Get attributes.

>          */

>         public void init() {

>             //  Load the parameters from the HTML file

>             String at = getParameter("img");

>             dir = (at != null) ? at : "images";

>             at = getParameter("speed");

>             nSpeed = (at != null) ? Integer.valueOf (at).intValue() : 20;

>             at = getParameter("height");

>             nHeight = (at != null) ? Integer.valueOf (at).intValue() : 100;

>             at = getParameter("width");

>             nWidth = (at != null) ? Integer.valueOf (at).intValue() : 170;

>             at = getParameter("balls");

>             nBalls = (at != null) ? Integer.valueOf (at).intValue() : 3;

>             //  Initialize the Ball variables

>             pjbPaths = new CascadeBallPaths ();

>             pjbBalls[0] = new JugglingBall ( 0, 0, pjbPaths);

>             pjbBalls[1] = new JugglingBall (40, 2, pjbPaths);

>             pjbBalls[2] = new JugglingBall (20, 4, pjbPaths);

>             //  Initialize the hand variables

>             phHandPaths = new HandPath (nBalls);

>             phLeft = new Hand (5, phHandPaths, true);

>             phRight = new Hand (35, phHandPaths, false);

>             resize(nWidth, nHeight);

>         }

>         /**

>          * Run the image loop. This method is called by class Thread.

>     * @see java.lang.Thread

>          */

>         public void run() {

>             //  Create the thread

>             Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

>             //  Load the images

>             jbiImages = new JugglingImages(getDocumentBase(), dir, this);

>             //  Do the animation

>             int ndx = 0;

>             while (size().width > 0 && size().height > 0 && kicker != null) {

>                 for (ndx = 0; ndx < nBalls; ndx++) {

>                     (pjbBalls[ndx]).Move();

>                 }

>                 phLeft.Move();

>                 phRight.Move();

>                 repaint();

>                 try {Thread.sleep(nSpeed);} catch (InterruptedException e){}

>             }

>         }

>         /**

>          * Paint the current frame.

>          */

>         public void paint(Graphics g) {

>             update ;

>         }

>         public void update(Graphics g) {

>             if ((jbiImages != null) && (jbiImages.imgs != null)) {

>                 //  Erase the background

>                 g.setColor(java.awt.Color.lightGray);

>                 g.fillRect(0, 0, nWidth, nHeight);

>                 int ndx = 0;

>                 for (ndx = 0; ndx < nBalls; ndx++) {

>                     if (jbiImages.imgs[pjbBalls[ndx].Color ()] == null) {

>                         System.out.print ("ERROR::No Image ");

>                         System.out.println (ndx);

>                     }

>                     g.drawImage(jbiImages.imgs[pjbBalls[ndx].Color ()],

>                           (pjbBalls[ndx]).XLoc(), (pjbBalls[ndx]).YLoc(), this);

>                 }

>                 //  Draw the hands

>                 g.drawImage(jbiImages.imgs[7],

>                             phLeft.XLoc(), phLeft.YLoc(), this);

>                 g.drawImage(jbiImages.imgs[7],

>                             phRight.XLoc(), phRight.YLoc(), this);

>             }

>         }

>         /**

>          * Start the applet by forking an animation thread.

>          */

>         public void start() {

>             if (kicker == null) {

>                 kicker = new Thread(this);

>                 kicker.start();

>             }

>         }

>         /**

>          * Stop the applet. The thread will exit because kicker is set to null.

>          */

>         public void stop() {

>             kicker = null;

>         }

>     }
> #### Animator Applet This chapter has shown you some simple applets based on animating images, but suppose you wanted to spice up a Web page with something a little more dynamic, such as the capability to interact with user input. Remember that Java has a complete set of windowing tools in the Abstract Window Toolkit. These tools allow you to build interfaces into your applets and create applets that interact with user input. For example, if you wanted to have some sort of animation or display some information based on when a user clicked a mouse, Java enables you to do just that. ClickBoard is an example of an applet that uses both animation and user input. The program can display a series of still images in sequence to create an animation, and the user activates the animation by clicking an image (see Figure 4.4 and Figure 4.5):
> | ClickBoard: Interactive Animation
> | Written by Steve Fu
> | http://www.intrinsa.com/personal/steve/ClickBoard/ClickBoard.html
> ClickBoard is quite flexible, and the user can configure many of the applet's attributes. For example, ClickBoard makes use of a configuration file that allows users to specify the following items: The background colors The number of images in an animation The image files used Sound files to be played during an animation The clickable areas The type and number of actions A configuration file allows the applet to be adaptable without requiring the user to alter the actual program. When you are designing applets that incorporate a number of complex features, configuration files or applet parameters can be a great way to make your applet useful to many people or easy to change later. Implementing configuration files or applet parameters can save you the trouble of reprogramming an applet to change its functionality and also allows you to pass the applet along to other users with a user-friendly method for implementing changes. Figure 4.4. In the ClickBoard applet, the user activates the animation by clicking the fish. Figure 4.5 The ClickBoard animation plays after the user clicks the picture. #### SlideShow Applet Many personal Web pages are enhanced by putting up photographs of family or friends. With a slide show applet, you can put together a collection of images that a user could flip through like a photo album. You could even add sound to the applet to assemble a soundtrack to your slide show. Such an applet could be used for personal photos, product photos, or even presentation slides. The following is an example of such a slide show applet:
> | SlideShow
> | Written by David Gulbransen
> | http://www.fa.indiana.edu/~dgulbran/slideshow.html
> This applet allows you to specify a number of images to be loaded, and a sound file to play. It also has controls to allow the user to flip through the slides or play them in a slide show and a button to turn off the soundtrack (see Figure 4.6). The SlideShow applet is a good example of a fairly simple applet that can be very flexible. Chapter 13 covers the development of the SlideShow applet in detail. Figure 4.6. A slide show applet can add a new twist to a Web photo gallery. ### Adding Functionality to Web Pages In addition to adding more graphics and sound capabilities to Web pages, Java applets can also do a great deal to enhance the functionality of Web pages. You can use applets to provide complex information in a more intuitive way or to simplify the presentation of such information. The following sections describe some applets that show how you can add functionality to a Web page. #### Curve Applet The Curve Applet is an educational applet designed to show different types of mathematical curves and how they are manipulated (see Figure 4.7). The applet shows three types of curves and how those curves are manipulated by points on the curve. Drawing curves is a fundamental part of graphics programming, and this applet helps explain how curves function:
> | Curve Applet
> | Written by Michael Heinrichs
> | Figure 4.7. The Curve applet is both educational and informative, demonstrating different types of mathematical curves. #### StockTrace Applet Because Java can communicate back to a server, applets can be configured to provide data to users in real time. Stock prices, for example, are in a constant state of flux, updating from minute to minute throughout the day. An applet that could provide real-time information about stocks could be invaluable as a device for keeping track of stock prices. The StockTrace Applet enables you to specify stocks to trace, and then fetches the price information from the server and displays current prices (see Figure 4.8). This applet also has a graphing function that enables you to plot the performance of a particular stock. Although putting server-based data onto Web pages has always been possible, updating the data in real time was not practical or easy. Updating standard HTML pages dynamically is slow and taxes both the browser and the server. But because Java applets run within the context of the Java Virtual Machine and open a separate data connection to the host machine, updating Java applets is not taxing for the browser or the Web server. Note: The StockTrace Applet does not currently display active stock data. The data that it retrieves in its current form is for simulation only. Keep in mind that providing users with real-time data from a server requires a server that contains such data, and this applet was designed as proof of concept. The ability to provide real-time data to customers is certainly a value-added service that many companies will begin to exploit in the near future. As Java grows, so will the business opportunities that the technology presents.
> | StockTrace Applet
> | Written by Christian Dreke
> | http://www.cs.virginia.edu/~cd4v/graph/StockGraph.html
> Figure 4.8. The StockTrace Applet demonstrates server communication and updating information in real time. #### TeleRadiology Applet Java applets can update any kind of data in real time with the proper server connection. Another prototype applet designed to showcase this capability is the TeleRadiology applet. This applet was developed at the Los Alamos National Laboratory and is designed to show how medical information could be transmitted and viewed by using such real-time applications. This prototype was designed to show how medical information can be transmitted to various locations, allowing consultations and diagnostics to be performed anywhere in the world. Such technology could help increase the quality of medicine in rural areas or help doctors verify opinions with colleagues around the globe.
> | Java TeleMed Prototype
> | Written by Andrew White
> | http://www.acl.lanl.gov/~rdaniel/classesJDK/PickTest2.html
> Figure 4.9. The TeleRadiology applet demonstrates how Java can communicate vital information in useful formats. #### Interactive PC Scoreboard Applet Communication with a server is not limited to updating real-time information. Java applets can be written to perform typical client/server tasks, such as functioning as database front ends. The Interactive PC Scoreboard is an example of how applets can communicate back to a database, use the database to look up information, and then redisplay the information in a useful format. This particular applet allows users to enter information about what qualities they are looking for in a personal computer. The applet then searches a database and, based on the criteria the user has selected, displays some recommended machines. Users can then click the recommended models to get configuration and pricing information.
> | c|net Interactive PC Scoreboard
> | http://www.cnet.com/Content/Reviews/Compare/Pc100/0,30,,0200.html
> Figure 4.10. The c|net PC Scoreboard shows how Java can integrate with databases and other information sources. #### The Player Piano Applet The lack of seamless sound has plagued the Web for many years. Downloading sounds has always been possible, but the capability to load sounds directly with a page has eluded the Web. The latest versions of Netscape and third-party applications such as Real Audio have begun to add the dimension of sound to the Web, but they still fall short of full Web integration. Java brings integrated sound to the Web. An applet can play a sound when the applet is launched, or the applet can be configured to play sounds at the click of a button. An outstanding example of an applet that utilizes sound is the Player Piano applet. This applet actually simulates a player piano, displaying the roll that is used to create the sounds within the applet. Sound can enhance Web pages by adding personality and, as this applet shows, functionality.
> | Player Piano
> | Written by Mark Leather
> | http://reality.sgi.com/employees/mark/piano/index.html
> Figure 4.11. This applet actually functions like a old-fashioned player piano, integrating visuals and sound. ### Summary Don't be disappointed if the first applet you create doesn't allow users to select a region of the country and display real-time satellite weather photos. The applets in this chapter have been presented to show you the range of what is possible with Java, not to imply that these are beginning applets. Each of the applets shown in this chapter utilize the basic idea of adding exciting new elements to a Web page. Some of them do so by adding animations, and others add animation and sound. They range from the functional (A Clock, the TeleRadiology applet) to educational (The Juggling Applet, the PC Scoreboard) to fun (ClickBoard, the Player Piano). As you become more involved with Java, you might want to start adding some of the advanced features shown in this chapter, but every programmer still needs to start with the basics. Now that you have a handle on what Java is and what it can do, the next chapters move on to cover how you can start adding Java to your own Web pages. Chapter 5 examines the issues raised in adding Java applets to your Web pages and shows you an example of how to add an applet to your page. Chapter 7 helps you to create your first applet, HelloWorld. From there, you'll move onto some more advanced programming topics, which give you the basic foundation you need to start creating your own applets. Contact reference@developer.com with questions or comments. Copyright 1998 EarthWeb Inc., All rights reserved. PLEASE READ THE ACCEPTABLE USAGE STATEMENT. Copyright 1998 Macmillan Computer Publishing. All rights reserved.