1. /*
  2. * @(#)Rectangle.java 1.70 04/05/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.geom.Rectangle2D;
  9. /**
  10. * A <code>Rectangle</code> specifies an area in a coordinate space that is
  11. * enclosed by the <code>Rectangle</code> object's top-left point
  12. * (<i>x</i>, <i>y</i>)
  13. * in the coordinate space, its width, and its height.
  14. * <p>
  15. * A <code>Rectangle</code> object's <code>width</code> and
  16. * <code>height</code> are <code>public</code> fields. The constructors
  17. * that create a <code>Rectangle</code>, and the methods that can modify
  18. * one, do not prevent setting a negative value for width or height.
  19. * <p>
  20. * A <code>Rectangle</code> whose width or height is negative is considered
  21. * empty. If the <code>Rectangle</code> is empty, then the
  22. * <code>isEmpty</code> method returns <code>true</code>. No point can be
  23. * contained by or inside an empty <code>Rectangle</code>. The
  24. * values of <code>width</code> and <code>height</code>, however, are still
  25. * valid. An empty <code>Rectangle</code> still has a location in the
  26. * coordinate space, and methods that change its size or location remain
  27. * valid. The behavior of methods that operate on more than one
  28. * <code>Rectangle</code> is undefined if any of the participating
  29. * <code>Rectangle</code> objects has a negative
  30. * <code>width</code> or <code>height</code>. These methods include
  31. * <code>intersects</code>, <code>intersection</code>, and
  32. * <code>union</code>.
  33. *
  34. * @version 1.70, 05/18/04
  35. * @author Sami Shaio
  36. * @since JDK1.0
  37. */
  38. public class Rectangle extends Rectangle2D
  39. implements Shape, java.io.Serializable
  40. {
  41. /**
  42. * The <i>x</i> coordinate of the <code>Rectangle</code>.
  43. *
  44. * @serial
  45. * @see #setLocation(int, int)
  46. * @see #getLocation()
  47. */
  48. public int x;
  49. /**
  50. * The <i>y</i> coordinate of the <code>Rectangle</code>.
  51. *
  52. * @serial
  53. * @see #setLocation(int, int)
  54. * @see #getLocation()
  55. */
  56. public int y;
  57. /**
  58. * The width of the <code>Rectangle</code>.
  59. * @serial
  60. * @see #setSize(int, int)
  61. * @see #getSize()
  62. * @since JDK1.0.
  63. */
  64. public int width;
  65. /**
  66. * The height of the <code>Rectangle</code>.
  67. *
  68. * @serial
  69. * @see #setSize(int, int)
  70. * @see #getSize()
  71. */
  72. public int height;
  73. /*
  74. * JDK 1.1 serialVersionUID
  75. */
  76. private static final long serialVersionUID = -4345857070255674764L;
  77. /**
  78. * Initialize JNI field and method IDs
  79. */
  80. private static native void initIDs();
  81. static {
  82. /* ensure that the necessary native libraries are loaded */
  83. Toolkit.loadLibraries();
  84. if (!GraphicsEnvironment.isHeadless()) {
  85. initIDs();
  86. }
  87. }
  88. /**
  89. * Constructs a new <code>Rectangle</code> whose top-left corner
  90. * is at (0, 0) in the coordinate space, and whose width and
  91. * height are both zero.
  92. */
  93. public Rectangle() {
  94. this(0, 0, 0, 0);
  95. }
  96. /**
  97. * Constructs a new <code>Rectangle</code>, initialized to match
  98. * the values of the specified <code>Rectangle</code>.
  99. * @param r the <code>Rectangle</code> from which to copy initial values
  100. * to a newly constructed <code>Rectangle</code>
  101. * @since JDK1.1
  102. */
  103. public Rectangle(Rectangle r) {
  104. this(r.x, r.y, r.width, r.height);
  105. }
  106. /**
  107. * Constructs a new <code>Rectangle</code> whose top-left corner is
  108. * specified as
  109. * (<code>x</code>, <code>y</code>) and whose width and height
  110. * are specified by the arguments of the same name.
  111. * @param x the specified x coordinate
  112. * @param y the specified y coordinate
  113. * @param width the width of the <code>Rectangle</code>
  114. * @param height the height of the <code>Rectangle</code>
  115. */
  116. public Rectangle(int x, int y, int width, int height) {
  117. this.x = x;
  118. this.y = y;
  119. this.width = width;
  120. this.height = height;
  121. }
  122. /**
  123. * Constructs a new <code>Rectangle</code> whose top-left corner
  124. * is at (0, 0) in the coordinate space, and whose width and
  125. * height are specified by the arguments of the same name.
  126. * @param width the width of the <code>Rectangle</code>
  127. * @param height the height of the <code>Rectangle</code>
  128. */
  129. public Rectangle(int width, int height) {
  130. this(0, 0, width, height);
  131. }
  132. /**
  133. * Constructs a new <code>Rectangle</code> whose top-left corner is
  134. * specified by the {@link Point} argument, and
  135. * whose width and height are specified by the
  136. * {@link Dimension} argument.
  137. * @param p a <code>Point</code> that is the top-left corner of
  138. * the <code>Rectangle</code>
  139. * @param d a <code>Dimension</code>, representing the
  140. * width and height of the <code>Rectangle</code>
  141. */
  142. public Rectangle(Point p, Dimension d) {
  143. this(p.x, p.y, d.width, d.height);
  144. }
  145. /**
  146. * Constructs a new <code>Rectangle</code> whose top-left corner is the
  147. * specified <code>Point</code>, and whose width and height are both zero.
  148. * @param p a <code>Point</code> that is the top left corner
  149. * of the <code>Rectangle</code>
  150. */
  151. public Rectangle(Point p) {
  152. this(p.x, p.y, 0, 0);
  153. }
  154. /**
  155. * Constructs a new <code>Rectangle</code> whose top left corner is
  156. * (0, 0) and whose width and height are specified
  157. * by the <code>Dimension</code> argument.
  158. * @param d a <code>Dimension</code>, specifying width and height
  159. */
  160. public Rectangle(Dimension d) {
  161. this(0, 0, d.width, d.height);
  162. }
  163. /**
  164. * Returns the X coordinate of the bounding <code>Rectangle</code> in
  165. * <code>double</code> precision.
  166. * @return the x coordinate of the bounding <code>Rectangle</code>.
  167. */
  168. public double getX() {
  169. return x;
  170. }
  171. /**
  172. * Returns the Y coordinate of the bounding <code>Rectangle</code> in
  173. * <code>double</code> precision.
  174. * @return the y coordinate of the bounding <code>Rectangle</code>.
  175. */
  176. public double getY() {
  177. return y;
  178. }
  179. /**
  180. * Returns the width of the bounding <code>Rectangle</code> in
  181. * <code>double</code> precision.
  182. * @return the width of the bounding <code>Rectangle</code>.
  183. */
  184. public double getWidth() {
  185. return width;
  186. }
  187. /**
  188. * Returns the height of the bounding <code>Rectangle</code> in
  189. * <code>double</code> precision.
  190. * @return the height of the bounding <code>Rectangle</code>.
  191. */
  192. public double getHeight() {
  193. return height;
  194. }
  195. /**
  196. * Gets the bounding <code>Rectangle</code> of this <code>Rectangle</code>.
  197. * <p>
  198. * This method is included for completeness, to parallel the
  199. * <code>getBounds</code> method of
  200. * {@link Component}.
  201. * @return a new <code>Rectangle</code>, equal to the
  202. * bounding <code>Rectangle</code> for this <code>Rectangle</code>.
  203. * @see java.awt.Component#getBounds
  204. * @see #setBounds(Rectangle)
  205. * @see #setBounds(int, int, int, int)
  206. * @since JDK1.1
  207. */
  208. public Rectangle getBounds() {
  209. return new Rectangle(x, y, width, height);
  210. }
  211. /**
  212. * Return the high precision bounding box of this rectangle.
  213. * @since 1.2
  214. */
  215. public Rectangle2D getBounds2D() {
  216. return new Rectangle(x, y, width, height);
  217. }
  218. /**
  219. * Sets the bounding <code>Rectangle</code> of this <code>Rectangle</code>
  220. * to match the specified <code>Rectangle</code>.
  221. * <p>
  222. * This method is included for completeness, to parallel the
  223. * <code>setBounds</code> method of <code>Component</code>.
  224. * @param r the specified <code>Rectangle</code>
  225. * @see #getBounds
  226. * @see java.awt.Component#setBounds(java.awt.Rectangle)
  227. * @since JDK1.1
  228. */
  229. public void setBounds(Rectangle r) {
  230. setBounds(r.x, r.y, r.width, r.height);
  231. }
  232. /**
  233. * Sets the bounding <code>Rectangle</code> of this
  234. * <code>Rectangle</code> to the specified
  235. * <code>x</code>, <code>y</code>, <code>width</code>,
  236. * and <code>height</code>.
  237. * <p>
  238. * This method is included for completeness, to parallel the
  239. * <code>setBounds</code> method of <code>Component</code>.
  240. * @param x the new x coordinate for the top-left
  241. * corner of this <code>Rectangle</code>
  242. * @param y the new y coordinate for the top-left
  243. * corner of this <code>Rectangle</code>
  244. * @param width the new width for this <code>Rectangle</code>
  245. * @param height the new height for this <code>Rectangle</code>
  246. * @see #getBounds
  247. * @see java.awt.Component#setBounds(int, int, int, int)
  248. * @since JDK1.1
  249. */
  250. public void setBounds(int x, int y, int width, int height) {
  251. reshape(x, y, width, height);
  252. }
  253. /**
  254. * Sets the bounds of this <code>Rectangle</code> to the specified
  255. * <code>x</code>, <code>y</code>, <code>width</code>,
  256. * and <code>height</code>.
  257. * This method is included for completeness, to parallel the
  258. * <code>setBounds</code> method of <code>Component</code>.
  259. * @param x the x coordinate of the upper-left corner of
  260. * the specified rectangle
  261. * @param y the y coordinate of the upper-left corner of
  262. * the specified rectangle
  263. * @param width the new width for the <code>Dimension</code> object
  264. * @param height the new height for the <code>Dimension</code> object
  265. */
  266. public void setRect(double x, double y, double width, double height) {
  267. int x0 = (int) Math.floor(x);
  268. int y0 = (int) Math.floor(y);
  269. int x1 = (int) Math.ceil(x+width);
  270. int y1 = (int) Math.ceil(y+height);
  271. setBounds(x0, y0, x1-x0, y1-y0);
  272. }
  273. /**
  274. * Sets the bounding <code>Rectangle</code> of this
  275. * <code>Rectangle</code> to the specified
  276. * <code>x</code>, <code>y</code>, <code>width</code>,
  277. * and <code>height</code>.
  278. * <p>
  279. * @param x the new x coordinate for the top-left
  280. * corner of this <code>Rectangle</code>
  281. * @param y the new y coordinate for the top-left
  282. * corner of this <code>Rectangle</code>
  283. * @param width the new width for this <code>Rectangle</code>
  284. * @param height the new height for this <code>Rectangle</code>
  285. * @deprecated As of JDK version 1.1,
  286. * replaced by <code>setBounds(int, int, int, int)</code>.
  287. */
  288. @Deprecated
  289. public void reshape(int x, int y, int width, int height) {
  290. this.x = x;
  291. this.y = y;
  292. this.width = width;
  293. this.height = height;
  294. }
  295. /**
  296. * Returns the location of this <code>Rectangle</code>.
  297. * <p>
  298. * This method is included for completeness, to parallel the
  299. * <code>getLocation</code> method of <code>Component</code>.
  300. * @return the <code>Point</code> that is the top-left corner of
  301. * this <code>Rectangle</code>.
  302. * @see java.awt.Component#getLocation
  303. * @see #setLocation(Point)
  304. * @see #setLocation(int, int)
  305. * @since JDK1.1
  306. */
  307. public Point getLocation() {
  308. return new Point(x, y);
  309. }
  310. /**
  311. * Moves this <code>Rectangle</code> to the specified location.
  312. * <p>
  313. * This method is included for completeness, to parallel the
  314. * <code>setLocation</code> method of <code>Component</code>.
  315. * @param p the <code>Point</code> specifying the new location
  316. * for this <code>Rectangle</code>
  317. * @see java.awt.Component#setLocation(java.awt.Point)
  318. * @see #getLocation
  319. * @since JDK1.1
  320. */
  321. public void setLocation(Point p) {
  322. setLocation(p.x, p.y);
  323. }
  324. /**
  325. * Moves this <code>Rectangle</code> to the specified location.
  326. * <p>
  327. * This method is included for completeness, to parallel the
  328. * <code>setLocation</code> method of <code>Component</code>.
  329. * @param x the x coordinate of the new location
  330. * @param y the y coordinate of the new location
  331. * @see #getLocation
  332. * @see java.awt.Component#setLocation(int, int)
  333. * @since JDK1.1
  334. */
  335. public void setLocation(int x, int y) {
  336. move(x, y);
  337. }
  338. /**
  339. * Moves this <code>Rectangle</code> to the specified location.
  340. * <p>
  341. * @param x the x coordinate of the new location
  342. * @param y the y coordinate of the new location
  343. * @deprecated As of JDK version 1.1,
  344. * replaced by <code>setLocation(int, int)</code>.
  345. */
  346. @Deprecated
  347. public void move(int x, int y) {
  348. this.x = x;
  349. this.y = y;
  350. }
  351. /**
  352. * Translates this <code>Rectangle</code> the indicated distance,
  353. * to the right along the x coordinate axis, and
  354. * downward along the y coordinate axis.
  355. * @param x the distance to move this <code>Rectangle</code>
  356. * along the x axis
  357. * @param y the distance to move this <code>Rectangle</code>
  358. * along the y axis
  359. * @see java.awt.Rectangle#setLocation(int, int)
  360. * @see java.awt.Rectangle#setLocation(java.awt.Point)
  361. */
  362. public void translate(int x, int y) {
  363. this.x += x;
  364. this.y += y;
  365. }
  366. /**
  367. * Gets the size of this <code>Rectangle</code>, represented by
  368. * the returned <code>Dimension</code>.
  369. * <p>
  370. * This method is included for completeness, to parallel the
  371. * <code>getSize</code> method of <code>Component</code>.
  372. * @return a <code>Dimension</code>, representing the size of
  373. * this <code>Rectangle</code>.
  374. * @see java.awt.Component#getSize
  375. * @see #setSize(Dimension)
  376. * @see #setSize(int, int)
  377. * @since JDK1.1
  378. */
  379. public Dimension getSize() {
  380. return new Dimension(width, height);
  381. }
  382. /**
  383. * Sets the size of this <code>Rectangle</code> to match the
  384. * specified <code>Dimension</code>.
  385. * <p>
  386. * This method is included for completeness, to parallel the
  387. * <code>setSize</code> method of <code>Component</code>.
  388. * @param d the new size for the <code>Dimension</code> object
  389. * @see java.awt.Component#setSize(java.awt.Dimension)
  390. * @see #getSize
  391. * @since JDK1.1
  392. */
  393. public void setSize(Dimension d) {
  394. setSize(d.width, d.height);
  395. }
  396. /**
  397. * Sets the size of this <code>Rectangle</code> to the specified
  398. * width and height.
  399. * <p>
  400. * This method is included for completeness, to parallel the
  401. * <code>setSize</code> method of <code>Component</code>.
  402. * @param width the new width for this <code>Rectangle</code>
  403. * @param height the new height for this <code>Rectangle</code>
  404. * @see java.awt.Component#setSize(int, int)
  405. * @see #getSize
  406. * @since JDK1.1
  407. */
  408. public void setSize(int width, int height) {
  409. resize(width, height);
  410. }
  411. /**
  412. * Sets the size of this <code>Rectangle</code> to the specified
  413. * width and height.
  414. * <p>
  415. * @param width the new width for this <code>Rectangle</code>
  416. * @param height the new height for this <code>Rectangle</code>
  417. * @deprecated As of JDK version 1.1,
  418. * replaced by <code>setSize(int, int)</code>.
  419. */
  420. @Deprecated
  421. public void resize(int width, int height) {
  422. this.width = width;
  423. this.height = height;
  424. }
  425. /**
  426. * Checks whether or not this <code>Rectangle</code> contains the
  427. * specified <code>Point</code>.
  428. * @param p the <code>Point</code> to test
  429. * @return <code>true</code> if the <code>Point</code>
  430. * (<i>x</i>, <i>y</i>) is inside this
  431. * <code>Rectangle</code>
  432. * <code>false</code> otherwise.
  433. * @since JDK1.1
  434. */
  435. public boolean contains(Point p) {
  436. return contains(p.x, p.y);
  437. }
  438. /**
  439. * Checks whether or not this <code>Rectangle</code> contains the
  440. * point at the specified location
  441. * (<i>x</i>, <i>y</i>).
  442. * @param x the specified x coordinate
  443. * @param y the specified y coordinate
  444. * @return <code>true</code> if the point
  445. * (<i>x</i>, <i>y</i>) is inside this
  446. * <code>Rectangle</code>
  447. * <code>false</code> otherwise.
  448. * @since JDK1.1
  449. */
  450. public boolean contains(int x, int y) {
  451. return inside(x, y);
  452. }
  453. /**
  454. * Checks whether or not this <code>Rectangle</code> entirely contains
  455. * the specified <code>Rectangle</code>.
  456. *
  457. * @param r the specified <code>Rectangle</code>
  458. * @return <code>true</code> if the <code>Rectangle</code>
  459. * is contained entirely inside this <code>Rectangle</code>
  460. * <code>false</code> otherwise
  461. * @since JDK1.2
  462. */
  463. public boolean contains(Rectangle r) {
  464. return contains(r.x, r.y, r.width, r.height);
  465. }
  466. /**
  467. * Checks whether this <code>Rectangle</code> entirely contains
  468. * the <code>Rectangle</code>
  469. * at the specified location (<i>X</i>, <i>Y</i>) with the
  470. * specified dimensions (<i>W</i>, <i>H</i>).
  471. * @param X the specified x coordinate
  472. * @param Y the specified y coordinate
  473. * @param W the width of the <code>Rectangle</code>
  474. * @param H the height of the <code>Rectangle</code>
  475. * @return <code>true</code> if the <code>Rectangle</code> specified by
  476. * (<i>X</i>, <i>Y</i>, <i>W</i>, <i>H</i>)
  477. * is entirely enclosed inside this <code>Rectangle</code>
  478. * <code>false</code> otherwise.
  479. * @since JDK1.1
  480. */
  481. public boolean contains(int X, int Y, int W, int H) {
  482. int w = this.width;
  483. int h = this.height;
  484. if ((w | h | W | H) < 0) {
  485. // At least one of the dimensions is negative...
  486. return false;
  487. }
  488. // Note: if any dimension is zero, tests below must return false...
  489. int x = this.x;
  490. int y = this.y;
  491. if (X < x || Y < y) {
  492. return false;
  493. }
  494. w += x;
  495. W += X;
  496. if (W <= X) {
  497. // X+W overflowed or W was zero, return false if...
  498. // either original w or W was zero or
  499. // x+w did not overflow or
  500. // the overflowed x+w is smaller than the overflowed X+W
  501. if (w >= x || W > w) return false;
  502. } else {
  503. // X+W did not overflow and W was not zero, return false if...
  504. // original w was zero or
  505. // x+w did not overflow and x+w is smaller than X+W
  506. if (w >= x && W > w) return false;
  507. }
  508. h += y;
  509. H += Y;
  510. if (H <= Y) {
  511. if (h >= y || H > h) return false;
  512. } else {
  513. if (h >= y && H > h) return false;
  514. }
  515. return true;
  516. }
  517. /**
  518. * Checks whether or not this <code>Rectangle</code> contains the
  519. * point at the specified location
  520. * (<i>X</i>, <i>Y</i>).
  521. * @param X the specified x coordinate
  522. * @param Y the specified y coordinate
  523. * @return <code>true</code> if the point
  524. * (<i>X</i>, <i>Y</i>) is inside this
  525. * <code>Rectangle</code>
  526. * <code>false</code> otherwise.
  527. * @deprecated As of JDK version 1.1,
  528. * replaced by <code>contains(int, int)</code>.
  529. */
  530. @Deprecated
  531. public boolean inside(int X, int Y) {
  532. int w = this.width;
  533. int h = this.height;
  534. if ((w | h) < 0) {
  535. // At least one of the dimensions is negative...
  536. return false;
  537. }
  538. // Note: if either dimension is zero, tests below must return false...
  539. int x = this.x;
  540. int y = this.y;
  541. if (X < x || Y < y) {
  542. return false;
  543. }
  544. w += x;
  545. h += y;
  546. // overflow || intersect
  547. return ((w < x || w > X) &&
  548. (h < y || h > Y));
  549. }
  550. /**
  551. * Determines whether or not this <code>Rectangle</code> and the specified
  552. * <code>Rectangle</code> intersect. Two rectangles intersect if
  553. * their intersection is nonempty.
  554. *
  555. * @param r the specified <code>Rectangle</code>
  556. * @return <code>true</code> if the specified <code>Rectangle</code>
  557. * and this <code>Rectangle</code> intersect;
  558. * <code>false</code> otherwise.
  559. */
  560. public boolean intersects(Rectangle r) {
  561. int tw = this.width;
  562. int th = this.height;
  563. int rw = r.width;
  564. int rh = r.height;
  565. if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
  566. return false;
  567. }
  568. int tx = this.x;
  569. int ty = this.y;
  570. int rx = r.x;
  571. int ry = r.y;
  572. rw += rx;
  573. rh += ry;
  574. tw += tx;
  575. th += ty;
  576. // overflow || intersect
  577. return ((rw < rx || rw > tx) &&
  578. (rh < ry || rh > ty) &&
  579. (tw < tx || tw > rx) &&
  580. (th < ty || th > ry));
  581. }
  582. /**
  583. * Computes the intersection of this <code>Rectangle</code> with the
  584. * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
  585. * that represents the intersection of the two rectangles.
  586. * If the two rectangles do not intersect, the result will be
  587. * an empty rectangle.
  588. *
  589. * @param r the specified <code>Rectangle</code>
  590. * @return the largest <code>Rectangle</code> contained in both the
  591. * specified <code>Rectangle</code> and in
  592. * this <code>Rectangle</code> or if the rectangles
  593. * do not intersect, an empty rectangle.
  594. */
  595. public Rectangle intersection(Rectangle r) {
  596. int tx1 = this.x;
  597. int ty1 = this.y;
  598. int rx1 = r.x;
  599. int ry1 = r.y;
  600. long tx2 = tx1; tx2 += this.width;
  601. long ty2 = ty1; ty2 += this.height;
  602. long rx2 = rx1; rx2 += r.width;
  603. long ry2 = ry1; ry2 += r.height;
  604. if (tx1 < rx1) tx1 = rx1;
  605. if (ty1 < ry1) ty1 = ry1;
  606. if (tx2 > rx2) tx2 = rx2;
  607. if (ty2 > ry2) ty2 = ry2;
  608. tx2 -= tx1;
  609. ty2 -= ty1;
  610. // tx2,ty2 will never overflow (they will never be
  611. // larger than the smallest of the two source w,h)
  612. // they might underflow, though...
  613. if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
  614. if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
  615. return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
  616. }
  617. /**
  618. * Computes the union of this <code>Rectangle</code> with the
  619. * specified <code>Rectangle</code>. Returns a new
  620. * <code>Rectangle</code> that
  621. * represents the union of the two rectangles
  622. * @param r the specified <code>Rectangle</code>
  623. * @return the smallest <code>Rectangle</code> containing both
  624. * the specified <code>Rectangle</code> and this
  625. * <code>Rectangle</code>.
  626. */
  627. public Rectangle union(Rectangle r) {
  628. int x1 = Math.min(x, r.x);
  629. int x2 = Math.max(x + width, r.x + r.width);
  630. int y1 = Math.min(y, r.y);
  631. int y2 = Math.max(y + height, r.y + r.height);
  632. return new Rectangle(x1, y1, x2 - x1, y2 - y1);
  633. }
  634. /**
  635. * Adds a point, specified by the integer arguments <code>newx</code>
  636. * and <code>newy</code>, to this <code>Rectangle</code>. The
  637. * resulting <code>Rectangle</code> is
  638. * the smallest <code>Rectangle</code> that contains both the
  639. * original <code>Rectangle</code> and the specified point.
  640. * <p>
  641. * After adding a point, a call to <code>contains</code> with the
  642. * added point as an argument does not necessarily return
  643. * <code>true</code>. The <code>contains</code> method does not
  644. * return <code>true</code> for points on the right or bottom
  645. * edges of a <code>Rectangle</code>. Therefore, if the added point
  646. * falls on the right or bottom edge of the enlarged
  647. * <code>Rectangle</code>, <code>contains</code> returns
  648. * <code>false</code> for that point.
  649. * @param newx the x coordinate of the new point
  650. * @param newy the y coordinate of the new point
  651. */
  652. public void add(int newx, int newy) {
  653. int x1 = Math.min(x, newx);
  654. int x2 = Math.max(x + width, newx);
  655. int y1 = Math.min(y, newy);
  656. int y2 = Math.max(y + height, newy);
  657. x = x1;
  658. y = y1;
  659. width = x2 - x1;
  660. height = y2 - y1;
  661. }
  662. /**
  663. * Adds the specified <code>Point</code> to this
  664. * <code>Rectangle</code>. The resulting <code>Rectangle</code>
  665. * is the smallest <code>Rectangle</code> that contains both the
  666. * original <code>Rectangle</code> and the specified
  667. * <code>Point</code>.
  668. * <p>
  669. * After adding a <code>Point</code>, a call to <code>contains</code>
  670. * with the added <code>Point</code> as an argument does not
  671. * necessarily return <code>true</code>. The <code>contains</code>
  672. * method does not return <code>true</code> for points on the right
  673. * or bottom edges of a <code>Rectangle</code>. Therefore if the added
  674. * <code>Point</code> falls on the right or bottom edge of the
  675. * enlarged <code>Rectangle</code>, <code>contains</code> returns
  676. * <code>false</code> for that <code>Point</code>.
  677. * @param pt the new <code>Point</code> to add to this
  678. * <code>Rectangle</code>
  679. */
  680. public void add(Point pt) {
  681. add(pt.x, pt.y);
  682. }
  683. /**
  684. * Adds a <code>Rectangle</code> to this <code>Rectangle</code>.
  685. * The resulting <code>Rectangle</code> is the union of the two
  686. * rectangles.
  687. * @param r the specified <code>Rectangle</code>
  688. */
  689. public void add(Rectangle r) {
  690. int x1 = Math.min(x, r.x);
  691. int x2 = Math.max(x + width, r.x + r.width);
  692. int y1 = Math.min(y, r.y);
  693. int y2 = Math.max(y + height, r.y + r.height);
  694. x = x1;
  695. y = y1;
  696. width = x2 - x1;
  697. height = y2 - y1;
  698. }
  699. /**
  700. * Resizes the <code>Rectangle</code> both horizontally and vertically.
  701. * <p>
  702. * This method modifies the <code>Rectangle</code> so that it is
  703. * <code>h</code> units larger on both the left and right side,
  704. * and <code>v</code> units larger at both the top and bottom.
  705. * <p>
  706. * The new <code>Rectangle</code> has (<code>x - h</code>,
  707. * <code>y - v</code>) as its top-left corner, a
  708. * width of
  709. * <code>width</code> <code>+</code> <code>2h</code>,
  710. * and a height of
  711. * <code>height</code> <code>+</code> <code>2v</code>.
  712. * <p>
  713. * If negative values are supplied for <code>h</code> and
  714. * <code>v</code>, the size of the <code>Rectangle</code>
  715. * decreases accordingly.
  716. * The <code>grow</code> method does not check whether the resulting
  717. * values of <code>width</code> and <code>height</code> are
  718. * non-negative.
  719. * @param h the horizontal expansion
  720. * @param v the vertical expansion
  721. */
  722. public void grow(int h, int v) {
  723. x -= h;
  724. y -= v;
  725. width += h * 2;
  726. height += v * 2;
  727. }
  728. /**
  729. * Determines whether or not this <code>Rectangle</code> is empty. A
  730. * <code>Rectangle</code> is empty if its width or its height is less
  731. * than or equal to zero.
  732. * @return <code>true</code> if this <code>Rectangle</code> is empty;
  733. * <code>false</code> otherwise.
  734. */
  735. public boolean isEmpty() {
  736. return (width <= 0) || (height <= 0);
  737. }
  738. /**
  739. * Determines where the specified coordinates lie with respect
  740. * to this <code>Rectangle</code>.
  741. * This method computes a binary OR of the appropriate mask values
  742. * indicating, for each side of this <code>Rectangle</code>,
  743. * whether or not the specified coordinates are on the same side of the
  744. * edge as the rest of this <code>Rectangle</code>.
  745. * @param x the specified x coordinate
  746. * @param y the specified y coordinate
  747. * @return the logical OR of all appropriate out codes.
  748. * @see #OUT_LEFT
  749. * @see #OUT_TOP
  750. * @see #OUT_RIGHT
  751. * @see #OUT_BOTTOM
  752. * @since 1.2
  753. */
  754. public int outcode(double x, double y) {
  755. /*
  756. * Note on casts to double below. If the arithmetic of
  757. * x+w or y+h is done in int, then we may get integer
  758. * overflow. By converting to double before the addition
  759. * we force the addition to be carried out in double to
  760. * avoid overflow in the comparison.
  761. *
  762. * See bug 4320890 for problems that this can cause.
  763. */
  764. int out = 0;
  765. if (this.width <= 0) {
  766. out |= OUT_LEFT | OUT_RIGHT;
  767. } else if (x < this.x) {
  768. out |= OUT_LEFT;
  769. } else if (x > this.x + (double) this.width) {
  770. out |= OUT_RIGHT;
  771. }
  772. if (this.height <= 0) {
  773. out |= OUT_TOP | OUT_BOTTOM;
  774. } else if (y < this.y) {
  775. out |= OUT_TOP;
  776. } else if (y > this.y + (double) this.height) {
  777. out |= OUT_BOTTOM;
  778. }
  779. return out;
  780. }
  781. /**
  782. * Returns a new {@link Rectangle2D} object
  783. * representing the intersection of this <code>Rectangle</code> with the
  784. * specified <code>Rectangle2D</code>.
  785. * @param r the <code>Rectangle2D</code> to be intersected
  786. * with this <code>Rectangle</code>
  787. * @return the largest <code>Rectangle2D</code> contained in both the
  788. * specified <code>Rectangle2D</code> and in
  789. * this <code>Rectangle</code>.
  790. * @since 1.2
  791. */
  792. public Rectangle2D createIntersection(Rectangle2D r) {
  793. if (r instanceof Rectangle) {
  794. return intersection((Rectangle) r);
  795. }
  796. Rectangle2D dest = new Rectangle2D.Double();
  797. Rectangle2D.intersect(this, r, dest);
  798. return dest;
  799. }
  800. /**
  801. * Returns a new <code>Rectangle2D</code> object representing the
  802. * union of this <code>Rectangle</code> with the specified
  803. * <code>Rectangle2D</code>.
  804. * @param r the <code>Rectangle2D</code> to be combined with
  805. * this <code>Rectangle</code>
  806. * @return the smallest <code>Rectangle2D</code> containing
  807. * both the specified <code>Rectangle2D</code> and this
  808. * <code>Rectangle</code>.
  809. * @since 1.2
  810. */
  811. public Rectangle2D createUnion(Rectangle2D r) {
  812. if (r instanceof Rectangle) {
  813. return union((Rectangle) r);
  814. }
  815. Rectangle2D dest = new Rectangle2D.Double();
  816. Rectangle2D.union(this, r, dest);
  817. return dest;
  818. }
  819. /**
  820. * Checks whether two rectangles are equal.
  821. * <p>
  822. * The result is <code>true</code> if and only if the argument is not
  823. * <code>null</code> and is a <code>Rectangle</code> object that has the
  824. * same top-left corner, width, and height as this <code>Rectangle</code>.
  825. * @param obj the <code>Object</code> to compare with
  826. * this <code>Rectangle</code>
  827. * @return <code>true</code> if the objects are equal;
  828. * <code>false</code> otherwise.
  829. */
  830. public boolean equals(Object obj) {
  831. if (obj instanceof Rectangle) {
  832. Rectangle r = (Rectangle)obj;
  833. return ((x == r.x) &&
  834. (y == r.y) &&
  835. (width == r.width) &&
  836. (height == r.height));
  837. }
  838. return super.equals(obj);
  839. }
  840. /**
  841. * Returns a <code>String</code> representing this
  842. * <code>Rectangle</code> and its values.
  843. * @return a <code>String</code> representing this
  844. * <code>Rectangle</code> object's coordinate and size values.
  845. */
  846. public String toString() {
  847. return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]";
  848. }
  849. }