001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/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 * RectangleConstraint.java 029 * ------------------------ 030 * (C) Copyright 2004-2008, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes: 036 * -------- 037 * 22-Oct-2004 : Version 1 (DG); 038 * 02-Feb-2005 : Added toString() method (DG); 039 * 08-Feb-2005 : Separated height and width constraints (DG); 040 * 13-May-2005 : Added convenience constructor and new methods for 041 * transforming constraints (DG); 042 * 043 */ 044 045 package org.jfree.chart.block; 046 047 import org.jfree.data.Range; 048 import org.jfree.ui.Size2D; 049 050 /** 051 * A description of a constraint for resizing a rectangle. Constraints are 052 * immutable. 053 */ 054 public class RectangleConstraint { 055 056 /** 057 * An instance representing no constraint. 058 */ 059 public static final RectangleConstraint NONE = new RectangleConstraint( 060 0.0, null, LengthConstraintType.NONE, 061 0.0, null, LengthConstraintType.NONE); 062 063 /** The width. */ 064 private double width; 065 066 /** The width range. */ 067 private Range widthRange; 068 069 /** The width constraint type. */ 070 private LengthConstraintType widthConstraintType; 071 072 /** The fixed or maximum height. */ 073 private double height; 074 075 private Range heightRange; 076 077 /** The constraint type. */ 078 private LengthConstraintType heightConstraintType; 079 080 /** 081 * Creates a new "fixed width and height" instance. 082 * 083 * @param w the fixed width. 084 * @param h the fixed height. 085 */ 086 public RectangleConstraint(double w, double h) { 087 this(w, null, LengthConstraintType.FIXED, 088 h, null, LengthConstraintType.FIXED); 089 } 090 091 /** 092 * Creates a new "range width and height" instance. 093 * 094 * @param w the width range. 095 * @param h the height range. 096 */ 097 public RectangleConstraint(Range w, Range h) { 098 this(0.0, w, LengthConstraintType.RANGE, 099 0.0, h, LengthConstraintType.RANGE); 100 } 101 102 /** 103 * Creates a new constraint with a range for the width and a 104 * fixed height. 105 * 106 * @param w the width range. 107 * @param h the fixed height. 108 */ 109 public RectangleConstraint(Range w, double h) { 110 this(0.0, w, LengthConstraintType.RANGE, 111 h, null, LengthConstraintType.FIXED); 112 } 113 114 /** 115 * Creates a new constraint with a fixed width and a range for 116 * the height. 117 * 118 * @param w the fixed width. 119 * @param h the height range. 120 */ 121 public RectangleConstraint(double w, Range h) { 122 this(w, null, LengthConstraintType.FIXED, 123 0.0, h, LengthConstraintType.RANGE); 124 } 125 126 /** 127 * Creates a new constraint. 128 * 129 * @param w the fixed or maximum width. 130 * @param widthRange the width range. 131 * @param widthConstraintType the width type. 132 * @param h the fixed or maximum height. 133 * @param heightRange the height range. 134 * @param heightConstraintType the height type. 135 */ 136 public RectangleConstraint(double w, Range widthRange, 137 LengthConstraintType widthConstraintType, 138 double h, Range heightRange, 139 LengthConstraintType heightConstraintType) { 140 if (widthConstraintType == null) { 141 throw new IllegalArgumentException("Null 'widthType' argument."); 142 } 143 if (heightConstraintType == null) { 144 throw new IllegalArgumentException("Null 'heightType' argument."); 145 } 146 this.width = w; 147 this.widthRange = widthRange; 148 this.widthConstraintType = widthConstraintType; 149 this.height = h; 150 this.heightRange = heightRange; 151 this.heightConstraintType = heightConstraintType; 152 } 153 154 /** 155 * Returns the fixed width. 156 * 157 * @return The width. 158 */ 159 public double getWidth() { 160 return this.width; 161 } 162 163 /** 164 * Returns the width range. 165 * 166 * @return The range (possibly <code>null</code>). 167 */ 168 public Range getWidthRange() { 169 return this.widthRange; 170 } 171 172 /** 173 * Returns the constraint type. 174 * 175 * @return The constraint type (never <code>null</code>). 176 */ 177 public LengthConstraintType getWidthConstraintType() { 178 return this.widthConstraintType; 179 } 180 181 /** 182 * Returns the fixed height. 183 * 184 * @return The height. 185 */ 186 public double getHeight() { 187 return this.height; 188 } 189 190 /** 191 * Returns the width range. 192 * 193 * @return The range (possibly <code>null</code>). 194 */ 195 public Range getHeightRange() { 196 return this.heightRange; 197 } 198 199 /** 200 * Returns the constraint type. 201 * 202 * @return The constraint type (never <code>null</code>). 203 */ 204 public LengthConstraintType getHeightConstraintType() { 205 return this.heightConstraintType; 206 } 207 208 /** 209 * Returns a constraint that matches this one on the height attributes, 210 * but has no width constraint. 211 * 212 * @return A new constraint. 213 */ 214 public RectangleConstraint toUnconstrainedWidth() { 215 if (this.widthConstraintType == LengthConstraintType.NONE) { 216 return this; 217 } 218 else { 219 return new RectangleConstraint(this.width, this.widthRange, 220 LengthConstraintType.NONE, this.height, this.heightRange, 221 this.heightConstraintType); 222 } 223 } 224 225 /** 226 * Returns a constraint that matches this one on the width attributes, 227 * but has no height constraint. 228 * 229 * @return A new constraint. 230 */ 231 public RectangleConstraint toUnconstrainedHeight() { 232 if (this.heightConstraintType == LengthConstraintType.NONE) { 233 return this; 234 } 235 else { 236 return new RectangleConstraint(this.width, this.widthRange, 237 this.widthConstraintType, 0.0, this.heightRange, 238 LengthConstraintType.NONE); 239 } 240 } 241 242 /** 243 * Returns a constraint that matches this one on the height attributes, 244 * but has a fixed width constraint. 245 * 246 * @param width the fixed width. 247 * 248 * @return A new constraint. 249 */ 250 public RectangleConstraint toFixedWidth(double width) { 251 return new RectangleConstraint(width, this.widthRange, 252 LengthConstraintType.FIXED, this.height, this.heightRange, 253 this.heightConstraintType); 254 } 255 256 /** 257 * Returns a constraint that matches this one on the width attributes, 258 * but has a fixed height constraint. 259 * 260 * @param height the fixed height. 261 * 262 * @return A new constraint. 263 */ 264 public RectangleConstraint toFixedHeight(double height) { 265 return new RectangleConstraint(this.width, this.widthRange, 266 this.widthConstraintType, height, this.heightRange, 267 LengthConstraintType.FIXED); 268 } 269 270 /** 271 * Returns a constraint that matches this one on the height attributes, 272 * but has a range width constraint. 273 * 274 * @param range the width range (<code>null</code> not permitted). 275 * 276 * @return A new constraint. 277 */ 278 public RectangleConstraint toRangeWidth(Range range) { 279 if (range == null) { 280 throw new IllegalArgumentException("Null 'range' argument."); 281 } 282 return new RectangleConstraint(range.getUpperBound(), range, 283 LengthConstraintType.RANGE, this.height, this.heightRange, 284 this.heightConstraintType); 285 } 286 287 /** 288 * Returns a constraint that matches this one on the width attributes, 289 * but has a range height constraint. 290 * 291 * @param range the height range (<code>null</code> not permitted). 292 * 293 * @return A new constraint. 294 */ 295 public RectangleConstraint toRangeHeight(Range range) { 296 if (range == null) { 297 throw new IllegalArgumentException("Null 'range' argument."); 298 } 299 return new RectangleConstraint(this.width, this.widthRange, 300 this.widthConstraintType, range.getUpperBound(), range, 301 LengthConstraintType.RANGE); 302 } 303 304 /** 305 * Returns a string representation of this instance, mostly used for 306 * debugging purposes. 307 * 308 * @return A string. 309 */ 310 public String toString() { 311 return "RectangleConstraint[" 312 + this.widthConstraintType.toString() + ": width=" 313 + this.width + ", height=" + this.height + "]"; 314 } 315 316 /** 317 * Returns the new size that reflects the constraints defined by this 318 * instance. 319 * 320 * @param base the base size. 321 * 322 * @return The constrained size. 323 */ 324 public Size2D calculateConstrainedSize(Size2D base) { 325 Size2D result = new Size2D(); 326 if (this.widthConstraintType == LengthConstraintType.NONE) { 327 result.width = base.width; 328 if (this.heightConstraintType == LengthConstraintType.NONE) { 329 result.height = base.height; 330 } 331 else if (this.heightConstraintType == LengthConstraintType.RANGE) { 332 result.height = this.heightRange.constrain(base.height); 333 } 334 else if (this.heightConstraintType == LengthConstraintType.FIXED) { 335 result.height = this.height; 336 } 337 } 338 else if (this.widthConstraintType == LengthConstraintType.RANGE) { 339 result.width = this.widthRange.constrain(base.width); 340 if (this.heightConstraintType == LengthConstraintType.NONE) { 341 result.height = base.height; 342 } 343 else if (this.heightConstraintType == LengthConstraintType.RANGE) { 344 result.height = this.heightRange.constrain(base.height); 345 } 346 else if (this.heightConstraintType == LengthConstraintType.FIXED) { 347 result.height = this.height; 348 } 349 } 350 else if (this.widthConstraintType == LengthConstraintType.FIXED) { 351 result.width = this.width; 352 if (this.heightConstraintType == LengthConstraintType.NONE) { 353 result.height = base.height; 354 } 355 else if (this.heightConstraintType == LengthConstraintType.RANGE) { 356 result.height = this.heightRange.constrain(base.height); 357 } 358 else if (this.heightConstraintType == LengthConstraintType.FIXED) { 359 result.height = this.height; 360 } 361 } 362 return result; 363 } 364 365 }