For other graphics newbies, I hope this is helpful.

The answer is to take advantage of the Swing painting architecture, which I had 
every intention of doing, but still managed to burn myself with.

Instead of using paintImmediately() to erase a region, have the mouse listener 
update the start and end points of the crop rectangle, and call repaint().  The 
Swing repaint mechanism will coalesce these calls where necessary (eliminating 
some flicker right there) and Swing components are double-buffered by default 
(which I knew and promptly did not take advantage of for some reason).

The new code (for completeness) is pasted below.  BSD-licensed for all you 
reckless copy and pasters.

Thanks,
Laird

ImagePanel.java (code condensed to save space in this forum):
[code]
package bricks.swing.imagepanel;
import java.awt.*;
import javax.swing.JPanel;
public class ImagePanel extends JPanel {

  private Image suppliedImage;
  protected Image imageToPaint;
  
  public ImagePanel() {
    super();
  }
  public Image getImage() {
    return this.suppliedImage;
  }
  public void setImage(final Image image) {
    final Image old = this.getImage();
    this.suppliedImage = image;
    this.imageToPaint = image;
    if (image != null) {
      final int height = image.getHeight(this);
      final int width = image.getWidth(this);
      if (height >= 0 && width >= 0) {
        this.setPreferredSize(new Dimension(height, width));
      }
    }
    this.firePropertyChange("image", old, this.getImage());
  }
  @Override
  protected void paintComponent(final Graphics graphics) {
    super.paintComponent(graphics);
    this.paintImage(graphics);
  }
  protected void paintImage(final Graphics graphics) {
    if (graphics != null && this.imageToPaint != null) {
      graphics.drawImage(this.imageToPaint, 0, 0, this.getWidth(), 
this.getHeight(), this);
    }
  }
}
[/code]

ImageCropper.java (incomplete, but the drawing works):
[code]
package bricks.swing.imagepanel;
import java.awt.*;
import java.awt.event.*;

public class ImageCropper extends ImagePanel {

  private static final Color RECTANGLE_COLOR = new Color(0, 0, 255, 40);
  private final MouseAdapter mouseListener;
  private int startX;
  private int startY;
  private int currentX;
  private int currentY;

  public ImageCropper() {
    super();
    this.mouseListener = new MouseAdapter() {
        private boolean dragging;
        
        @Override
        public final void mousePressed(final MouseEvent event) {
          if (event != null && !this.dragging) {
            this.dragging = true;
            ImageCropper.this.startX = event.getX();
            ImageCropper.this.startY = event.getY();
            ImageCropper.this.currentX = ImageCropper.this.startX;
            ImageCropper.this.currentY = ImageCropper.this.startY;
            ImageCropper.this.repaint();
          }
        }

        @Override
        public final void mouseDragged(final MouseEvent event) {
          if (event != null && this.dragging) {
            ImageCropper.this.currentX = event.getX();
            ImageCropper.this.currentY = event.getY();
            ImageCropper.this.repaint();
          }
        }

        @Override
        public final void mouseReleased(final MouseEvent event) {
          if (event != null && this.dragging) {
            this.dragging = false;
            ImageCropper.this.currentX = event.getX();
            ImageCropper.this.currentY = event.getY();
            ImageCropper.this.repaint();
          }
        }
      };
    this.addMouseListener(this.mouseListener);
    this.addMouseMotionListener(this.mouseListener);
  }

  @Override
  protected void paintComponent(final Graphics graphics) {
    super.paintComponent(graphics);
    if (graphics != null && 
        this.startX >= 0 &&
        this.startX != this.currentX && 
        this.startY >= 0 &&
        this.startY != this.currentY) {
      final int x;
      final int width;
      if (this.currentX > this.startX) {
        x = this.startX;
        width = this.currentX - this.startX;
      } else if (this.currentX == this.startX) {
        width = 0;
        return;
      } else {
        x = this.currentX;
        width = this.startX - this.currentX;
      }
      final int y;
      final int height;
      if (this.currentY > this.startY) {
        y = this.startY;
        height = this.currentY - this.startY;
      } else {
        assert this.currentY < this.startY;
        y = this.currentY;
        height = this.startY - this.currentY;
      }
      this.paintRectangle(graphics, x, y, width, height);
    }
  }
  
  protected void paintRectangle(final Graphics graphics, final int x, final int 
y, final int width, final int height) {
    if (graphics != null) {
      final Color oldColor = graphics.getColor();
      try {
        graphics.setColor(RECTANGLE_COLOR);
        graphics.fillRect(x, y, width, height);
      } finally {
        graphics.setColor(oldColor);
      }
    }
  }

}
[/code]
[Message sent by forum member 'ljnelson' (ljnelson)]

http://forums.java.net/jive/thread.jspa?messageID=294169

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to