problem with water.java

I’ve been trying to make this applet run, but it wont! The site didnt come with a image, just the source code:


/*
 * Name:     Water
 * Date:     December 2004
 * Author:   Neil Wallis
 * Purpose:  Simulate ripples on water.
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.applet.Applet;
import java.net.URL;

public class water extends Applet implements
  Runnable, MouseListener, MouseMotionListener {

    String str;
    int width,height,hwidth,hheight;
    MemoryImageSource source;
    Image image, offImage;
    Graphics offGraphics;
    int i,a,b;
    int MouseX,MouseY;
    int fps,delay,size;

    short ripplemap[];
    int texture[];
    int ripple[];
    int oldind,newind,mapind;
    int riprad;
    Image im;

    Thread animatorThread;
    boolean frozen = false;

    public void init() {
      addMouseListener(this);
      addMouseMotionListener(this);

      //Retrieve the base image
      str = getParameter("image");
      if (str != null) {
        try {
          MediaTracker mt = new MediaTracker(this);
          im = getImage(getDocumentBase(),str);
          mt.addImage(im,0);
          try {
            mt.waitForID(0);
            } catch (InterruptedException e) {
              return;
            }
        } catch(Exception e) {}
      }

      //How many milliseconds between frames?
      str = getParameter("fps");
      try {
        if (str != null) {
          fps = (int)Integer.parseInt(str);
        }
      } catch (Exception e) {}
      delay = (fps > 0) ? (1000 / fps) : 100;

      width = im.getWidth(this);
      height = im.getHeight(this);
      hwidth = width>>1;
      hheight = height>>1;
      riprad=3;

      size = width * (height+2) * 2;
      ripplemap = new short[size];
      ripple = new int[width*height];
      texture = new int[width*height];
      oldind = width;
      newind = width * (height+3);

      PixelGrabber pg = new PixelGrabber(im,0,0,width,height,texture,0,width);
      try {
        pg.grabPixels();
        } catch (InterruptedException e) {}


      source = new MemoryImageSource(width, height, ripple, 0, width);
      source.setAnimated(true);
      source.setFullBufferUpdates(true);

      image = createImage(source);
      offImage = createImage(width, height);
      offGraphics = offImage.getGraphics();
    }

    public void start() {
        if (frozen) {
            //Do nothing.
        } else {
            //Start animation thread
            if (animatorThread == null) {
                animatorThread = new Thread(this);
            }
            animatorThread.start();
        }
    }

    public void stop() {
      animatorThread = null;
    }

    public void destroy() {
      removeMouseListener(this);
      removeMouseMotionListener(this);
    }

    public void mouseEntered(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}

    public void mousePressed(MouseEvent e) {
      if (frozen) {
        frozen = false;
        start();
      } else {
        frozen = true;
        animatorThread = null;
      }
    }

    public void mouseMoved(MouseEvent e) {
	disturb(e.getX(),e.getY());
    }

    public void run() {
      Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
      long startTime = System.currentTimeMillis();

      while (Thread.currentThread() == animatorThread) {
        newframe();
        source.newPixels();
        offGraphics.drawImage(image,0,0,width,height,null);
        repaint();

        try {
            startTime += delay;
            Thread.sleep(Math.max(0,startTime-System.currentTimeMillis()));
        } catch (InterruptedException e) {
            break;
        }
      }
    }

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

    public void update(Graphics g) {
      g.drawImage(offImage,0,0,this);
    }

    public void disturb(int dx, int dy) {
      for (int j=dy-riprad;j<dy+riprad;j++) {
        for (int k=dx-riprad;k<dx+riprad;k++) {
          if (j>=0 && j<height && k>=0 && k<width) {
	    ripplemap[oldind+(j*width)+k] += 512;            
          } 
        }
      }
    }

    public void newframe() {
      //Toggle maps each frame
      i=oldind;
      oldind=newind;
      newind=i;

      i=0;
      mapind=oldind;
      for (int y=0;y<height;y++) {
        for (int x=0;x<width;x++) {
	  short data = (short)((ripplemap[mapind-width]+ripplemap[mapind+width]+ripplemap[mapind-1]+ripplemap[mapind+1])>>1);
          data -= ripplemap[newind+i];
          data -= data >> 5;
          ripplemap[newind+i]=data;

	  //where data=0 then still, where data>0 then wave
	  data = (short)(1024-data);

          //offsets
  	  a=((x-hwidth)*data/1024)+hwidth;
          b=((y-hheight)*data/1024)+hheight;

 	  //bounds check
          if (a>=width) a=width-1;
          if (a<0) a=0;
          if (b>=height) b=height-1;
          if (b<0) b=0;

          ripple[i]=texture[a+(b*width)];
          mapind++;
	  i++;
        }
      }
    }

}


This is of course not my code, yet i get these errors in Eclipse:

[quote]java.lang.NullPointerException
at water.init(water.java:64)
at sun.applet.AppletPanel.run(AppletPanel.java:417)
at java.lang.Thread.run(Thread.java:619)
[/quote]
I added in a substitute image that is a .png and it is 100x100, but it still doesnt work:

I got the code from this site, but im trying to make it work so i can implement it one day:
http://www.neilwallis.com/java/water.html

Compiler tells you that you get null pointer exception at line 64 (you can click on it in eclipse and it will take you to that line), and if I counted right that is:


width = im.getWidth(this);

so “im” is null and you can’t call a method on null obviusly. Above in the code im is read as some kind of a parametar (don’t know what getParameter() does), maybe you passed wrong image name?

i have no clue how this guy is reading the image directories, i see it no where, also i have never seen this in java before:

hwidth = width>>1;

it looks like a c++ thingy. but that is not the problem anyway.

It does a “fast” integer division by two using a bit shift. Although you might find it’s not actually any faster on any cpu thats not made out of wood.

See the Applet.getImage() apidoc. It’s a method to retrieve an image from an url (e.g. the webserver). In the posted code, it looks for an image specified in the applet-parameter “image” beneath the location of the html page that contains the applet.