Sunncity.com - Developer & I.T. Zone

 
Sunncity Web

Technology Menu

Developer Center
Delphi Online Tutorial
JAVA Online Tutorial
The Code Project
XML Code Library
FREE Download
Our Free Components
Our Free Software
Free Components
Delphi & Kylix Training
SMTC Training Course
About Delphi EXAM

Search Component


Search Software(s)


by oneNetwork

 

Java Online Tutorial - Animation Techniques

MORE ABOUT APPLETS

Generally applets are much more powerful than applications because they can be run within a web browser. They can be harder to write as they work in context of the web page they are in. As we mentioned earlier, to create an applet one has to create a subclass of the java.applet.Applet class. Applets also take strong advantage of Java's Abstract Windowing Toolkit (awt), which provides behavior for creating graphical user interface (GUI)-based applets and applications: drawing to the screen; creating windows, menu bars, buttons, check boxes, and other UI elements; and managing user input such as mouse clicks and keypresses. The awt classes are part of the java.awt package. We shall take a look at some of these applet capabilities in this section.

 

 


The applet tag

As you probably know by now that applets are invoked by a java-enabled browser or an appletviewer by the use of a special tag known as the <APPLET attributes></APPLET> tag. This tag is embedded into a html page. Look at the example below as we shall attempt to explain each of its components in detail.

    <HTML>
    <HEAD>
    <TITLE>The applet tag !</TITLE>
    </HEAD><BODY>
    <P>A sample html file which includes an applet:
    <APPLET CODE="SampleApplet.class" 
    WIDTH=150 HEIGHT=25 >
    <PARAM NAME = FONT VALUE = "TimesRoman" >
    < PARAM NAME = STYLE VALUE = "Italic" >
    < PARAM NAME = SIZE VALUE = "30" > 
    </APPLET>
    </BODY>
    </HTML>

The <APPLET> tag supports 11 attributes: ALIGN, ALT, ARCHIVE, CODE, CODEBASE, HEIGHT, HSPACE, VSPACE, NAME, OBJECT and WIDTH. Of these 11 applet attibutes only the CODE, WIDTH and HEIGHT are required.

  • The ALIGN attribute specifies the alignment of an applet's display area with respect to the html page it resides in. Values for this attibute are TOP, TEXTTOP, BOTTOM, ABSBOTTOM, BASELINE, MIDDLE, ABSMIDDLE, LEFT and RIGHT.
  • The ALT attribute identifies text that should be displayed by a browser if it understands the <applet > tags, but does not support java applets or has applet processing disabled.
  • The ARCHIVE tag identifies the class archives that enable the browser to pre-load an applet. Using the archive tag significantly improves applet start-up time. Typically this points to a jar or zip file in the applet's codebase.
  • The CODE attribute is a relative URL that identifies the name of the bytecode file of the applet's main class.
  • The CODEBASE attribute specifies the directory that will be searched to locate the applet's bytecode class file. By default it is the URL of the html page the applet resides in.
  • The HEIGHT and WIDTH attributes specifies in pixels the height and width of the bounding box of the applets display area.
  • The HSPACE and VSPACE attributes specifies the number of pixels to be used as the left and right and top and bottom margins surrounding an applet.
  • The NAME attribute is used to assign a name to an applet. This name is used to support inter-applet communication.
  • The OBJECT attribute identifies a file that contains a serialized representation of an applet.

Back to TOP


Applet life cycle

Applets do not need to be explicitly constructed. They are automatically constructed by 
the runtime environment associated with their applet context - the web browser or appletviewer.

An applet's life cycle begins when a browser visits the web page the applet resides in. 
The first part of this process is called class loading. Once this is done, the browser creates an instance of the applet class. In the next step of the life cycle, the browser sends several 
start up method calls to the applet.

  • init()
    The first call the browser makes to the applet is init(). This method provides the capability to load applet parameters and perform any necessary initialization processing such as:
    • Creating the applet's GUI.
    • Reading values from <PARAM> tags.
    • Loading off-screen images from external files.
    • Loading audio clips from external files.
  • start() and stop()
    The start() method serves as the execution entry point for an applet when it is initially executed and restarted as the result of a user returning to the web page that contains the applet.
    The stop() method provides the capability to stop and applet's execution when the web page theat contains the applet is no longer active.
    There are three activities an applet should suspend in the stop() method and resume in the start() method:
    • Animation - There is no benefit in wasting cycles on an animation that no one is looking at.
    • Sound - It would confuse the user to play sound for a different page than 
      the one being viewed. Iconified programs of any kind should not play sounds.
    • General background thread processing - The thread would be doing work 
      for a page other than the one being viewed. This would steal 
      resources that should be available to the current page.
  • paint(Graphics g)
    This method is called both at start-up time and subsequently at the browser's discretion. After the initial call, the browser calls paint() whenever it needs the applet to render itself.
  • destroy()
    The browser calls destroy() when it no longer needs the applet. The destroy() method 
    is the applet's opportunity to release any non-memory resources it might have, such as 
    threads and network connections.
    In fact, the call only happens when the applet's page is reloaded or when the browser 
    itself terminates. Because the browser caches the applet even when the applet's page 
    is no longer displayed, destroy() is rarely called.

Back to TOP


What applets can do and cannot do

Here are some of the things browsers let applets do:

  • Applets can usually make network connections to the host they came from.
  • Applets running within a web browser can easily cause HTML documents to be displayed.
  • Applets can invoke public methods of other applets on the same page.
  • Applets that are loaded from the local file system (from a directory in the user's CLASSPATH) have none of the restrictions that applets loaded over the network do.
  • Although most applets stop running once you leave the page they're on, they don't have to.

Browsers impose the following restrictions on any applet loaded over the network:

  • An applet cannot load libraries or define native methods.
  • It cannot ordinarily read or write files on the host that's executing it.
  • It cannot make network connectiopns except to the host it came from.
  • It cannot start any program on the host that's executing it.
  • It cannot read certain system properties.
  • Windows that an applet brings up to look different than windows that an
    application brings up.

Back to TOP


An Animation Applet

Displaying animation is probably the most popular use of java applets on the web. We can use HTML to display static images, but we need java to make them come alive.

There are three general steps that should usually be followed when creating animation applets.

  • Load the images.
  • Start a thread.
  • Run the animation.

While the first part is accomplished in the applet's init() method, the other two are accomplished in start() and paint().

Take a good look at the source code below and also see the example running on this page. Then we will discuss an advanced technique for improving animation called double buffering.


import java.awt.*;
import java.applet.*;

/** Sample html file provided to run this example. 
<applet code=Animation codebase="."  height=68 width=55>
</applet>
*/

public class Animation extends Applet implements Runnable {

   Image img[] = new Image[10];
   Image current;
   int picture[] = {0,1,2,3,4,5,6,7,8,9};
   Thread thread;


   public void init() {
      for (int i=0;i<img.length;i++){
      img[i]=getImage(getCodeBase(), "./images/" + "T"+ (i+1) +".gif");
     }
      }

        public void start(){
                if(thread==null)
                thread=new Thread(this);
                thread.start();
        }

        public void stop() {
                if(thread!=null)
                thread=null;
                thread.stop();
        }

        public void run(){
                while(true) {
                for(int i=0;i<picture.length;i++) {
                current=img[i];
                repaint();
                        try {
                                thread.sleep(200);
                        }
                        catch(Exception e) {
                                e.printStackTrace();
                        }
                }
              }
        }
        public void paint(Graphics g) {
                if(current!=null)
                g.drawImage(current, 0, 0, this);
                showStatus("Inside paint");

        }

}

To see a sample of the above applet in action go here.

Back to TOP


Reducing animation flicker: Double Buffering

In the above example you might have noticed that parts of the animation seem to dissapear as the frames are drawn onto the screen which gives rise to something called flicker. This flicker is due
to the fact that the entire screen is repainted with each new frame. For advanced animation, the 
best solution for fighting flicker is a technique called double buffering.b

With double-buffering, you create a second surface (offscreen, so to speak), do all your painting to that offscreen surface, and then draw the whole surface at once onto the actual applet (and onto 
the screen) at the end-rather than drawing to the applet's actual graphics surface. Because all the work actually goes on behind the scenes, there's no opportunity for interim parts of the drawing process to appear accidentally and disrupt the smoothness of the animation.

Double-bufferingis the process of doing all your drawing to an offscreen buffer and then displaying that entire screen at once. It's called double-buffering because there are two drawing buffers and you switch between them.

Creating Applets with Double-Buffering

To create an applet that uses double-buffering, you need two things: an offscreen image to draw on and a graphics context for that image. Those two together mimic the effect of the applet's drawing surface: the graphics context (an instance of Graphics) to provide the drawing methods, such as drawImage (and drawString), and the Image to hold the dots that get drawn.

There are four major steps to adding double-buffering to your applet. First, your offscreen image 
and graphics context need to be stored in instance variables so that you can pass them to the paint() method. Declare the following instance variables in your class definition:

        Image offscreenImage;
        Graphics offscreenGraphics; 

Second, during the initialization of the applet, you'll create an Image and a Graphics object and assign them to these variables (you have to wait until initialization so you know how big they're going to be). The createImage() method gives you an instance of Image, which you can then send the getGraphics() method in order to get a new graphics context for that image:

        offscreenImage = createImage(size().width, size().height);
        offscreenGraphics = offscreenImage.getGraphics();

Now, whenever you have to draw to the screen (usually in your paint() method), rather than drawing to paint's graphics, draw to the offscreen graphics. For example, to draw an image called img at position 10,10, use this line:

     offscreenGraphics.drawImage(img, 10, 10, this);

Finally, at the end of your paint method, after all the drawing to the offscreen image is done, add the following line to place the offscreen buffer on to the real screen:

     g.drawImage(offscreenImage, 0, 0, this);

Of course, you most likely will want to override update() so that it doesn't clear the screen between paintings:

     public 
         void paint(Graphics g) {            
         update(g);
         }
 

Let's review those four steps:

  1. Add instance variables to hold the image and graphics contexts for the offscreen buffer.
  2. Create an image and a graphics context when your applet is initialized.
  3. Do all your applet painting to the offscreen buffer, not the applet's drawing surface.
  4. At the end of your paint() method, draw the offscreen buffer to the real screen.

Back to TOP


The Animation Applet: Revisited

Here is the animation applet which now supports double buffering and eliminates flicker. The html file is included within comments in the source code. Save it separately within a html file.

import java.awt.*;
import java.applet.*;

/**
<applet code="DoubleBufferedAnim.class" codebase="." width=55 height=68>
<param name=delay value="200">
</applet>
*/

public class DoubleBufferedAnim extends Applet implements Runnable {

        Image img [] = new Image[10];
        Image current, doubleg;
        int picture[] = {0,1,2,3,4,5,6,7,8,9};
        Thread thread;
        Graphics gg;
        int delay=200;



     public void init() {
     for(int i=0; i<img.length;i++){
     img[i]=getImage(getCodeBase(),"./images/"+"T"+(i+1)+".gif");
        }

        delay=Integer.parseInt(getParameter("delay"));
        }

        public void start() {
                if (thread==null)
                thread= new Thread(this);
                thread.start();
        }

        public void stop() {
                if(thread != null)
                thread.stop();
                thread=null;
        }

        public void run() {
                while (true) {
                for (int i=0;i<picture.length;i++) {
                current=img[i];
                repaint();
                        try {
                                thread.sleep(delay);
                        }
                        catch (Exception e) {
                                e.printStackTrace();
                        }
                }

                }

        }

        public void paint(Graphics g) {
                update(g);
        }

        public void update(Graphics g) {
                if (current != null) {
                doubleg = createImage(100, 100);
                gg = doubleg.getGraphics();
                gg.drawImage(current, 0,0, null);
                g.drawImage(doubleg, 0, 0, this);
                showStatus("Inside paint");
                }

        }

}

To see a sample of the improved applet in action go here.

A Note on Disposing Graphics Contexts

pIf you make pextensive use of graphics contexts in your applets or applications, be aware that those contexts will often continue to stay around after you're done with them, even if you no longer have any references to them. Graphics contexts are special objects in the awt that map to the native operating system; Java's garbage collector cannot release those contexts by itself. If you use multiple graphics contexts or use them repeatedly, you'll want to explicitly get rid of those contexts once you're done with them.

Use the dispose() method to explicitly clean up a graphics context. A good place to put this might be in the applet's destroy() method.

      public void 
            destroy() {
            offscreenGraphics.dispose();
        }
                        

Download a zipped copy of all the source code, class files and html for this chapter here.

Back to TOP

Now on to the next chapter The Java Awt or Graphic User Interfaces


All questions and comments can be addressed to the author.
All material appearing within this website is copyright protected and may not be reproduced elsewhere without the express written permission of the author (Sanjeev Dasgupta)

 


Support this site BUY from Sunncity Gift Store