summaryrefslogtreecommitdiff
path: root/java/gjt/rubberband/Rubberband.java
blob: be4b1b6ac054396218420f25ba0e93f011c1b093 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package gjt.rubberband;

import java.awt.*;

/** 
 * A abstract base class for rubberbands.<p>
 *
 * Rubberbands do their rubberbanding inside of a Component, 
 * which must be specified at construction time.<p>
 * 
 * Subclasses are responsible for implementing 
 * <em>void drawLast(Graphics g)</em> and 
 * <em>void drawNext(Graphics g)</em>.  
 *
 * drawLast() draws the appropriate geometric shape at the last 
 * rubberband location, while drawNext() draws the appropriate 
 * geometric shape at the next rubberband location.  All of the 
 * underlying support for rubberbanding is taken care of here, 
 * including handling XOR mode setting; extensions of Rubberband
 * need not concern themselves with anything but drawing the 
 * last and next geometric shapes.<p>
 *
 * @version 1.00, 12/27/95
 * @author  David Geary
 * @see     RubberbandLine
 * @see     RubberbandRectangle
 * @see     RubberbandEllipse
 * @see     gjt.test.RubberbandTest
 */
abstract public class Rubberband {
    protected Point anchor    = new Point(0,0); 
    protected Point stretched = new Point(0,0);
    protected Point last      = new Point(0,0); 
    protected Point end       = new Point(0,0);

    private Component component;
    private boolean   firstStretch = true;

    abstract public void drawLast(Graphics g);
    abstract public void drawNext(Graphics g);

    public Rubberband(Component component) {
        this.component = component;
    }
    public Point getAnchor   () { return anchor;    }
    public Point getStretched() { return stretched; }
    public Point getLast     () { return last;      }
    public Point getEnd      () { return end;       }

    public void anchor(Point p) {
        firstStretch = true;
        anchor.x = p.x;
        anchor.y = p.y;

        stretched.x = last.x = anchor.x;
        stretched.y = last.y = anchor.y;
    }
    public void stretch(Point p) {
        last.x      = stretched.x;
        last.y      = stretched.y;
        stretched.x = p.x;
        stretched.y = p.y;

        Graphics g = component.getGraphics();
        if(g != null) {
            g.setXORMode(component.getBackground());

            if(firstStretch == true) firstStretch = false;
            else                     drawLast(g);

            drawNext(g);
        }
    }
    public void end(Point p) {
        last.x = end.x = p.x;
        last.y = end.y = p.y;

        Graphics g = component.getGraphics();
        if(g != null) {
            g.setXORMode(component.getBackground());
            drawLast(g);
        }
    }
    public Rectangle bounds() {
      return new Rectangle(stretched.x < anchor.x ? 
                           stretched.x : anchor.x,
                           stretched.y < anchor.y ? 
                           stretched.y : anchor.y,
                           Math.abs(stretched.x - anchor.x),
                           Math.abs(stretched.y - anchor.y));
    }

    public Rectangle lastBounds() {
      return new Rectangle(
                  last.x < anchor.x ? last.x : anchor.x,
                  last.y < anchor.y ? last.y : anchor.y,
                  Math.abs(last.x - anchor.x),
                  Math.abs(last.y - anchor.y));
    }
}