001/* ======================================================================== 002 * JCommon : a free general purpose class library for the Java(tm) platform 003 * ======================================================================== 004 * 005 * (C) Copyright 2000-2015, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jcommon/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * -------------------- 028 * RectangleAnchor.java 029 * -------------------- 030 * (C) Copyright 2003-2015, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes: 036 * -------- 037 * 31-Oct-2003 (DG); 038 * 01-Apr-2004 : Changed java.awt.geom.Dimension2D to org.jfree.ui.Size2D 039 * because of JDK bug 4976448 which persists on JDK 1.3.1 (DG); 040 * 21-Jan-2005 : Changed return type of coordinates() method (DG); 041 * 17-Feb-2015 : Fixes for createRectangle() (DG); 042 * 043 */ 044 045package org.jfree.ui; 046 047import java.awt.geom.Point2D; 048import java.awt.geom.Rectangle2D; 049import java.io.ObjectStreamException; 050import java.io.Serializable; 051 052/** 053 * Used to indicate an anchor point for a rectangle. 054 */ 055public final class RectangleAnchor implements Serializable { 056 057 /** For serialization. */ 058 private static final long serialVersionUID = -2457494205644416327L; 059 060 /** Center. */ 061 public static final RectangleAnchor CENTER 062 = new RectangleAnchor("RectangleAnchor.CENTER"); 063 064 /** Top. */ 065 public static final RectangleAnchor TOP 066 = new RectangleAnchor("RectangleAnchor.TOP"); 067 068 /** Top-Left. */ 069 public static final RectangleAnchor TOP_LEFT 070 = new RectangleAnchor("RectangleAnchor.TOP_LEFT"); 071 072 /** Top-Right. */ 073 public static final RectangleAnchor TOP_RIGHT 074 = new RectangleAnchor("RectangleAnchor.TOP_RIGHT"); 075 076 /** Bottom. */ 077 public static final RectangleAnchor BOTTOM 078 = new RectangleAnchor("RectangleAnchor.BOTTOM"); 079 080 /** Bottom-Left. */ 081 public static final RectangleAnchor BOTTOM_LEFT 082 = new RectangleAnchor("RectangleAnchor.BOTTOM_LEFT"); 083 084 /** Bottom-Right. */ 085 public static final RectangleAnchor BOTTOM_RIGHT 086 = new RectangleAnchor("RectangleAnchor.BOTTOM_RIGHT"); 087 088 /** Left. */ 089 public static final RectangleAnchor LEFT 090 = new RectangleAnchor("RectangleAnchor.LEFT"); 091 092 /** Right. */ 093 public static final RectangleAnchor RIGHT 094 = new RectangleAnchor("RectangleAnchor.RIGHT"); 095 096 /** The name. */ 097 private String name; 098 099 /** 100 * Private constructor. 101 * 102 * @param name the name. 103 */ 104 private RectangleAnchor(String name) { 105 this.name = name; 106 } 107 108 /** 109 * Returns a string representing the object. 110 * 111 * @return The string. 112 */ 113 public String toString() { 114 return this.name; 115 } 116 117 /** 118 * Returns <code>true</code> if this object is equal to the specified 119 * object, and <code>false</code> otherwise. 120 * 121 * @param obj the other object (<code>null</code> permitted). 122 * 123 * @return A boolean. 124 */ 125 public boolean equals(final Object obj) { 126 127 if (this == obj) { 128 return true; 129 } 130 if (!(obj instanceof RectangleAnchor)) { 131 return false; 132 } 133 134 final RectangleAnchor order = (RectangleAnchor) obj; 135 if (!this.name.equals(order.name)) { 136 return false; 137 } 138 139 return true; 140 } 141 142 /** 143 * Returns a hash code value for the object. 144 * 145 * @return The hashcode 146 */ 147 public int hashCode() { 148 return this.name.hashCode(); 149 } 150 151 /** 152 * Returns the (x, y) coordinates of the specified anchor. 153 * 154 * @param rectangle the rectangle. 155 * @param anchor the anchor. 156 * 157 * @return The (x, y) coordinates. 158 */ 159 public static Point2D coordinates(final Rectangle2D rectangle, 160 final RectangleAnchor anchor) { 161 Point2D result = new Point2D.Double(); 162 if (anchor == RectangleAnchor.CENTER) { 163 result.setLocation(rectangle.getCenterX(), rectangle.getCenterY()); 164 } 165 else if (anchor == RectangleAnchor.TOP) { 166 result.setLocation(rectangle.getCenterX(), rectangle.getMinY()); 167 } 168 else if (anchor == RectangleAnchor.BOTTOM) { 169 result.setLocation(rectangle.getCenterX(), rectangle.getMaxY()); 170 } 171 else if (anchor == RectangleAnchor.LEFT) { 172 result.setLocation(rectangle.getMinX(), rectangle.getCenterY()); 173 } 174 else if (anchor == RectangleAnchor.RIGHT) { 175 result.setLocation(rectangle.getMaxX(), rectangle.getCenterY()); 176 } 177 else if (anchor == RectangleAnchor.TOP_LEFT) { 178 result.setLocation(rectangle.getMinX(), rectangle.getMinY()); 179 } 180 else if (anchor == RectangleAnchor.TOP_RIGHT) { 181 result.setLocation(rectangle.getMaxX(), rectangle.getMinY()); 182 } 183 else if (anchor == RectangleAnchor.BOTTOM_LEFT) { 184 result.setLocation(rectangle.getMinX(), rectangle.getMaxY()); 185 } 186 else if (anchor == RectangleAnchor.BOTTOM_RIGHT) { 187 result.setLocation(rectangle.getMaxX(), rectangle.getMaxY()); 188 } 189 return result; 190 } 191 192 /** 193 * Creates a new rectangle with the specified dimensions that is aligned to 194 * the given anchor point {@code (anchorX, anchorY)}. 195 * 196 * @param dimensions the dimensions ({@code null} not permitted). 197 * @param anchorX the x-anchor. 198 * @param anchorY the y-anchor. 199 * @param anchor the anchor ({@code null} not permitted). 200 * 201 * @return A rectangle. 202 */ 203 public static Rectangle2D createRectangle(Size2D dimensions, 204 double anchorX, double anchorY, RectangleAnchor anchor) { 205 Rectangle2D result = null; 206 final double w = dimensions.getWidth(); 207 final double h = dimensions.getHeight(); 208 if (anchor == RectangleAnchor.CENTER) { 209 result = new Rectangle2D.Double(anchorX - w / 2.0, 210 anchorY - h / 2.0, w, h); 211 } else if (anchor == RectangleAnchor.TOP) { 212 result = new Rectangle2D.Double(anchorX - w / 2.0, anchorY, w, h); 213 } else if (anchor == RectangleAnchor.BOTTOM) { 214 result = new Rectangle2D.Double(anchorX - w / 2.0, anchorY - h, 215 w, h); 216 } else if (anchor == RectangleAnchor.LEFT) { 217 result = new Rectangle2D.Double(anchorX, anchorY - h / 2.0, w, h); 218 } else if (anchor == RectangleAnchor.RIGHT) { 219 result = new Rectangle2D.Double(anchorX - w, anchorY - h / 2.0, 220 w, h); 221 } else if (anchor == RectangleAnchor.TOP_LEFT) { 222 result = new Rectangle2D.Double(anchorX, anchorY, w, h); 223 } else if (anchor == RectangleAnchor.TOP_RIGHT) { 224 result = new Rectangle2D.Double(anchorX - w, anchorY, w, h); 225 } else if (anchor == RectangleAnchor.BOTTOM_LEFT) { 226 result = new Rectangle2D.Double(anchorX, anchorY - h, w, h); 227 } else if (anchor == RectangleAnchor.BOTTOM_RIGHT) { 228 result = new Rectangle2D.Double(anchorX - w, anchorY - h, w, h); 229 } 230 return result; 231 } 232 233 /** 234 * Ensures that serialization returns the unique instances. 235 * 236 * @return The object. 237 * 238 * @throws ObjectStreamException if there is a problem. 239 */ 240 private Object readResolve() throws ObjectStreamException { 241 RectangleAnchor result = null; 242 if (this.equals(RectangleAnchor.CENTER)) { 243 result = RectangleAnchor.CENTER; 244 } 245 else if (this.equals(RectangleAnchor.TOP)) { 246 result = RectangleAnchor.TOP; 247 } 248 else if (this.equals(RectangleAnchor.BOTTOM)) { 249 result = RectangleAnchor.BOTTOM; 250 } 251 else if (this.equals(RectangleAnchor.LEFT)) { 252 result = RectangleAnchor.LEFT; 253 } 254 else if (this.equals(RectangleAnchor.RIGHT)) { 255 result = RectangleAnchor.RIGHT; 256 } 257 else if (this.equals(RectangleAnchor.TOP_LEFT)) { 258 result = RectangleAnchor.TOP_LEFT; 259 } 260 else if (this.equals(RectangleAnchor.TOP_RIGHT)) { 261 result = RectangleAnchor.TOP_RIGHT; 262 } 263 else if (this.equals(RectangleAnchor.BOTTOM_LEFT)) { 264 result = RectangleAnchor.BOTTOM_LEFT; 265 } 266 else if (this.equals(RectangleAnchor.BOTTOM_RIGHT)) { 267 result = RectangleAnchor.BOTTOM_RIGHT; 268 } 269 return result; 270 } 271 272}