001    /* RubberBandRectangle.java
002     * Created on February 6, 2008
003     */
004    import javax.swing.*;
005    import java.awt.*;
006    
007    /** This class implements a rectangle suitable for use in rubberbanding
008     * in a JPanel. This is used for selecting a region or rectangle in the panel.
009     *
010     * @author William Krieger
011     */
012    public class RubberBandRectangle {
013        /** Panel that this rubber band services */
014        private JPanel panel;
015        /** Current rectangle for the rubber band */
016        private Rectangle rect;
017        /** Start point for the rectangle */
018        private Point start;
019    
020        /** Creates a new instance of RubberBandRectangle in the given panel.
021         * @param panel The panel in which we're drawing.
022         */
023        public RubberBandRectangle( JPanel panel) {
024            this.panel = panel;
025            rect = new Rectangle();
026        }
027    
028        /** Returns the rectangle for the current rubber band.
029         * @return Returns the rectangle, never null.
030         */
031        public Rectangle getRectangle() { return rect; }
032    
033        /** Start the rubber band at this point. This is usually the point
034         * at which the mouse was initially pressed.
035         * @param p Point where the rubber banding starts.
036         */
037        public void start( Point p) {
038            start = new Point( p);
039            rect.setLocation( p.x, p.y);
040            rect.setSize( 0, 0);
041        }
042    
043        /** Move the rubber band rectangle to the given point, drawing the 
044         * result. The point is typically the current location of the mouse
045         * as it is being dragged.
046         * @param p Current location of the mouse.
047         */
048        public void move( Point p) {
049            draw();
050            rect.setLocation( Math.min( start.x, p.x), Math.min( start.y, p.y));
051            rect.setSize( Math.abs( start.x - p.x), Math.abs( start.y - p.y));
052            draw();
053        }
054    
055        /** Draws the rubber band rectangle. 
056         * XOR mode is used, so that a call to draw() may erase an already drawn
057         * rectangle.
058         */
059        public void draw() {
060            if( rect.width < 2  && rect.height < 2) { return; }
061    
062            Graphics g = panel.getGraphics();
063            g.setXORMode( panel.getBackground());
064            g.drawRect( rect.x, rect.y, rect.width, rect.height);
065        }
066    }