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