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