1. /*
  2. * @(#)Rectangle.java 1.65 03/01/23
  3. *
  4. * Copyright 2003 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.65, 01/23/03
  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. public void reshape(int x, int y, int width, int height) {
  289. this.x = x;
  290. this.y = y;
  291. this.width = width;
  292. this.height = height;
  293. }
  294. /**
  295. * Returns the location of this <code>Rectangle</code>.
  296. * <p>
  297. * This method is included for completeness, to parallel the
  298. * <code>getLocation</code> method of <code>Component</code>.
  299. * @return the <code>Point</code> that is the top-left corner of
  300. * this <code>Rectangle</code>.
  301. * @see java.awt.Component#getLocation
  302. * @see #setLocation(Point)
  303. * @see #setLocation(int, int)
  304. * @since JDK1.1
  305. */
  306. public Point getLocation() {
  307. return new Point(x, y);
  308. }
  309. /**
  310. * Moves this <code>Rectangle</code> to the specified location.
  311. * <p>
  312. * This method is included for completeness, to parallel the
  313. * <code>setLocation</code> method of <code>Component</code>.
  314. * @param p the <code>Point</code> specifying the new location
  315. * for this <code>Rectangle</code>
  316. * @see java.awt.Component#setLocation(java.awt.Point)
  317. * @see #getLocation
  318. * @since JDK1.1
  319. */
  320. public void setLocation(Point p) {
  321. setLocation(p.x, p.y);
  322. }
  323. /**
  324. * Moves this <code>Rectangle</code> to the specified location.
  325. * <p>
  326. * This method is included for completeness, to parallel the
  327. * <code>setLocation</code> method of <code>Component</code>.
  328. * @param x the x coordinate of the new location
  329. * @param y the y coordinate of the new location
  330. * @see #getLocation
  331. * @see java.awt.Component#setLocation(int, int)
  332. * @since JDK1.1
  333. */
  334. public void setLocation(int x, int y) {
  335. move(x, y);
  336. }
  337. /**
  338. * Moves this <code>Rectangle</code> to the specified location.
  339. * <p>
  340. * @param x the x coordinate of the new location
  341. * @param y the y coordinate of the new location
  342. * @deprecated As of JDK version 1.1,
  343. * replaced by <code>setLocation(int, int)</code>.
  344. */
  345. public void move(int x, int y) {
  346. this.x = x;
  347. this.y = y;
  348. }
  349. /**
  350. * Translates this <code>Rectangle</code> the indicated distance,
  351. * to the right along the x coordinate axis, and
  352. * downward along the y coordinate axis.
  353. * @param x the distance to move this <code>Rectangle</code>
  354. * along the x axis
  355. * @param y the distance to move this <code>Rectangle</code>
  356. * along the y axis
  357. * @see java.awt.Rectangle#setLocation(int, int)
  358. * @see java.awt.Rectangle#setLocation(java.awt.Point)
  359. */
  360. public void translate(int x, int y) {
  361. this.x += x;
  362. this.y += y;
  363. }
  364. /**
  365. * Gets the size of this <code>Rectangle</code>, represented by
  366. * the returned <code>Dimension</code>.
  367. * <p>
  368. * This method is included for completeness, to parallel the
  369. * <code>getSize</code> method of <code>Component</code>.
  370. * @return a <code>Dimension</code>, representing the size of
  371. * this <code>Rectangle</code>.
  372. * @see java.awt.Component#getSize
  373. * @see #setSize(Dimension)
  374. * @see #setSize(int, int)
  375. * @since JDK1.1
  376. */
  377. public Dimension getSize() {
  378. return new Dimension(width, height);
  379. }
  380. /**
  381. * Sets the size of this <code>Rectangle</code> to match the
  382. * specified <code>Dimension</code>.
  383. * <p>
  384. * This method is included for completeness, to parallel the
  385. * <code>setSize</code> method of <code>Component</code>.
  386. * @param d the new size for the <code>Dimension</code> object
  387. * @see java.awt.Component#setSize(java.awt.Dimension)
  388. * @see #getSize
  389. * @since JDK1.1
  390. */
  391. public void setSize(Dimension d) {
  392. setSize(d.width, d.height);
  393. }
  394. /**
  395. * Sets the size of this <code>Rectangle</code> to the specified
  396. * width and height.
  397. * <p>
  398. * This method is included for completeness, to parallel the
  399. * <code>setSize</code> method of <code>Component</code>.
  400. * @param width the new width for this <code>Rectangle</code>
  401. * @param height the new height for this <code>Rectangle</code>
  402. * @see java.awt.Component#setSize(int, int)
  403. * @see #getSize
  404. * @since JDK1.1
  405. */
  406. public void setSize(int width, int height) {
  407. resize(width, height);
  408. }
  409. /**
  410. * Sets the size of this <code>Rectangle</code> to the specified
  411. * width and height.
  412. * <p>
  413. * @param width the new width for this <code>Rectangle</code>
  414. * @param height the new height for this <code>Rectangle</code>
  415. * @deprecated As of JDK version 1.1,
  416. * replaced by <code>setSize(int, int)</code>.
  417. */
  418. public void resize(int width, int height) {
  419. this.width = width;
  420. this.height = height;
  421. }
  422. /**
  423. * Checks whether or not this <code>Rectangle</code> contains the
  424. * specified <code>Point</code>.
  425. * @param p the <code>Point</code> to test
  426. * @return <code>true</code> if the <code>Point</code>
  427. * (<i>x</i>, <i>y</i>) is inside this
  428. * <code>Rectangle</code>
  429. * <code>false</code> otherwise.
  430. * @since JDK1.1
  431. */
  432. public boolean contains(Point p) {
  433. return contains(p.x, p.y);
  434. }
  435. /**
  436. * Checks whether or not this <code>Rectangle</code> contains the
  437. * point at the specified location
  438. * (<i>x</i>, <i>y</i>).
  439. * @param x the specified x coordinate
  440. * @param y the specified y coordinate
  441. * @return <code>true</code> if the point
  442. * (<i>x</i>, <i>y</i>) is inside this
  443. * <code>Rectangle</code>
  444. * <code>false</code> otherwise.
  445. * @since JDK1.1
  446. */
  447. public boolean contains(int x, int y) {
  448. return inside(x, y);
  449. }
  450. /**
  451. * Checks whether or not this <code>Rectangle</code> entirely contains
  452. * the specified <code>Rectangle</code>.
  453. * @param r the specified <code>Rectangle</code>
  454. * @return <code>true</code> if the <code>Rectangle</code>
  455. * is contained entirely inside this <code>Rectangle</code>
  456. * <code>false</code> otherwise.
  457. * @since JDK1.1
  458. */
  459. public boolean contains(Rectangle r) {
  460. return contains(r.x, r.y, r.width, r.height);
  461. }
  462. /**
  463. * Checks whether this <code>Rectangle</code> entirely contains
  464. * the <code>Rectangle</code>
  465. * at the specified location (<i>X</i>, <i>Y</i>) with the
  466. * specified dimensions (<i>W</i>, <i>H</i>).
  467. * @param X the specified x coordinate
  468. * @param Y the specified y coordinate
  469. * @param W the width of the <code>Rectangle</code>
  470. * @param H the height of the <code>Rectangle</code>
  471. * @return <code>true</code> if the <code>Rectangle</code> specified by
  472. * (<i>X</i>, <i>Y</i>, <i>W</i>, <i>H</i>)
  473. * is entirely enclosed inside this <code>Rectangle</code>
  474. * <code>false</code> otherwise.
  475. * @since JDK1.1
  476. */
  477. public boolean contains(int X, int Y, int W, int H) {
  478. int w = this.width;
  479. int h = this.height;
  480. if ((w | h | W | H) < 0) {
  481. // At least one of the dimensions is negative...
  482. return false;
  483. }
  484. // Note: if any dimension is zero, tests below must return false...
  485. int x = this.x;
  486. int y = this.y;
  487. if (X < x || Y < y) {
  488. return false;
  489. }
  490. w += x;
  491. W += X;
  492. if (W <= X) {
  493. // X+W overflowed or W was zero, return false if...
  494. // either original w or W was zero or
  495. // x+w did not overflow or
  496. // the overflowed x+w is smaller than the overflowed X+W
  497. if (w >= x || W > w) return false;
  498. } else {
  499. // X+W did not overflow and W was not zero, return false if...
  500. // original w was zero or
  501. // x+w did not overflow and x+w is smaller than X+W
  502. if (w >= x && W > w) return false;
  503. }
  504. h += y;
  505. H += Y;
  506. if (H <= Y) {
  507. if (h >= y || H > h) return false;
  508. } else {
  509. if (h >= y && H > h) return false;
  510. }
  511. return true;
  512. }
  513. /**
  514. * Checks whether or not this <code>Rectangle</code> contains the
  515. * point at the specified location
  516. * (<i>X</i>, <i>Y</i>).
  517. * @param X the specified x coordinate
  518. * @param Y the specified y coordinate
  519. * @return <code>true</code> if the point
  520. * (<i>X</i>, <i>Y</i>) is inside this
  521. * <code>Rectangle</code>
  522. * <code>false</code> otherwise.
  523. * @deprecated As of JDK version 1.1,
  524. * replaced by <code>contains(int, int)</code>.
  525. */
  526. public boolean inside(int X, int Y) {
  527. int w = this.width;
  528. int h = this.height;
  529. if ((w | h) < 0) {
  530. // At least one of the dimensions is negative...
  531. return false;
  532. }
  533. // Note: if either dimension is zero, tests below must return false...
  534. int x = this.x;
  535. int y = this.y;
  536. if (X < x || Y < y) {
  537. return false;
  538. }
  539. w += x;
  540. h += y;
  541. // overflow || intersect
  542. return ((w < x || w > X) &&
  543. (h < y || h > Y));
  544. }
  545. /**
  546. * Determines whether or not this <code>Rectangle</code> and the specified
  547. * <code>Rectangle</code> intersect. Two rectangles intersect if
  548. * their intersection is nonempty.
  549. *
  550. * @param r the specified <code>Rectangle</code>
  551. * @return <code>true</code> if the specified <code>Rectangle</code>
  552. * and this <code>Rectangle</code> intersect;
  553. * <code>false</code> otherwise.
  554. */
  555. public boolean intersects(Rectangle r) {
  556. int tw = this.width;
  557. int th = this.height;
  558. int rw = r.width;
  559. int rh = r.height;
  560. if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
  561. return false;
  562. }
  563. int tx = this.x;
  564. int ty = this.y;
  565. int rx = r.x;
  566. int ry = r.y;
  567. rw += rx;
  568. rh += ry;
  569. tw += tx;
  570. th += ty;
  571. // overflow || intersect
  572. return ((rw < rx || rw > tx) &&
  573. (rh < ry || rh > ty) &&
  574. (tw < tx || tw > rx) &&
  575. (th < ty || th > ry));
  576. }
  577. /**
  578. * Computes the intersection of this <code>Rectangle</code> with the
  579. * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
  580. * that represents the intersection of the two rectangles.
  581. * If the two rectangles do not intersect, the result will be
  582. * an empty rectangle.
  583. *
  584. * @param r the specified <code>Rectangle</code>
  585. * @return the largest <code>Rectangle</code> contained in both the
  586. * specified <code>Rectangle</code> and in
  587. * this <code>Rectangle</code> or if the rectangles
  588. * do not intersect, an empty rectangle.
  589. */
  590. public Rectangle intersection(Rectangle r) {
  591. int tx1 = this.x;
  592. int ty1 = this.y;
  593. int rx1 = r.x;
  594. int ry1 = r.y;
  595. long tx2 = tx1; tx2 += this.width;
  596. long ty2 = ty1; ty2 += this.height;
  597. long rx2 = rx1; rx2 += r.width;
  598. long ry2 = ry1; ry2 += r.height;
  599. if (tx1 < rx1) tx1 = rx1;
  600. if (ty1 < ry1) ty1 = ry1;
  601. if (tx2 > rx2) tx2 = rx2;
  602. if (ty2 > ry2) ty2 = ry2;
  603. tx2 -= tx1;
  604. ty2 -= ty1;
  605. // tx2,ty2 will never overflow (they will never be
  606. // larger than the smallest of the two source w,h)
  607. // they might underflow, though...
  608. if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
  609. if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
  610. return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
  611. }
  612. /**
  613. * Computes the union of this <code>Rectangle</code> with the
  614. * specified <code>Rectangle</code>. Returns a new
  615. * <code>Rectangle</code> that
  616. * represents the union of the two rectangles
  617. * @param r the specified <code>Rectangle</code>
  618. * @return the smallest <code>Rectangle</code> containing both
  619. * the specified <code>Rectangle</code> and this
  620. * <code>Rectangle</code>.
  621. */
  622. public Rectangle union(Rectangle r) {
  623. int x1 = Math.min(x, r.x);
  624. int x2 = Math.max(x + width, r.x + r.width);
  625. int y1 = Math.min(y, r.y);
  626. int y2 = Math.max(y + height, r.y + r.height);
  627. return new Rectangle(x1, y1, x2 - x1, y2 - y1);
  628. }
  629. /**
  630. * Adds a point, specified by the integer arguments <code>newx</code>
  631. * and <code>newy</code>, to this <code>Rectangle</code>. The
  632. * resulting <code>Rectangle</code> is
  633. * the smallest <code>Rectangle</code> that contains both the
  634. * original <code>Rectangle</code> and the specified point.
  635. * <p>
  636. * After adding a point, a call to <code>contains</code> with the
  637. * added point as an argument does not necessarily return
  638. * <code>true</code>. The <code>contains</code> method does not
  639. * return <code>true</code> for points on the right or bottom
  640. * edges of a <code>Rectangle</code>. Therefore, if the added point
  641. * falls on the right or bottom edge of the enlarged
  642. * <code>Rectangle</code>, <code>contains</code> returns
  643. * <code>false</code> for that point.
  644. * @param newx the x coordinate of the new point
  645. * @param newy the y coordinate of the new point
  646. */
  647. public void add(int newx, int newy) {
  648. int x1 = Math.min(x, newx);
  649. int x2 = Math.max(x + width, newx);
  650. int y1 = Math.min(y, newy);
  651. int y2 = Math.max(y + height, newy);
  652. x = x1;
  653. y = y1;
  654. width = x2 - x1;
  655. height = y2 - y1;
  656. }
  657. /**
  658. * Adds the specified <code>Point</code> to this
  659. * <code>Rectangle</code>. The resulting <code>Rectangle</code>
  660. * is the smallest <code>Rectangle</code> that contains both the
  661. * original <code>Rectangle</code> and the specified
  662. * <code>Point</code>.
  663. * <p>
  664. * After adding a <code>Point</code>, a call to <code>contains</code>
  665. * with the added <code>Point</code> as an argument does not
  666. * necessarily return <code>true</code>. The <code>contains</code>
  667. * method does not return <code>true</code> for points on the right
  668. * or bottom edges of a <code>Rectangle</code>. Therefore if the added
  669. * <code>Point</code> falls on the right or bottom edge of the
  670. * enlarged <code>Rectangle</code>, <code>contains</code> returns
  671. * <code>false</code> for that <code>Point</code>.
  672. * @param pt the new <code>Point</code> to add to this
  673. * <code>Rectangle</code>
  674. */
  675. public void add(Point pt) {
  676. add(pt.x, pt.y);
  677. }
  678. /**
  679. * Adds a <code>Rectangle</code> to this <code>Rectangle</code>.
  680. * The resulting <code>Rectangle</code> is the union of the two
  681. * rectangles.
  682. * @param r the specified <code>Rectangle</code>
  683. */
  684. public void add(Rectangle r) {
  685. int x1 = Math.min(x, r.x);
  686. int x2 = Math.max(x + width, r.x + r.width);
  687. int y1 = Math.min(y, r.y);
  688. int y2 = Math.max(y + height, r.y + r.height);
  689. x = x1;
  690. y = y1;
  691. width = x2 - x1;
  692. height = y2 - y1;
  693. }
  694. /**
  695. * Resizes the <code>Rectangle</code> both horizontally and vertically.
  696. * <p>
  697. * This method modifies the <code>Rectangle</code> so that it is
  698. * <code>h</code> units larger on both the left and right side,
  699. * and <code>v</code> units larger at both the top and bottom.
  700. * <p>
  701. * The new <code>Rectangle</code> has (<code>x - h</code>,
  702. * <code>y - v</code>) as its top-left corner, a
  703. * width of
  704. * <code>width</code> <code>+</code> <code>2h</code>,
  705. * and a height of
  706. * <code>height</code> <code>+</code> <code>2v</code>.
  707. * <p>
  708. * If negative values are supplied for <code>h</code> and
  709. * <code>v</code>, the size of the <code>Rectangle</code>
  710. * decreases accordingly.
  711. * The <code>grow</code> method does not check whether the resulting
  712. * values of <code>width</code> and <code>height</code> are
  713. * non-negative.
  714. * @param h the horizontal expansion
  715. * @param v the vertical expansion
  716. */
  717. public void grow(int h, int v) {
  718. x -= h;
  719. y -= v;
  720. width += h * 2;
  721. height += v * 2;
  722. }
  723. /**
  724. * Determines whether or not this <code>Rectangle</code> is empty. A
  725. * <code>Rectangle</code> is empty if its width or its height is less
  726. * than or equal to zero.
  727. * @return <code>true</code> if this <code>Rectangle</code> is empty;
  728. * <code>false</code> otherwise.
  729. */
  730. public boolean isEmpty() {
  731. return (width <= 0) || (height <= 0);
  732. }
  733. /**
  734. * Determines where the specified coordinates lie with respect
  735. * to this <code>Rectangle</code>.
  736. * This method computes a binary OR of the appropriate mask values
  737. * indicating, for each side of this <code>Rectangle</code>,
  738. * whether or not the specified coordinates are on the same side of the
  739. * edge as the rest of this <code>Rectangle</code>.
  740. * @param x the specified x coordinate
  741. * @param y the specified y coordinate
  742. * @return the logical OR of all appropriate out codes.
  743. * @see #OUT_LEFT
  744. * @see #OUT_TOP
  745. * @see #OUT_RIGHT
  746. * @see #OUT_BOTTOM
  747. * @since 1.2
  748. */
  749. public int outcode(double x, double y) {
  750. /*
  751. * Note on casts to double below. If the arithmetic of
  752. * x+w or y+h is done in int, then we may get integer
  753. * overflow. By converting to double before the addition
  754. * we force the addition to be carried out in double to
  755. * avoid overflow in the comparison.
  756. *
  757. * See bug 4320890 for problems that this can cause.
  758. */
  759. int out = 0;
  760. if (this.width <= 0) {
  761. out |= OUT_LEFT | OUT_RIGHT;
  762. } else if (x < this.x) {
  763. out |= OUT_LEFT;
  764. } else if (x > this.x + (double) this.width) {
  765. out |= OUT_RIGHT;
  766. }
  767. if (this.height <= 0) {
  768. out |= OUT_TOP | OUT_BOTTOM;
  769. } else if (y < this.y) {
  770. out |= OUT_TOP;
  771. } else if (y > this.y + (double) this.height) {
  772. out |= OUT_BOTTOM;
  773. }
  774. return out;
  775. }
  776. /**
  777. * Returns a new {@link Rectangle2D} object
  778. * representing the intersection of this <code>Rectangle</code> with the
  779. * specified <code>Rectangle2D</code>.
  780. * @param r the <code>Rectangle2D</code> to be intersected
  781. * with this <code>Rectangle</code>
  782. * @return the largest <code>Rectangle2D</code> contained in both the
  783. * specified <code>Rectangle2D</code> and in
  784. * this <code>Rectangle</code>.
  785. * @since 1.2
  786. */
  787. public Rectangle2D createIntersection(Rectangle2D r) {
  788. if (r instanceof Rectangle) {
  789. return intersection((Rectangle) r);
  790. }
  791. Rectangle2D dest = new Rectangle2D.Double();
  792. Rectangle2D.intersect(this, r, dest);
  793. return dest;
  794. }
  795. /**
  796. * Returns a new <code>Rectangle2D</code> object representing the
  797. * union of this <code>Rectangle</code> with the specified
  798. * <code>Rectangle2D</code>.
  799. * @param r the <code>Rectangle2D</code> to be combined with
  800. * this <code>Rectangle</code>
  801. * @return the smallest <code>Rectangle2D</code> containing
  802. * both the specified <code>Rectangle2D</code> and this
  803. * <code>Rectangle</code>.
  804. * @since 1.2
  805. */
  806. public Rectangle2D createUnion(Rectangle2D r) {
  807. if (r instanceof Rectangle) {
  808. return union((Rectangle) r);
  809. }
  810. Rectangle2D dest = new Rectangle2D.Double();
  811. Rectangle2D.union(this, r, dest);
  812. return dest;
  813. }
  814. /**
  815. * Checks whether two rectangles are equal.
  816. * <p>
  817. * The result is <code>true</code> if and only if the argument is not
  818. * <code>null</code> and is a <code>Rectangle</code> object that has the
  819. * same top-left corner, width, and height as this <code>Rectangle</code>.
  820. * @param obj the <code>Object</code> to compare with
  821. * this <code>Rectangle</code>
  822. * @return <code>true</code> if the objects are equal;
  823. * <code>false</code> otherwise.
  824. */
  825. public boolean equals(Object obj) {
  826. if (obj instanceof Rectangle) {
  827. Rectangle r = (Rectangle)obj;
  828. return ((x == r.x) &&
  829. (y == r.y) &&
  830. (width == r.width) &&
  831. (height == r.height));
  832. }
  833. return super.equals(obj);
  834. }
  835. /**
  836. * Returns a <code>String</code> representing this
  837. * <code>Rectangle</code> and its values.
  838. * @return a <code>String</code> representing this
  839. * <code>Rectangle</code> object's coordinate and size values.
  840. */
  841. public String toString() {
  842. return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]";
  843. }
  844. }