source: trunk/gcc/libjava/java/awt/Rectangle.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 20.9 KB
Line 
1/* Rectangle.java -- represents a graphics rectangle
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.awt;
40
41import java.awt.geom.AffineTransform;
42import java.awt.geom.Rectangle2D;
43import java.io.Serializable;
44
45/**
46 * This class represents a rectangle and all the interesting things you
47 * might want to do with it. Note that the coordinate system uses
48 * the origin (0,0) as the top left of the screen, with the x and y
49 * values increasing as they move to the right and down respectively.
50 *
51 * <p>It is valid for a rectangle to have negative width or height; but it
52 * is considered to have no area or internal points. Therefore, the behavior
53 * in methods like <code>contains</code> or <code>intersects</code> is
54 * undefined unless the rectangle has positive width and height.
55 *
56 * <p>There are some public fields; if you mess with them in an inconsistent
57 * manner, it is your own fault when you get NullPointerException,
58 * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is
59 * not threadsafe.
60 *
61 * @author Warren Levy <warrenl@cygnus.com>
62 * @author Aaron M. Renn <arenn@urbanophile.com>
63 * @author Eric Blake <ebb9@email.byu.edu>
64 * @since 1.0
65 * @status updated to 1.4
66 */
67public class Rectangle extends Rectangle2D implements Shape, Serializable
68{
69 /**
70 * Compatible with JDK 1.0+.
71 */
72 private static final long serialVersionUID = -4345857070255674764L;
73
74 /**
75 * The X coordinate of the top-left corner of the rectangle.
76 *
77 * @see #setLocation(int, int)
78 * @see #getLocation()
79 * @serial the x coordinate
80 */
81 public int x;
82
83 /**
84 * The Y coordinate of the top-left corner of the rectangle.
85 *
86 * @see #setLocation(int, int)
87 * @see #getLocation()
88 * @serial the y coordinate
89 */
90 public int y;
91
92 /**
93 * The width of the rectangle.
94 *
95 * @see #setSize(int, int)
96 * @see #getSize()
97 * @serial
98 */
99 public int width;
100
101 /**
102 * The height of the rectangle.
103 *
104 * @see #setSize(int, int)
105 * @see #getSize()
106 * @serial
107 */
108 public int height;
109
110 /**
111 * Initializes a new instance of <code>Rectangle</code> with a top
112 * left corner at (0,0) and a width and height of 0.
113 */
114 public Rectangle()
115 {
116 }
117
118 /**
119 * Initializes a new instance of <code>Rectangle</code> from the
120 * coordinates of the specified rectangle.
121 *
122 * @param r the rectangle to copy from
123 * @throws NullPointerException if r is null
124 * @since 1.1
125 */
126 public Rectangle(Rectangle r)
127 {
128 x = r.x;
129 y = r.y;
130 width = r.width;
131 height = r.height;
132 }
133
134 /**
135 * Initializes a new instance of <code>Rectangle</code> from the specified
136 * inputs.
137 *
138 * @param x the X coordinate of the top left corner
139 * @param y the Y coordinate of the top left corner
140 * @param width the width of the rectangle
141 * @param height the height of the rectangle
142 */
143 public Rectangle(int x, int y, int width, int height)
144 {
145 this.x = x;
146 this.y = y;
147 this.width = width;
148 this.height = height;
149 }
150
151 /**
152 * Initializes a new instance of <code>Rectangle</code> with the specified
153 * width and height. The upper left corner of the rectangle will be at
154 * the origin (0,0).
155 *
156 * @param width the width of the rectangle
157 * @param height the height of the rectange
158 */
159 public Rectangle(int width, int height)
160 {
161 this.width = width;
162 this.height = height;
163 }
164
165 /**
166 * Initializes a new instance of <code>Rectangle</code> with a top-left
167 * corner represented by the specified point and the width and height
168 * represented by the specified dimension.
169 *
170 * @param p the upper left corner of the rectangle
171 * @param d the width and height of the rectangle
172 * @throws NullPointerException if p or d is null
173 */
174 public Rectangle(Point p, Dimension d)
175 {
176 x = p.x;
177 y = p.y;
178 width = d.width;
179 height = d.height;
180 }
181
182 /**
183 * Initializes a new instance of <code>Rectangle</code> with a top left
184 * corner at the specified point and a width and height of zero.
185 *
186 * @param p the upper left corner of the rectangle
187 */
188 public Rectangle(Point p)
189 {
190 x = p.x;
191 y = p.y;
192 }
193
194 /**
195 * Initializes a new instance of <code>Rectangle</code> with an
196 * upper left corner at the origin (0,0) and a width and height represented
197 * by the specified dimension.
198 *
199 * @param d the width and height of the rectangle
200 */
201 public Rectangle(Dimension d)
202 {
203 width = d.width;
204 height = d.height;
205 }
206
207 /**
208 * Get the X coordinate of the upper-left corner.
209 *
210 * @return the value of x, as a double
211 */
212 public double getX()
213 {
214 return x;
215 }
216
217 /**
218 * Get the Y coordinate of the upper-left corner.
219 *
220 * @return the value of y, as a double
221 */
222 public double getY()
223 {
224 return y;
225 }
226
227 /**
228 * Get the width of the rectangle.
229 *
230 * @return the value of width, as a double
231 */
232 public double getWidth()
233 {
234 return width;
235 }
236
237 /**
238 * Get the height of the rectangle.
239 *
240 * @return the value of height, as a double
241 */
242 public double getHeight()
243 {
244 return height;
245 }
246
247 /**
248 * Returns the bounds of this rectangle. A pretty useless method, as this
249 * is already a rectangle; it is included to mimic the
250 * <code>getBounds</code> method in Component.
251 *
252 * @return a copy of this rectangle
253 * @see #setBounds(Rectangle)
254 * @since 1.1
255 */
256 public Rectangle getBounds()
257 {
258 return new Rectangle(this);
259 }
260
261 /**
262 * Returns the high-precision bounds of this rectangle. A pretty useless
263 * method, as this is already a rectangle.
264 *
265 * @return a copy of this rectangle
266 * @see #setBounds(Rectangle)
267 * @since 1.2
268 */
269 public Rectangle2D getBounds2D()
270 {
271 return new Rectangle(x, y, width, height);
272 }
273
274 /**
275 * Updates this rectangle to match the dimensions of the specified
276 * rectangle.
277 *
278 * @param r the rectangle to update from
279 * @throws NullPointerException if r is null
280 * @see #setBounds(int, int, int, int)
281 * @since 1.1
282 */
283 public void setBounds(Rectangle r)
284 {
285 x = r.x;
286 y = r.y;
287 width = r.width;
288 height = r.height;
289 }
290
291 /**
292 * Updates this rectangle to have the specified dimensions.
293 *
294 * @param x the new X coordinate of the upper left hand corner
295 * @param y the new Y coordinate of the upper left hand corner
296 * @param width the new width of this rectangle
297 * @param height the new height of this rectangle
298 * @since 1.1
299 */
300 public void setBounds(int x, int y, int width, int height)
301 {
302 this.x = x;
303 this.y = y;
304 this.width = width;
305 this.height = height;
306 }
307
308 /**
309 * Updates this rectangle to have the specified dimensions, as rounded to
310 * integers.
311 *
312 * @param x the new X coordinate of the upper left hand corner
313 * @param y the new Y coordinate of the upper left hand corner
314 * @param width the new width of this rectangle
315 * @param height the new height of this rectangle
316 * @since 1.2
317 */
318 public void setRect(double x, double y, double width, double height)
319 {
320 this.x = (int) x;
321 this.y = (int) y;
322 this.width = (int) width;
323 this.height = (int) height;
324 }
325
326 /**
327 * Updates this rectangle to have the specified dimensions.
328 *
329 * @param x the new X coordinate of the upper left hand corner
330 * @param y the new Y coordinate of the upper left hand corner
331 * @param width the new width of this rectangle
332 * @param height the new height of this rectangle
333 * @deprecated use {@link #setBounds(int, int, int, int)} instead
334 */
335 public void reshape(int x, int y, int width, int height)
336 {
337 setBounds(x, y, width, height);
338 }
339
340 /**
341 * Returns the location of this rectangle, which is the coordinates of
342 * its upper left corner.
343 *
344 * @return the point where this rectangle is located
345 * @see setLocation(Point)
346 * @since 1.1
347 */
348 public Point getLocation()
349 {
350 return new Point(x,y);
351 }
352
353 /**
354 * Moves the location of this rectangle by setting its upper left
355 * corner to the specified point.
356 *
357 * @param p the point to move the rectangle to
358 * @throws NullPointerException if p is null
359 * @see #getLocation()
360 * @since 1.1
361 */
362 public void setLocation(Point p)
363 {
364 this.x = p.x;
365 this.y = p.y;
366 }
367
368 /**
369 * Moves the location of this rectangle by setting its upper left
370 * corner to the specified coordinates.
371 *
372 * @param x the new X coordinate for this rectangle
373 * @param y the new Y coordinate for this rectangle
374 * @since 1.1
375 */
376 public void setLocation(int x, int y)
377 {
378 this.x = x;
379 this.y = y;
380 }
381
382 /**
383 * Moves the location of this rectangle by setting its upper left
384 * corner to the specified coordinates.
385 *
386 * @param x the new X coordinate for this rectangle
387 * @param y the new Y coordinate for this rectangle
388 * @deprecated use {@link #setLocation(int, int)} instead
389 */
390 public void move(int x, int y)
391 {
392 setLocation(x, y);
393 }
394
395 /**
396 * Translate the location of this rectangle by the given amounts.
397 *
398 * @param dx the x distance to move by
399 * @param dy the y distance to move by
400 * @see #setLocation(int, int)
401 */
402 public void translate(int dx, int dy)
403 {
404 x += dx;
405 y += dy;
406 }
407
408 /**
409 * Returns the size of this rectangle.
410 *
411 * @return the size of this rectangle
412 * @see #setSize(Dimension)
413 * @since 1.1
414 */
415 public Dimension getSize()
416 {
417 return new Dimension(width, height);
418 }
419
420 /**
421 * Sets the size of this rectangle based on the specified dimensions.
422 *
423 * @param d the new dimensions of the rectangle
424 * @throws NullPointerException if d is null
425 * @see #getSize()
426 * @since 1.1
427 */
428 public void setSize(Dimension d)
429 {
430 width = d.width;
431 height = d.height;
432 }
433
434 /**
435 * Sets the size of this rectangle based on the specified dimensions.
436 *
437 * @param width the new width of the rectangle
438 * @param height the new height of the rectangle
439 * @since 1.1
440 */
441 public void setSize(int width, int height)
442 {
443 this.width = width;
444 this.height = height;
445 }
446
447 /**
448 * Sets the size of this rectangle based on the specified dimensions.
449 *
450 * @param width the new width of the rectangle
451 * @param height the new height of the rectangle
452 * @deprecated use {@link #setSize(int, int)} instead
453 */
454 public void resize(int width, int height)
455 {
456 setSize(width, height);
457 }
458
459 /**
460 * Tests whether or not the specified point is inside this rectangle.
461 * According to the contract of Shape, a point on the border is in only if
462 * it has an adjacent point inside the rectangle in either the increasing
463 * x or y direction.
464 *
465 * @param p the point to test
466 * @return true if the point is inside the rectangle
467 * @throws NullPointerException if p is null
468 * @see #contains(int, int)
469 * @since 1.1
470 */
471 public boolean contains(Point p)
472 {
473 return width > 0 && height > 0
474 && p.x >= x && p.x < x + width
475 && p.y >= y && p.y < y + height;
476 }
477
478 /**
479 * Tests whether or not the specified point is inside this rectangle.
480 * According to the contract of Shape, a point on the border is in only if
481 * it has an adjacent point inside the rectangle in either the increasing
482 * x or y direction.
483 *
484 * @param x the X coordinate of the point to test
485 * @param y the Y coordinate of the point to test
486 * @return true if the point is inside the rectangle
487 * @since 1.1
488 */
489 public boolean contains(int x, int y)
490 {
491 return width > 0 && height > 0
492 && x >= this.x && x < this.x + width
493 && y >= this.y && y < this.y + height;
494 }
495
496 /**
497 * Checks whether all points in the given rectangle are contained in this
498 * rectangle.
499 *
500 * @param r the rectangle to check
501 * @return true if r is contained in this rectangle
502 * @throws NullPointerException if r is null
503 * @see #contains(int, int, int, int)
504 * @since 1.1
505 */
506 public boolean contains(Rectangle r)
507 {
508 return width > 0 && height > 0 && r.width > 0 && r.height > 0
509 && r.x >= x && r.x + r.width <= x + width
510 && r.y >= y && r.y + r.height <= y + height;
511 }
512
513 /**
514 * Checks whether all points in the given rectangle are contained in this
515 * rectangle.
516 *
517 * @param x the x coordinate of the rectangle to check
518 * @param y the y coordinate of the rectangle to check
519 * @param w the width of the rectangle to check
520 * @param h the height of the rectangle to check
521 * @return true if the parameters are contained in this rectangle
522 * @since 1.1
523 */
524 public boolean contains(int x, int y, int w, int h)
525 {
526 return width > 0 && height > 0 && w > 0 && h > 0
527 && x >= this.x && x + w <= this.x + this.width
528 && y >= this.y && y + h <= this.y + this.height;
529 }
530
531 /**
532 * Tests whether or not the specified point is inside this rectangle.
533 *
534 * @param x the X coordinate of the point to test
535 * @param y the Y coordinate of the point to test
536 * @return true if the point is inside the rectangle
537 * @deprecated use {@link #contains(int, int)} instead
538 */
539 public boolean inside(int x, int y)
540 {
541 return contains(x, y);
542 }
543
544 /**
545 * Tests whether or not the specified rectangle intersects this rectangle.
546 * This means the two rectangles share at least one internal point.
547 *
548 * @param r the rectangle to test against
549 * @return true if the specified rectangle intersects this one
550 * @throws NullPointerException if r is null
551 * @since 1.2
552 */
553 public boolean intersects(Rectangle r)
554 {
555 return width > 0 && height > 0 && r.width > 0 && r.height > 0
556 && r.x < x + width && r.x + r.width > x
557 && r.y < y + height && r.y + r.height > y;
558 }
559
560 /**
561 * Determines the rectangle which is formed by the intersection of this
562 * rectangle with the specified rectangle. If the two do not intersect,
563 * an empty rectangle will be returned (meaning the width and/or height
564 * will be non-positive).
565 *
566 * @param r the rectange to calculate the intersection with
567 * @return a new rectangle bounding the intersection
568 * @throws NullPointerException if r is null
569 */
570 public Rectangle intersection(Rectangle r)
571 {
572 Rectangle res = new Rectangle();
573 intersect(this, r, res);
574 return res;
575 }
576
577 /**
578 * Returns the smallest rectangle that contains both this rectangle
579 * and the specified rectangle.
580 *
581 * @param r the rectangle to compute the union with
582 * @return the smallest rectangle containing both rectangles
583 * @throws NullPointerException if r is null
584 */
585 public Rectangle union(Rectangle r)
586 {
587 Rectangle res = new Rectangle();
588 union(this, r, res);
589 return res;
590 }
591
592 /**
593 * Modifies this rectangle so that it represents the smallest rectangle
594 * that contains both the existing rectangle and the specified point.
595 * However, if the point falls on one of the two borders which are not
596 * inside the rectangle, a subsequent call to <code>contains</code> may
597 * return false.
598 *
599 * @param x the X coordinate of the point to add to this rectangle
600 * @param y the Y coordinate of the point to add to this rectangle
601 */
602 public void add(int x, int y)
603 {
604 add((double) x, (double) y);
605 }
606
607 /**
608 * Modifies this rectangle so that it represents the smallest rectangle
609 * that contains both the existing rectangle and the specified point.
610 * However, if the point falls on one of the two borders which are not
611 * inside the rectangle, a subsequent call to <code>contains</code> may
612 * return false.
613 *
614 * @param p the point to add to this rectangle
615 * @throws NullPointerException if p is null
616 */
617 public void add(Point p)
618 {
619 add((double) p.x, (double) p.y);
620 }
621
622 /**
623 * Modifies this rectangle so that it represents the smallest rectangle
624 * that contains both the existing rectangle and the specified rectangle.
625 *
626 * @param r the rectangle to add to this rectangle
627 * @throws NullPointerException if r is null
628 * @see #union(Rectangle)
629 */
630 public void add(Rectangle r)
631 {
632 union(this, r, this);
633 }
634
635 /**
636 * Expands the rectangle by the specified amount. The horizontal
637 * and vertical expansion values are applied both to the X,Y coordinate
638 * of this rectangle, and its width and height. Thus the width and
639 * height will increase by 2h and 2v accordingly.
640 *
641 * @param h the horizontal expansion value
642 * @param v the vertical expansion value
643 */
644 public void grow(int h, int v)
645 {
646 x -= h;
647 y -= v;
648 width += h + h;
649 height += v + v;
650 }
651
652 /**
653 * Tests whether or not this rectangle is empty. An empty rectangle
654 * has a non-positive width or height.
655 *
656 * @return true if the rectangle is empty
657 */
658 public boolean isEmpty()
659 {
660 return width <= 0 || height <= 0;
661 }
662
663 /**
664 * Determine where the point lies with respect to this rectangle. The
665 * result will be the binary OR of the appropriate bit masks.
666 *
667 * @param x the x coordinate to check
668 * @param y the y coordinate to check
669 * @return the binary OR of the result
670 * @see #OUT_LEFT
671 * @see #OUT_TOP
672 * @see #OUT_RIGHT
673 * @see #OUT_BOTTOM
674 * @since 1.2
675 */
676 public int outcode(double x, double y)
677 {
678 int result = 0;
679 if (width <= 0)
680 result |= OUT_LEFT | OUT_RIGHT;
681 else if (x < this.x)
682 result |= OUT_LEFT;
683 else if (x > this.x + width)
684 result |= OUT_RIGHT;
685 if (height <= 0)
686 result |= OUT_BOTTOM | OUT_TOP;
687 else if (y < this.y) // Remember that +y heads top-to-bottom.
688 result |= OUT_TOP;
689 else if (y > this.y + height)
690 result |= OUT_BOTTOM;
691 return result;
692 }
693
694 /**
695 * Determines the rectangle which is formed by the intersection of this
696 * rectangle with the specified rectangle. If the two do not intersect,
697 * an empty rectangle will be returned (meaning the width and/or height
698 * will be non-positive).
699 *
700 * @param r the rectange to calculate the intersection with
701 * @return a new rectangle bounding the intersection
702 * @throws NullPointerException if r is null
703 * @since 1.2
704 */
705 public Rectangle2D createIntersection(Rectangle2D r)
706 {
707 // Favor runtime type of other rectangle.
708 Rectangle2D res = r.getBounds2D();
709 intersect(this, r, res);
710 return res;
711 }
712
713 /**
714 * Returns the smallest rectangle that contains both this rectangle
715 * and the specified rectangle.
716 *
717 * @param r the rectangle to compute the union with
718 * @return the smallest rectangle containing both rectangles
719 * @throws NullPointerException if r is null
720 * @since 1.2
721 */
722 public Rectangle2D createUnion(Rectangle2D r)
723 {
724 // Favor runtime type of other rectangle.
725 Rectangle2D res = r.getBounds2D();
726 union(this, r, res);
727 return res;
728 }
729
730 /**
731 * Tests this rectangle for equality against the specified object. This
732 * will be true if an only if the specified object is an instance of
733 * Rectangle2D with the same coordinates and dimensions.
734 *
735 * @param obj the object to test against for equality
736 * @return true if the specified object is equal to this one
737 */
738 public boolean equals(Object obj)
739 {
740 if (! (obj instanceof Rectangle2D))
741 return false;
742 Rectangle2D r = (Rectangle2D) obj;
743 return r.getX() == x && r.getY() == y
744 && r.getWidth() == width && r.getHeight() == height;
745 }
746
747 /**
748 * Returns a string representation of this rectangle. This is in the form
749 * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
750 * + ",height=" + height + ']'</code>.
751 *
752 * @return a string representation of this rectangle
753 */
754 public String toString()
755 {
756 return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
757 + ",height=" + height + ']';
758 }
759} // class Rectangle
Note: See TracBrowser for help on using the repository browser.