Link to home
Start Free TrialLog in
Avatar of luinzi
luinzi

asked on

How do my methods know what graphic g is????

Please check out this piece of code:

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

public class anim1 extends Applet  implements Runnable
{

   Image buffer;
   Graphics bufferGraphics;
   boolean shouldRun = true;

   Image imagelist[];
   int pic_counter =0; //start at 0



   public void init()
    {

        Dimension size = getSize();
        buffer = createImage(size.width, size.height);
        bufferGraphics = buffer.getGraphics();
        bufferGraphics.setColor(getBackground());

        imagelist = new Image [15];


     for (int i = 0; i < 15; i++)
      {
         imagelist[i] = getImage(getCodeBase(), "q"+ i +".jpg");
      }    
     }

public void start()
{
   shouldRun = true;
   Thread runner = new Thread(this);
   runner.start();
}


public void stop()
{
   shouldRun = false;
}



public void run()
{

   while (shouldRun)
   {

         repaint();
         try
         {Thread.sleep(200);} // I think this is right - sleep for 1 second [1000 milliseconds]
         catch(InterruptedException e){}

   }
 }

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

   Rectangle clipBounds = g.getClipBounds();

   bufferGraphics.setClip(g.getClip());

   bufferGraphics.fillRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);

   bufferGraphics.drawImage(imagelist[pic_counter], 50, 100, this);

   // flip buffer to screen
   g.drawImage(buffer, 0, 0, this);

   pic_counter++;
   if(pic_counter >= 15)
  do
    {
     pic_counter--;
    }
   while(pic_counter > 1);
 
 }


}

I got an expert to help me with it. It uses double buffering to display a series of pictures. Whilst reading through it to understand what was going on, i couldn't work out how the paint, and update methods, who were passed an argument called g, of type Graphics, knew what g is. Could someone please annotate my code telling me how the applet knows what g is refering to. Could you also please explain the paint method as well. Thanks
Avatar of saivon
saivon

I think you should ask Pitman. :)
ASKER CERTIFIED SOLUTION
Avatar of Jod
Jod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
some more info,

update() & paint() r methods defined under Component class. Whenever there is a change in the display..for ex: the first time the component is placed on teh screen, or its moved , or resized, or its contents r altered it needs to update its display. so the update() method is called, which goes about restoring everything, and as a part of that restoration calls paint( ).

When update( ) calls paint( ) it hands it a handle to a Graphics object that represents the surface on which you can paint. This
is important because you’re limited to the surface of that particular component and thus cannot paint outside that area, which is a good thing or else you’d be painting outside the lines.

All the components r allocated a rectangular solid area("Heavy weight components") with teh help of the native peers. Hence all the painting should be done within the allocated area.

Double buffering:

Instead of drwaing on teh screen & causing flicker during every move the entire image(or rather the entire painting) is done on a buffer & this buffer is copied(not redrawn) on to the specified area.

In ur program even if u do not have the update method the result wud be the same 'cos update() wil be inherently called.

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

public class anim1 extends Applet  implements Runnable{

            Image buffer;
            Graphics bufferGraphics;
            boolean shouldRun = true;
            Image imagelist[];
            int pic_counter =0; //start at 0
            
            public void init(){
            
                //Create a Image buffer eqivalent to the size of the applet
                        Dimension size = getSize();
                buffer = createImage(size.width, size.height);
                bufferGraphics = buffer.getGraphics();
                bufferGraphics.setColor(getBackground());
            
                imagelist = new Image [15];
            
                        //Load the images into the image array            
                         for (int i = 0; i < 15; i++){
                       imagelist[i] = getImage(getCodeBase(), "q"+ i +".jpg");
                          }    
            } //init
            
            public void start(){
                        shouldRun = true;
                        Thread runner = new Thread(this); //create an instance of the thread & start it
                        runner.start();
            }
            
            public void stop(){
                        shouldRun = false; //stop the animation
            }
            
                  
            public void run(){
            
                  while (shouldRun){
                       repaint(); //paint the image
                       try
                       {Thread.sleep(200);} // I think this is right - sleep for 1 second [1000 milliseconds]
                       catch(InterruptedException e){}
                  
                  }
       }
            
            public void update(Graphics g){
                        paint(g); //pass the graphics object of the applet to the paint method
            }
            
                                         
            public void paint(Graphics g){
                //get the boundary of the screen that has been altered
                        Rectangle clipBounds = g.getClipBounds();
                        //set the boundary of the buffer
                        bufferGraphics.setClip(g.getClip());
                        //fill the altered area with the background color in the buffer
                        bufferGraphics.fillRect(clipBounds.x, clipBounds.y,clipBounds.width, clipBounds.height);
                        //draw the image on the buffer
                        bufferGraphics.drawImage(imagelist[pic_counter], 50, 100, this);
                        //COPY the buffer to the applet screen
                        g.drawImage(buffer, 0, 0, this);
                        //move on to the next image
                        pic_counter++;
                        if(pic_counter >= 15)
                              do{
                                 pic_counter--;
                              }while(pic_counter > 1);
            } //paint
            

}

-sgoms

Avatar of luinzi

ASKER

Thanks very much once again.  One last question though. Is it the case that every graphics component you wish to paint in an applet will require its own paint and update methods, or does the single update and paint method cater for more than one component?
every component has its own update() & paint methods. As i said update & paint r methods in java.awt.Component class.

Its not necessary to override update or paint unless u wish to do some explicit painting operation on it.

If you have a applet with 2 panels & u wish to paint a rect on each panel, then u shud have 2 classes extending Panel & override the paint method inside that.

Hope ur clear.
-sgoms
The important hing to remember is that you are overriding update and paint.

By default they are already written for you, but because Java has no idea what you are going to do with the component there are two problems with this:

Firstly, the only thing Java knows to do in update is to clear the component and redraw it as it was origninally. So the default implementation (which your graphical component will inherit) looks like this:

public void update(Graphics g) {
  setColor(backgroundColor);
  fillRect(0,0,getSize().width, getSize().height);
  paint(g);
}

All it does is blank out the componenet and call paint.

By default, this is all you want a component to do - just redraw itself, but it is importatnt to override update in double buffering as you just don't need to do this. You are already redrawing the screen in your paint method and don't need to do it here as well.

So every graphics component is created for you with the ability to redraw itself - you then change the paint method to redraw it in ways other than this default way.

You could then extend your anim1 class above and it will then contain a paint method that does animation as you will inherit the changed paint method into your new class.

It's all taking advantage of the class heirarchy to provide you with these functions inherited from more general components higher up in the class heirarchy.

The best thing to do is to play with these methods to see what they are doing.

There is an excellent explanation of this in Exploring Java (as well as other books) which would be well worth getting if you are interested in really pursuing this. It has a good tutorial section that leads you through the in's and out's of designing an applet that does double buffered imaging.