1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Denis M. Kishenko 19 * @version $Revision$ 20 */ 21 22 package java.awt; 23 24 import java.awt.geom.Rectangle2D; 25 import java.io.Serializable; 26 27 /** 28 * The Rectangle class defines the rectangular area in terms of its upper left 29 * corner coordinates [x,y], its width, and its height. A Rectangle specified by 30 * [x, y, width, height] parameters has an outline path with corners at [x, y], 31 * [x + width,y], [x + width,y + height], and [x, y + height]. <br> 32 * <br> 33 * The rectangle is empty if the width or height is negative or zero. In this 34 * case the isEmpty method returns true. 35 * 36 * @since Android 1.0 37 */ 38 public class Rectangle extends Rectangle2D implements Shape, Serializable { 39 40 /** 41 * The Constant serialVersionUID. 42 */ 43 private static final long serialVersionUID = -4345857070255674764L; 44 45 /** 46 * The X coordinate of the rectangle's left upper corner. 47 */ 48 public int x; 49 50 /** 51 * The Y coordinate of the rectangle's left upper corner. 52 */ 53 public int y; 54 55 /** 56 * The width of rectangle. 57 */ 58 public int width; 59 60 /** 61 * The height of rectangle. 62 */ 63 public int height; 64 65 /** 66 * Instantiates a new rectangle with [0, 0] upper left corner coordinates, 67 * the width and the height are zero. 68 */ Rectangle()69 public Rectangle() { 70 setBounds(0, 0, 0, 0); 71 } 72 73 /** 74 * Instantiates a new rectangle whose upper left corner coordinates are 75 * given by the Point object (p.X and p.Y), and the width and the height are 76 * zero. 77 * 78 * @param p 79 * the Point specifies the upper left corner coordinates of the 80 * rectangle. 81 */ Rectangle(Point p)82 public Rectangle(Point p) { 83 setBounds(p.x, p.y, 0, 0); 84 } 85 86 /** 87 * Instantiates a new rectangle whose upper left corner coordinates are 88 * given by the Point object (p.X and p.Y), and the width and the height are 89 * given by Dimension object (d.width and d.height). 90 * 91 * @param p 92 * the point specifies the upper left corner coordinates of the 93 * rectangle. 94 * @param d 95 * the dimension specifies the width and the height of the 96 * rectangle. 97 */ Rectangle(Point p, Dimension d)98 public Rectangle(Point p, Dimension d) { 99 setBounds(p.x, p.y, d.width, d.height); 100 } 101 102 /** 103 * Instantiates a new rectangle determined by the upper left corner 104 * coordinates (x, y), width and height. 105 * 106 * @param x 107 * the X upper left corner coordinate of the rectangle. 108 * @param y 109 * the Y upper left corner coordinate of the rectangle. 110 * @param width 111 * the width of rectangle. 112 * @param height 113 * the height of rectangle. 114 */ Rectangle(int x, int y, int width, int height)115 public Rectangle(int x, int y, int width, int height) { 116 setBounds(x, y, width, height); 117 } 118 119 /** 120 * Instantiates a new rectangle with [0, 0] as its upper left corner 121 * coordinates and the specified width and height. 122 * 123 * @param width 124 * the width of rectangle. 125 * @param height 126 * the height of rectangle. 127 */ Rectangle(int width, int height)128 public Rectangle(int width, int height) { 129 setBounds(0, 0, width, height); 130 } 131 132 /** 133 * Instantiates a new rectangle with the same coordinates as the given 134 * source rectangle. 135 * 136 * @param r 137 * the Rectangle object which parameters will be used for 138 * instantiating a new Rectangle. 139 */ Rectangle(Rectangle r)140 public Rectangle(Rectangle r) { 141 setBounds(r.x, r.y, r.width, r.height); 142 } 143 144 /* 145 * public Rectangle(Dimension d) { setBounds(0, 0, d.width, d.height); } 146 */ 147 /** 148 * Gets the X coordinate of bound as a double. 149 * 150 * @return the X coordinate of bound as a double. 151 * @see java.awt.geom.RectangularShape#getX() 152 */ 153 @Override getX()154 public double getX() { 155 return x; 156 } 157 158 /** 159 * Gets the Y coordinate of bound as a double. 160 * 161 * @return the Y coordinate of bound as a double. 162 * @see java.awt.geom.RectangularShape#getY() 163 */ 164 @Override getY()165 public double getY() { 166 return y; 167 } 168 169 /** 170 * Gets the height of the rectangle as a double. 171 * 172 * @return the height of the rectangle as a double. 173 * @see java.awt.geom.RectangularShape#getHeight() 174 */ 175 @Override getHeight()176 public double getHeight() { 177 return height; 178 } 179 180 /** 181 * Gets the width of the rectangle as a double. 182 * 183 * @return the width of the rectangle as a double. 184 * @see java.awt.geom.RectangularShape#getWidth() 185 */ 186 @Override getWidth()187 public double getWidth() { 188 return width; 189 } 190 191 /** 192 * Determines whether or not the rectangle is empty. The rectangle is empty 193 * if its width or height is negative or zero. 194 * 195 * @return true, if the rectangle is empty, otherwise false. 196 * @see java.awt.geom.RectangularShape#isEmpty() 197 */ 198 @Override isEmpty()199 public boolean isEmpty() { 200 return width <= 0 || height <= 0; 201 } 202 203 /** 204 * Gets the size of a Rectangle as Dimension object. 205 * 206 * @return a Dimension object which represents size of the rectangle. 207 */ getSize()208 public Dimension getSize() { 209 return new Dimension(width, height); 210 } 211 212 /** 213 * Sets the size of the Rectangle. 214 * 215 * @param width 216 * the new width of the rectangle. 217 * @param height 218 * the new height of the rectangle. 219 */ setSize(int width, int height)220 public void setSize(int width, int height) { 221 this.width = width; 222 this.height = height; 223 } 224 225 /** 226 * Sets the size of a Rectangle specified as Dimension object. 227 * 228 * @param d 229 * a Dimension object which represents new size of a rectangle. 230 */ setSize(Dimension d)231 public void setSize(Dimension d) { 232 setSize(d.width, d.height); 233 } 234 235 /** 236 * Gets the location of a rectangle's upper left corner as a Point object. 237 * 238 * @return the Point object with coordinates equal to the upper left corner 239 * of the rectangle. 240 */ getLocation()241 public Point getLocation() { 242 return new Point(x, y); 243 } 244 245 /** 246 * Sets the location of the rectangle in terms of its upper left corner 247 * coordinates X and Y. 248 * 249 * @param x 250 * the X coordinate of the rectangle's upper left corner. 251 * @param y 252 * the Y coordinate of the rectangle's upper left corner. 253 */ setLocation(int x, int y)254 public void setLocation(int x, int y) { 255 this.x = x; 256 this.y = y; 257 } 258 259 /** 260 * Sets the location of a rectangle using a Point object to give the 261 * coordinates of the upper left corner. 262 * 263 * @param p 264 * the Point object which represents the new upper left corner 265 * coordinates of rectangle. 266 */ setLocation(Point p)267 public void setLocation(Point p) { 268 setLocation(p.x, p.y); 269 } 270 271 /** 272 * Moves a rectangle to the new location by moving its upper left corner to 273 * the point with coordinates X and Y. 274 * 275 * @param x 276 * the new X coordinate of the rectangle's upper left corner. 277 * @param y 278 * the new Y coordinate of the rectangle's upper left corner. 279 * @deprecated Use setLocation(int, int) method. 280 */ 281 @Deprecated move(int x, int y)282 public void move(int x, int y) { 283 setLocation(x, y); 284 } 285 286 /** 287 * Sets the rectangle to be the nearest rectangle with integer coordinates 288 * bounding the rectangle defined by the double-valued parameters. 289 * 290 * @param x 291 * the X coordinate of the upper left corner of the double-valued 292 * rectangle to be bounded. 293 * @param y 294 * the Y coordinate of the upper left corner of the double-valued 295 * rectangle to be bounded. 296 * @param width 297 * the width of the rectangle to be bounded. 298 * @param height 299 * the height of the rectangle to be bounded. 300 * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double) 301 */ 302 @Override setRect(double x, double y, double width, double height)303 public void setRect(double x, double y, double width, double height) { 304 int x1 = (int)Math.floor(x); 305 int y1 = (int)Math.floor(y); 306 int x2 = (int)Math.ceil(x + width); 307 int y2 = (int)Math.ceil(y + height); 308 setBounds(x1, y1, x2 - x1, y2 - y1); 309 } 310 311 /** 312 * Sets a new size for the rectangle. 313 * 314 * @param width 315 * the rectangle's new width. 316 * @param height 317 * the rectangle's new height. 318 * @deprecated use the setSize(int, int) method. 319 */ 320 @Deprecated resize(int width, int height)321 public void resize(int width, int height) { 322 setBounds(x, y, width, height); 323 } 324 325 /** 326 * Resets the bounds of a rectangle to the specified x, y, width and height 327 * parameters. 328 * 329 * @param x 330 * the new X coordinate of the upper left corner. 331 * @param y 332 * the new Y coordinate of the upper left corner. 333 * @param width 334 * the new width of rectangle. 335 * @param height 336 * the new height of rectangle. 337 * @deprecated use setBounds(int, int, int, int) method 338 */ 339 @Deprecated reshape(int x, int y, int width, int height)340 public void reshape(int x, int y, int width, int height) { 341 setBounds(x, y, width, height); 342 } 343 344 /** 345 * Gets bounds of the rectangle as a new Rectangle object. 346 * 347 * @return the Rectangle object with the same bounds as the original 348 * rectangle. 349 * @see java.awt.geom.RectangularShape#getBounds() 350 */ 351 @Override getBounds()352 public Rectangle getBounds() { 353 return new Rectangle(x, y, width, height); 354 } 355 356 /** 357 * Gets the bounds of the original rectangle as a Rectangle2D object. 358 * 359 * @return the Rectangle2D object which represents the bounds of the 360 * original rectangle. 361 * @see java.awt.geom.Rectangle2D#getBounds2D() 362 */ 363 @Override getBounds2D()364 public Rectangle2D getBounds2D() { 365 return getBounds(); 366 } 367 368 /** 369 * Sets the bounds of a rectangle to the specified x, y, width, and height 370 * parameters. 371 * 372 * @param x 373 * the X coordinate of the upper left corner. 374 * @param y 375 * the Y coordinate of the upper left corner. 376 * @param width 377 * the width of rectangle. 378 * @param height 379 * the height of rectangle. 380 */ setBounds(int x, int y, int width, int height)381 public void setBounds(int x, int y, int width, int height) { 382 this.x = x; 383 this.y = y; 384 this.height = height; 385 this.width = width; 386 } 387 388 /** 389 * Sets the bounds of the rectangle to match the bounds of the Rectangle 390 * object sent as a parameter. 391 * 392 * @param r 393 * the Rectangle object which specifies the new bounds. 394 */ setBounds(Rectangle r)395 public void setBounds(Rectangle r) { 396 setBounds(r.x, r.y, r.width, r.height); 397 } 398 399 /** 400 * Enlarges the rectangle by moving each corner outward from the center by a 401 * distance of dx horizonally and a distance of dy vertically. Specifically, 402 * changes a rectangle with [x, y, width, height] parameters to a rectangle 403 * with [x-dx, y-dy, width+2*dx, height+2*dy] parameters. 404 * 405 * @param dx 406 * the horizontal distance to move each corner coordinate. 407 * @param dy 408 * the vertical distance to move each corner coordinate. 409 */ grow(int dx, int dy)410 public void grow(int dx, int dy) { 411 x -= dx; 412 y -= dy; 413 width += dx + dx; 414 height += dy + dy; 415 } 416 417 /** 418 * Moves a rectangle a distance of mx along the x coordinate axis and a 419 * distance of my along y coordinate axis. 420 * 421 * @param mx 422 * the horizontal translation increment. 423 * @param my 424 * the vertical translation increment. 425 */ translate(int mx, int my)426 public void translate(int mx, int my) { 427 x += mx; 428 y += my; 429 } 430 431 /** 432 * Enlarges the rectangle to cover the specified point. 433 * 434 * @param px 435 * the X coordinate of the new point to be covered by the 436 * rectangle. 437 * @param py 438 * the Y coordinate of the new point to be covered by the 439 * rectangle. 440 */ add(int px, int py)441 public void add(int px, int py) { 442 int x1 = Math.min(x, px); 443 int x2 = Math.max(x + width, px); 444 int y1 = Math.min(y, py); 445 int y2 = Math.max(y + height, py); 446 setBounds(x1, y1, x2 - x1, y2 - y1); 447 } 448 449 /** 450 * Enlarges the rectangle to cover the specified point with the new point 451 * given as a Point object. 452 * 453 * @param p 454 * the Point object that specifies the new point to be covered by 455 * the rectangle. 456 */ add(Point p)457 public void add(Point p) { 458 add(p.x, p.y); 459 } 460 461 /** 462 * Adds a new rectangle to the original rectangle, the result is an union of 463 * the specified specified rectangle and original rectangle. 464 * 465 * @param r 466 * the Rectangle which is added to the original rectangle. 467 */ add(Rectangle r)468 public void add(Rectangle r) { 469 int x1 = Math.min(x, r.x); 470 int x2 = Math.max(x + width, r.x + r.width); 471 int y1 = Math.min(y, r.y); 472 int y2 = Math.max(y + height, r.y + r.height); 473 setBounds(x1, y1, x2 - x1, y2 - y1); 474 } 475 476 /** 477 * Determines whether or not the point with specified coordinates [px, py] 478 * is within the bounds of the rectangle. 479 * 480 * @param px 481 * the X coordinate of point. 482 * @param py 483 * the Y coordinate of point. 484 * @return true, if the point with specified coordinates [px, py] is within 485 * the bounds of the rectangle, false otherwise. 486 */ contains(int px, int py)487 public boolean contains(int px, int py) { 488 if (isEmpty()) { 489 return false; 490 } 491 if (px < x || py < y) { 492 return false; 493 } 494 px -= x; 495 py -= y; 496 return px < width && py < height; 497 } 498 499 /** 500 * Determines whether or not the point given as a Point object is within the 501 * bounds of the rectangle. 502 * 503 * @param p 504 * the Point object 505 * @return true, if the point p is within the bounds of the rectangle, 506 * otherwise false. 507 */ contains(Point p)508 public boolean contains(Point p) { 509 return contains(p.x, p.y); 510 } 511 512 /** 513 * Determines whether or not the rectangle specified by [rx, ry, rw, rh] 514 * parameters is located inside the original rectangle. 515 * 516 * @param rx 517 * the X coordinate of the rectangle to compare. 518 * @param ry 519 * the Y coordinate of the rectangle to compare. 520 * @param rw 521 * the width of the rectangle to compare. 522 * @param rh 523 * the height of the rectangle to compare. 524 * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely 525 * contained in the original rectangle, false otherwise. 526 */ contains(int rx, int ry, int rw, int rh)527 public boolean contains(int rx, int ry, int rw, int rh) { 528 return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1); 529 } 530 531 /** 532 * Compares whether or not the rectangle specified by the Rectangle object 533 * is located inside the original rectangle. 534 * 535 * @param r 536 * the Rectangle object. 537 * @return true, if the rectangle specified by Rectangle object is entirely 538 * contained in the original rectangle, false otherwise. 539 */ contains(Rectangle r)540 public boolean contains(Rectangle r) { 541 return contains(r.x, r.y, r.width, r.height); 542 } 543 544 /** 545 * Compares whether or not a point with specified coordinates [px, py] 546 * belongs to a rectangle. 547 * 548 * @param px 549 * the X coordinate of a point. 550 * @param py 551 * the Y coordinate of a point. 552 * @return true, if a point with specified coordinates [px, py] belongs to a 553 * rectangle, otherwise false. 554 * @deprecated use contains(int, int) method. 555 */ 556 @Deprecated inside(int px, int py)557 public boolean inside(int px, int py) { 558 return contains(px, py); 559 } 560 561 /** 562 * Returns the intersection of the original rectangle with the specified 563 * Rectangle2D. 564 * 565 * @param r 566 * the Rectangle2D object. 567 * @return the Rectangle2D object that is the result of intersecting the 568 * original rectangle with the specified Rectangle2D. 569 * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D) 570 */ 571 @Override createIntersection(Rectangle2D r)572 public Rectangle2D createIntersection(Rectangle2D r) { 573 if (r instanceof Rectangle) { 574 return intersection((Rectangle)r); 575 } 576 Rectangle2D dst = new Rectangle2D.Double(); 577 Rectangle2D.intersect(this, r, dst); 578 return dst; 579 } 580 581 /** 582 * Returns the intersection of the original rectangle with the specified 583 * rectangle. An empty rectangle is returned if there is no intersection. 584 * 585 * @param r 586 * the Rectangle object. 587 * @return the Rectangle object is result of the original rectangle with the 588 * specified rectangle. 589 */ intersection(Rectangle r)590 public Rectangle intersection(Rectangle r) { 591 int x1 = Math.max(x, r.x); 592 int y1 = Math.max(y, r.y); 593 int x2 = Math.min(x + width, r.x + r.width); 594 int y2 = Math.min(y + height, r.y + r.height); 595 return new Rectangle(x1, y1, x2 - x1, y2 - y1); 596 } 597 598 /** 599 * Determines whether or not the original rectangle intersects the specified 600 * rectangle. 601 * 602 * @param r 603 * the Rectangle object. 604 * @return true, if the two rectangles overlap, false otherwise. 605 */ intersects(Rectangle r)606 public boolean intersects(Rectangle r) { 607 return !intersection(r).isEmpty(); 608 } 609 610 /** 611 * Determines where the specified Point is located with respect to the 612 * rectangle. This method computes whether the point is to the right or to 613 * the left of the rectangle and whether it is above or below the rectangle, 614 * and packs the result into an integer by using a binary OR operation with 615 * the following masks: 616 * <ul> 617 *<li>Rectangle2D.OUT_LEFT</li> 618 *<li>Rectangle2D.OUT_TOP</li> 619 *<li>Rectangle2D.OUT_RIGHT</li> 620 *<li>Rectangle2D.OUT_BOTTOM</li> 621 *</ul> 622 * If the rectangle is empty, all masks are set, and if the point is inside 623 * the rectangle, none are set. 624 * 625 * @param px 626 * the X coordinate of the specified point. 627 * @param py 628 * the Y coordinate of the specified point. 629 * @return the location of the Point relative to the rectangle as the result 630 * of logical OR operation with all out masks. 631 * @see java.awt.geom.Rectangle2D#outcode(double, double) 632 */ 633 @Override outcode(double px, double py)634 public int outcode(double px, double py) { 635 int code = 0; 636 637 if (width <= 0) { 638 code |= OUT_LEFT | OUT_RIGHT; 639 } else if (px < x) { 640 code |= OUT_LEFT; 641 } else if (px > x + width) { 642 code |= OUT_RIGHT; 643 } 644 645 if (height <= 0) { 646 code |= OUT_TOP | OUT_BOTTOM; 647 } else if (py < y) { 648 code |= OUT_TOP; 649 } else if (py > y + height) { 650 code |= OUT_BOTTOM; 651 } 652 653 return code; 654 } 655 656 /** 657 * Enlarges the rectangle to cover the specified Rectangle2D. 658 * 659 * @param r 660 * the Rectangle2D object. 661 * @return the union of the original and the specified Rectangle2D. 662 * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D) 663 */ 664 @Override createUnion(Rectangle2D r)665 public Rectangle2D createUnion(Rectangle2D r) { 666 if (r instanceof Rectangle) { 667 return union((Rectangle)r); 668 } 669 Rectangle2D dst = new Rectangle2D.Double(); 670 Rectangle2D.union(this, r, dst); 671 return dst; 672 } 673 674 /** 675 * Enlarges the rectangle to cover the specified rectangle. 676 * 677 * @param r 678 * the Rectangle. 679 * @return the union of the original and the specified rectangle. 680 */ union(Rectangle r)681 public Rectangle union(Rectangle r) { 682 Rectangle dst = new Rectangle(this); 683 dst.add(r); 684 return dst; 685 } 686 687 /** 688 * Compares the original Rectangle with the specified object. 689 * 690 * @param obj 691 * the specified Object for comparison. 692 * @return true, if the specified Object is a rectangle with the same 693 * dimensions as the original rectangle, false otherwise. 694 * @see java.awt.geom.Rectangle2D#equals(Object) 695 */ 696 @Override equals(Object obj)697 public boolean equals(Object obj) { 698 if (obj == this) { 699 return true; 700 } 701 if (obj instanceof Rectangle) { 702 Rectangle r = (Rectangle)obj; 703 return r.x == x && r.y == y && r.width == width && r.height == height; 704 } 705 return false; 706 } 707 708 /** 709 * Returns a string representation of the rectangle; the string contains [x, 710 * y, width, height] parameters of the rectangle. 711 * 712 * @return the string representation of the rectangle. 713 */ 714 @Override toString()715 public String toString() { 716 // The output format based on 1.5 release behaviour. It could be 717 // obtained in the following way 718 // System.out.println(new Rectangle().toString()) 719 return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ 720 ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 721 } 722 723 } 724