/**
 * BufferingFrame
 * A Frame with software double-buffering
 * to eliminate flicker.
 *
 * Nina Amenta
 * September, 2001
 */
import java.awt.*;
import java.awt.geom.*;

public class BufferingFrame extends ApplicationFrame
{

    // Image to use for double-buffering
    private Image buffer;
    private Graphics ig;    // its Graphics
    private Graphics2D ig2; // its Graphics2d

    // Constructor
    public BufferingFrame(String title)
    {
        super(title);
    }


    // The update method of Frame erases the frame and then
    // calls paint(), causing hideous flicker in animation. 
    // Here, we override it, leaving out the erase, and call
    // our own double-buffering paint method.
    public void update(Graphics g) 
    {
        doubleBufferPaint(g); 
    } 



    // Double-buffering means erasing and drawing an
    // image in memory, then copying it to the window.
    // Since the erase happens off-screen, we don't see
    // the flicker.
    public void doubleBufferPaint(Graphics g) {
        if (g != null) 
        {
        Dimension d = getSize(); // method of Component;
                                 // gets size.
        if (checkImage(d)) // makes sure Frame and image
                           // are same size
            {

            // Clear the image background.
            ig2.setPaint(getBackground());
            // Component.getBacground gets background color
            // You tell me: what is the default background color?
            Rectangle2D background = 
                new Rectangle2D.Double(0,0,d.width,d.height);
            ig2.fill(background);
            ig2.setPaint(getForeground()); 
            // a subclass's paint method is entitled to expect 
            // the Paint to be the default foreground color.
            // Now call paint on the Graphics of the IMAGE. 
            paint(ig);
            // Now draw the image on to the screen Graphics
            g.drawImage(buffer, 0, 0, null);
            }
        g.dispose();
        }
    }

  // Make sure image used for double buffering exists,
  // and that it's dimensions match the dimensions of
  // the window.
  // The image gets CREATED here, when it finds the 
  // first time around that the image is null. 
  protected boolean checkImage(Dimension d) 
    {
    if (d.width == 0 || d.height == 0) return false;
    if (buffer == null || buffer.getWidth(null) != d.width
        || buffer.getHeight(null) != d.height) {
      buffer = createImage(d.width, d.height);
      // Component.createImage() exists mainly to make
      // to make images for double-buffering. 

      // Get a graphics object for drawing 
      // into the image.
      ig = buffer.getGraphics();
      ig2 = (Graphics2D) ig;
    }
    return true;
  }

}
