001: package jimm.datavision.field;
002:
003: import jimm.datavision.Writeable;
004: import jimm.util.XMLWriter;
005: import java.util.Observable;
006:
007: /**
008: * A rectangle with double coordinates.
009: *
010: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
011: */
012: public class Rectangle extends Observable implements Writeable {
013:
014: /**
015: * Warning: only read the x coordinate. When writing, make sure to use
016: * setter method so observers are notified.
017: */
018: public double x;
019: /**
020: * Warning: only read the y coordinate. When writing, make sure to use
021: * setter method so observers are notified.
022: */
023: public double y;
024: /**
025: * Warning: only read the width. When writing, make sure to use
026: * setter method so observers are notified.
027: */
028: public double width;
029: /**
030: * Warning: only read the height. When writing, make sure to use
031: * setter method so observers are notified.
032: */
033: public double height;
034:
035: /**
036: * Constructor.
037: */
038: public Rectangle() {
039: this (0, 0, 0, 0);
040: }
041:
042: /**
043: * Constructor.
044: *
045: * @param r the <em>other</em> kind of rectangle
046: */
047: public Rectangle(java.awt.Rectangle r) {
048: this (r.x, r.y, r.width, r.height);
049: }
050:
051: /**
052: * Constructor.
053: *
054: * @param r another rectangle
055: */
056: public Rectangle(Rectangle r) {
057: this (r.x, r.y, r.width, r.height);
058: }
059:
060: /**
061: * Constructor.
062: *
063: * @param x a double
064: * @param y a double
065: * @param width a double
066: * @param height a double
067: */
068: public Rectangle(double x, double y, double width, double height) {
069: this .x = x;
070: this .y = y;
071: this .width = width;
072: this .height = height;
073: }
074:
075: /**
076: * Returns the x coordinate.
077: *
078: * @return the doubleing-point x coordinate
079: */
080: public double getX() {
081: return x;
082: }
083:
084: /**
085: * Sets the x coordinate.
086: *
087: * @param newX the new x coordinate
088: */
089: public void setX(double newX) {
090: if (x != newX) {
091: x = newX;
092: setChanged();
093: notifyObservers();
094: }
095: }
096:
097: /**
098: * Returns the y coordinate.
099: *
100: * @return the doubleing-point y coordinate
101: */
102: public double getY() {
103: return y;
104: }
105:
106: /**
107: * Sets the y coordinate.
108: *
109: * @param newY the new y coordinate
110: */
111: public void setY(double newY) {
112: if (y != newY) {
113: y = newY;
114: setChanged();
115: notifyObservers();
116: }
117: }
118:
119: /**
120: * Returns the width.
121: *
122: * @return the doubleing-point width
123: */
124: public double getWidth() {
125: return width;
126: }
127:
128: /**
129: * Sets the width.
130: *
131: * @param newWidth the new width
132: */
133: public void setWidth(double newWidth) {
134: if (width != newWidth) {
135: width = newWidth;
136: setChanged();
137: notifyObservers();
138: }
139: }
140:
141: /**
142: * Returns the height.
143: *
144: * @return the doubleing-point height
145: */
146: public double getHeight() {
147: return height;
148: }
149:
150: /**
151: * Sets the height.
152: *
153: * @param newHeight the new height
154: */
155: public void setHeight(double newHeight) {
156: if (height != newHeight) {
157: height = newHeight;
158: setChanged();
159: notifyObservers();
160: }
161: }
162:
163: /**
164: * Sets everything at once.
165: *
166: * @param newX the new x coordinate
167: * @param newY the new y coordinate
168: * @param newWidth the new width
169: * @param newHeight the new height
170: */
171: public void setBounds(double newX, double newY, double newWidth,
172: double newHeight) {
173: // Instead of calling setX(), sety(), etc. individually, copy the
174: // code so we can call notifyObservers() once.
175: boolean needsToNotify = false;
176: if (x != newX) {
177: x = newX;
178: needsToNotify = true;
179: }
180: if (y != newY) {
181: y = newY;
182: needsToNotify = true;
183: }
184: if (width != newWidth) {
185: width = newWidth;
186: needsToNotify = true;
187: }
188: if (height != newHeight) {
189: height = newHeight;
190: needsToNotify = true;
191: }
192:
193: if (needsToNotify) {
194: setChanged();
195: notifyObservers();
196: }
197: }
198:
199: /**
200: * Sets everything at once.
201: *
202: * @param r a jimm.datavision.Rectangle
203: */
204: public void setBounds(jimm.datavision.field.Rectangle r) {
205: setBounds(r.x, r.y, r.width, r.height);
206: }
207:
208: /**
209: * Sets everything at once.
210: *
211: * @param r a java.awt.Rectangle
212: */
213: public void setBounds(java.awt.Rectangle r) {
214: setBounds(r.x, r.y, r.width, r.height);
215: }
216:
217: /**
218: * Returns a string representation of this rectangle.
219: *
220: * @return a string representing this rectangle
221: */
222: public String toString() {
223: return "[x=" + x + ", y=" + y + ", w=" + width + ", h="
224: + height + "]";
225: }
226:
227: /**
228: * Writes this rectangle as an XML tag.
229: *
230: * @param out a writer that knows how to write XML
231: */
232: public void writeXML(XMLWriter out) {
233: out.startElement("bounds");
234: out.attr("x", x);
235: out.attr("y", y);
236: out.attr("width", width);
237: out.attr("height", height);
238: out.endElement();
239: }
240:
241: }
|