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".