<! -- Startfragment --> ************************************ **************************************** **
// Lake. Java: Applet
//
// (C) David Griffin iths, 1997
// This Source Code may not be reproduced without the express permission of
// Author.
//************************************** ****************************************
Import java. Applet .*;
Import java.net. url;
Import java.net. malformedurlexception;
Import java. AWT .*;
// ================================================ ==========================================================
// Main class for applet Lake
//
// ================================================ ==========================================================
Public class Lake extends applet implements runnable
{
// Thread support:
// M_lakeis the thread object for the Applet
//--------------------------------------------------------------------------
Thread m_lake = NULL;
// Animation support:
// M_graphicsused for storing the applet's graphics context
// M_wavegraphicsused for storing the animation's graphics context
// M_image the original image
// M_waveimage the image containing the wave animations
// M_ncurrimagethe index of the next image to be displayed
// M_imgwidthwidth of each image
// M_imgheightheight of each image
// M_ovlwidthwidth of each overlay
// M_ovlheightheight of each overlay
// M_fallloadedindicates whether all images have been loaded
// M_tanimateindicates that OK to do animation (changed by mouse
// Click)
// Num_frames Number of num_frames used in the animation
//--------------------------------------------------------------------------
Private graphics m_graphics, m_wavegraphics;
Private image m_image, m_overlay, m_waveimage;
Private int m_ncurrimage;
Private int m_nimgwidth = 0;
Private int m_nimgheight = 0;
Private int m_novlwidth = 0;
Private int m_novlheight = 0;
Private Boolean m_fallloaded = false, m_tanimate = true;
Private Final int num_frames = 12;
// Parameter support:
// Parameters allow an HTML author to pass information to the applet;
// The HTML author specifies them using the <param> tag within the <APPLET>
// Tag. the following variables are used to store the values of
// Parameters.
//--------------------------------------------------------------------------
// Members for applet Parameters
// <Type> <membervar >=< default value>
//--------------------------------------------------------------------------
Private string m_imagename = "";
Private string m_overlayname = "";
Private URL m_href;
Private string m_frame = "_ Self ";
// Parameter names. To change a name of a parameter, you need only make
// A single change. simply modify the value of the parameter string below.
//--------------------------------------------------------------------------
Private final string param_image = "image ";
Private final string param_overlay = "overlay ";
Private final string param_href = "href ";
Private final string param_target = "target ";
// Lake class Constructor
//--------------------------------------------------------------------------
Public Lake ()
{
// Todo: Add constructor code here
}
// Applet info support:
// The getappletinfo () method returns a string describing the applet's
// Author, copyright date, or miscellaneous information.
//--------------------------------------------------------------------------
Public String getappletinfo ()
{
Return "Name: Lake V3.0/R/N" +
"Author: David Griffin iths/R/N" +
"Created with Microsoft Visual J ++ version 1.0 ";
}
// Parameter support
// The getparameterinfo () method returns an array of strings describing
// The parameters understood by this applet.
//
// Lake parameter information:
// {"Name", "type", "Description "},
//--------------------------------------------------------------------------
Public String [] [] getparameterinfo ()
{
String [] [] info =
{
{Param_image, "string", "jpg or GIF file to reflect "},
{Param_overlay, "string", "jpg or GIF file to use as overlay "},
{Param_href, "url", "URL to link "},
{Param_target, "string", "target frame "},
};
Return Info;
}
// The init () method is called by the AWT when an applet is first loaded or
// Reloaded. Override this method to perform whatever initialization your
// Applet needs, such as initializing data structures, loading images or
// Fonts, creating frame windows, setting the layout manager, or adding UI
// Components.
//--------------------------------------------------------------------------
Public void Init ()
{
// Parameter support
// The following code retrieves the value of each parameter
// Specified with the <param> tag and stores it in a member
// Variable.
//----------------------------------------------------------------------
String Param;
// Image: JPG of GIF file to reflect
//----------------------------------------------------------------------
Param = getparameter (param_image );
If (Param! = NULL)
M_imagename = Param;
// Overlay: JPG of GIF file to use as overlay
//----------------------------------------------------------------------
Param = getparameter (param_overlay );
If (Param! = NULL)
M_overlayname = Param;
// Href: URL to link
//----------------------------------------------------------------------
Param = getparameter (param_href );
If (Param! = NULL)
Try
{
M_href = new URL (getdocumentbase (), Param );
}
Catch (malformedurlexception E)
{
Getappletcontext (). showstatus ("Bad URL:" + PARAM );
Return;
}
// Target: Target Frame
//----------------------------------------------------------------------
Param = getparameter (param_target );
If (Param! = NULL)
M_frame = Param;
}
// Place additional applet clean up code here. Destroy () is called when
// When you applet is terminating and being unloaded.
//-------------------------------------------------------------------------
Public void destroy ()
{
// Todo: Place applet cleanup code here
}
// Animation support:
// Draws the next image, if all images are currently loaded
//--------------------------------------------------------------------------
Private void displayimage (Graphics g)
{
If (! M_fallloaded)
Return;
// Draw frame of rippled lower half
//----------------------------------------------------------------------
If (m_waveimage! = NULL ){
G. drawimage (m_waveimage, (-m_ncurrimage * m_nimgwidth), m_nimgheight, this );
G. drawimage (m_waveimage, (NUM_FRAMES-m_nCurrImage) * m_nimgwidth ),
M_nimgheight, this );
}
// Draw the original in the tophalf.
//----------------------------------------------------------------------
G. drawimage (m_image, 0,-1, this );
}
// Lake paint Handler
//--------------------------------------------------------------------------
Public void paint (Graphics g)
{
// Animation support:
// The following code displays a status message until all
// Images are loaded. Then it CILS displayimage to display the current
// Image.
//----------------------------------------------------------------------
If (m_fallloaded)
Displayimage (g );
Else
G. drawstring ("loading images...", 10, 20 );
// Todo: place additional applet paint code here
}
// The start () method is called when the page containing the Applet
// First appears on the screen. The appletwizard's initial implementation
// Of this method starts execution of the applet's thread.
//--------------------------------------------------------------------------
Public void start ()
{
If (m_lake = NULL)
{
M_lake = new thread (this );
M_lake.start ();
}
}
// The stop () method is called when the page containing the applet is
// No longer on the screen. The appletwizard's initial implementation
// This method stops execution of the applet's thread.
//--------------------------------------------------------------------------
Public void stop ()
{
If (m_lake! = NULL)
{
M_lake.stop ();
M_lake = NULL;
}
}
// Thread support
// The run () method is called when the applet's thread is started. If
// Your applet performs any ongoing activities without waiting for user
// Input, the code for implementing that behavior typically goes here.
// Example, for an applet that performs animation, the run () method controls
// The display of images.
//--------------------------------------------------------------------------
Public void run ()
{
M_ncurrimage = 0;
// If re-entering the page, then the images have already been loaded.
// M_fallloaded = true.
//----------------------------------------------------------------------
If (! M_fallloaded)
{
Repaint ();
M_graphics = getgraphics ();
// Now load up the image to be used in the animation. Rather than do
// This asynchronously with imageupdate (which is a pain in the bum
// Use) We'll do it synchronously with a mediatracker. This hangs
// Around until the image is loaded. Using the waitforall method, just
// In case we ever add other images to the applet.
//------------------------------------------------------------------
Mediatracker tracker = new mediatracker (this );
String strimage;
M_image = getimage (getdocumentbase (), m_imagename );
If (! "". Equals (m_overlayname ))
M_overlay = getimage (getdocumentbase (), m_overlayname );
Tracker. addimage (m_image, 0 );
If (! "". Equals (m_overlayname ))
Tracker. addimage (m_overlay, 1 );
// Wait until all images are fully loaded
//------------------------------------------------------------------
Try
{
Tracker. waitforall ();
M_fallloaded =! Tracker. iserrorany ();
}
Catch (interruptedexception e ){}
If (! M_fallloaded)
{
Stop ();
M_graphics.drawstring ("error loading images! ", 10, 40 );
Return;
}
// Can now set width and height straight away because
// Mediatracker object has ensured this information is now available.
//--------------------------------------------------------------
M_nimgwidth = m_image.getwidth (this );
M_nimgheight = m_image.getheight (this );
If (! "". Equals (m_overlayname )){
M_novlwidth = m_overlay.getwidth (this );
M_novlheight = m_overlay.getheight (this );
}
// Now create the animation of the rippling waves.
//--------------------------------------------------------------
Createanimation ();
}
Repaint ();
While (true)
{
Try
// Draw next image in animation
//--------------------------------------------------------------
If (m_tanimate)
{
Displayimage (m_graphics );
If (++ m_ncurrimage = num_frames)
M_ncurrimage = 0;
Thread. Sleep (50 );
}
Else
Thread. Sleep (500 );
Catch (interruptedexception E)
Stop ();
}
}
// Mouse support:
// Clicking on the applet starts/stops it.
// Doesn't call 'Stop () 'directly because otherwise an interruptedexception
// Is thrown...
//--------------------------------------------------------------------------
Public Boolean mouseup (event, int I, Int J)
{
Boolean flag = super. mouseup (event, I, j );
If (m_href = NULL)
M_tanimate =! M_tanimate; // toggle m_tanimate to start/stop animation.
Else
{
Showstatus ("" + m_href );
Getappletcontext (). showdocument (m_href, m_frame );
}
Return true;
}
// Animation
// Create the animation within a single background image. We use a single
// Image rather than the default multiple images because it's quicker.
//---------------------------------------------------------------------------
Public void createanimation ()
{
// Create inverted image of original loaded image.
// We create a background image (backimg) 1 pixel higher
// Than the original because we'll need an extra line
// Pixels to play with when we flip the image upside down.
//--------------------------------------------------------
Image backimg = createimage (m_nimgwidth, m_nimgheight + 1 );
Graphics backg = backimg. getgraphics ();
// Copy the original image (m_image) onto the background
// Version.
//--------------------------------------------------------
Backg. drawimage (m_image, 0, 1, this );
// Now flip the image upside down.
//--------------------------------------------------------
For (INT I = 0; I <(m_nimgheight> 1); I ++)
{
Backg. copyarea (0, I, m_nimgwidth, 1, 0, m_nimgheight-I );
Backg. copyarea (0, m_nimgheight-1-I, m_nimgwidth, 1,
0,-m_nimgheight + 1 + (I <1 ));
Backg. copyarea (0, m_nimgheight, m_nimgwidth, 1, 0,-1-I );
}
// Now create the large (num_frames + 1 times the width) Image
// That will store dithered copies of the inverted original.
//--------------------------------------------------------
M_waveimage = createimage (num_frames + 1) * m_nimgwidth, m_nimgheight );
M_wavegraphics = m_waveimage.getgraphics ();
M_wavegraphics.drawimage (backimg, num_frames * m_nimgwidth, 0, this );
// Now create dithered copies (sine displacement up or down) of
// Inverted original.
//--------------------------------------------------------
For (INT phase = 0; Phase <num_frames; Phase ++)
Makewaves (m_wavegraphics, phase );
// Now, if there is an overlay image, draw the top half of it
// Over the frame. (the bottom half of the overlay will be drawn over
// The rippled image)
//------------------------------------------------------------
Backg. drawimage (m_image, 0, 1, this );
If (! "". Equals (m_overlayname ))
Backg. drawimage (m_overlay,
(M_nimgwidth-m_novlwidth)> 1,
M_nimgheight-(m_novlheight> 1), this );
M_image = backimg;
}
// Animation
// Take the initial (unwaved) image from the left-hand-side of the graphics
// And make num_frames copies of it-the pixels rows of each one dithered
// Up or down depending upon the dispy sine function.
//---------------------------------------------------------------------------
Public void makewaves (Graphics g, int phase)
{
Double P1;
Int dispx, dispy;
// Convert the phase into radians (by splitting 2 * PI
// Num_frames segments ).
//--------------------------------------------------------
P1 = 2 * Math. Pi * (double) phase/(double) num_frames;
// Dispx defines how far implements ss the image has to be copied
// From the original LHS frame.
//--------------------------------------------------------
Dispx = (num_frames-phase) * m_nimgwidth;
// Now process each horizontal line of pixels. Copy upload SS
// From original frame on the left-had-side and displacing
// Up or down WRT the dispy sine function.
//--------------------------------------------------------
For (INT I = 0; I <m_nimgheight; I ++)
{
// Dispy defines the vertical sine displacement. It
// Attenuates higher up the image, for perspective.
//--------------------------------------------------------
Dispy = (INT) (m_nimgheight/14) * (double) I + 28.0)
* Math. Sin (double) (m_nimgheight/14) * (m_nimgheight-I ))
/(Double) (I + 1)
+ P1)
/(Double) m_nimgheight );
// If no line dithers here then copy Original.
//--------------------------------------------------------
If (I <-dispy)
G. copyarea (num_frames * m_nimgwidth, I, m_nimgwidth, 1,
-Dispx, 0 );
Else
// Else copy dithered line.
//--------------------------------------------------------
G. copyarea (num_frames * m_nimgwidth, I + dispy,
M_nimgwidth, 1,-dispx,-dispy );
}
// Now, if there is an overlay image, draw the bottom half of it
// Over the frame. (the top half of the overlay will be drawn over
// The original image)
//------------------------------------------------------------
If (! "". Equals (m_overlayname ))
G. drawimage (m_overlay,
(Phase * m_nimgwidth) + (m_nimgwidth-m_novlwidth)> 1 ),
-M_novlheight> 1, this );
}
}