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