// Java 2D ImageDragger modified to 
// take advantage of auto DoubleBuffering
// in Swing Components.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;


public class ImageDragger extends JPanel 
{
  BufferedImage image = null;
  Image underlay = null;

  int oldX;
  int oldY;

  int currentX;
  int currentY;

  boolean oldValid = false;

  boolean isDragging = false;
  boolean isLast = false;

 
  public ImageDragger() 
  {
    addMouseListener(new MousePresser());
    addMouseMotionListener(new MouseDragger());
    addComponentListener(new Resizer());

  } // end constructor


  protected void paintComponent( Graphics g )
  {
     Graphics2D g2 = (Graphics2D)g;

     if( isDragging )
     {
       g2.setXORMode( Color.black );
       if (oldValid) 
       {
         g2.drawImage(image, oldX, oldY, this);
       }

       g2.drawImage(image, currentX, currentY, this);

       oldValid = true;
       oldX = currentX;
       oldY = currentY;
     }
     else if (isLast)
     {
       g2.setXORMode( Color.black );
       g2.drawImage(image, oldX, oldY, this);
       oldValid = false;
       isLast = false;
     }
     else
     {
       if (underlay == null) {
         Dimension dim = getSize();
         underlay = createImage(dim.width, dim.height);
         Graphics gc = underlay.getGraphics();
         gc.fillRect(0, 0, dim.width, dim.height);
       }
       
       g2.drawImage(underlay, 0, 0, this);
     }

  } // end paintComponent
  

  public static void main(String[] args) 
  {
    JFrame frame = new JFrame();
    ImageDragger dragger = new ImageDragger();
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(dragger, BorderLayout.CENTER);
    frame.addWindowListener(
            new WindowAdapter()
            {
              public void windowClosing(WindowEvent e)
              {
                System.exit(0);
              }
            }
        );
    frame.setSize(500, 500);
    frame.setVisible(true);
  }

  public class MouseDragger extends MouseMotionAdapter 
  {
    public void mouseDragged(MouseEvent e) 
    {
      isDragging = true;

      currentX = e.getX();
      currentY = e.getY();

      repaint();
    }
  } // end class MouseDragger

  
  public class MousePresser extends MouseAdapter 
  {
    public void mousePressed(MouseEvent e) 
    {
      Dimension dim = getSize();
      dim.width /= 2;
      dim.height /= 2;

      image = new BufferedImage( dim.width, dim.height, BufferedImage.TYPE_BYTE_BINARY );
      Graphics2D g2 = image.createGraphics();
      if( g2 != null)
      try
      {
        g2.drawLine(0, 0, dim.width, dim.height);
        g2.drawLine(0, dim.height, dim.width, 0);
      }
      finally
      {
        g2.dispose();
      }
    }

    
    public void mouseReleased(MouseEvent e) 
    {
      oldValid = false;
      isDragging = false;
      isLast = true;
      repaint();
    }

  } // end class MousePresser

  public class Resizer extends ComponentAdapter
  {         
    public void componentResized(ComponentEvent e)
    {
      Dimension dim = getSize();
      underlay = createImage(dim.width, dim.height);
      Graphics gc = underlay.getGraphics();
      gc.fillRect(0, 0, dim.width, dim.height);
    }
    
  } // end class Resizer

} // end class ImageDragger
