Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ---------------------- 28: * CenterArrangement.java 29: * ---------------------- 30: * (C) Copyright 2005, 2006, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: CenterArrangement.java,v 1.3.2.2 2006/07/20 16:21:58 mungady Exp $ 36: * 37: * Changes: 38: * -------- 39: * 08-Mar-2005 : Version 1 (DG); 40: * ------------- JFREECHART 1.0.0 --------------------------------------------- 41: * 20-Jul-2006 : Set bounds of contained block when arranging (DG); 42: * 43: */ 44: 45: package org.jfree.chart.block; 46: 47: import java.awt.Graphics2D; 48: import java.awt.geom.Rectangle2D; 49: import java.io.Serializable; 50: import java.util.List; 51: 52: import org.jfree.ui.Size2D; 53: 54: /** 55: * Arranges a block in the center of its container. This class is immutable. 56: */ 57: public class CenterArrangement implements Arrangement, Serializable { 58: 59: /** For serialization. */ 60: private static final long serialVersionUID = -353308149220382047L; 61: 62: /** 63: * Creates a new instance. 64: */ 65: public CenterArrangement() { 66: } 67: 68: /** 69: * Adds a block to be managed by this instance. This method is usually 70: * called by the {@link BlockContainer}, you shouldn't need to call it 71: * directly. 72: * 73: * @param block the block. 74: * @param key a key that controls the position of the block. 75: */ 76: public void add(Block block, Object key) { 77: // since the flow layout is relatively straightforward, 78: // no information needs to be recorded here 79: } 80: 81: /** 82: * Calculates and sets the bounds of all the items in the specified 83: * container, subject to the given constraint. The <code>Graphics2D</code> 84: * can be used by some items (particularly items containing text) to 85: * calculate sizing parameters. 86: * 87: * @param container the container whose items are being arranged. 88: * @param g2 the graphics device. 89: * @param constraint the size constraint. 90: * 91: * @return The size of the container after arrangement of the contents. 92: */ 93: public Size2D arrange(BlockContainer container, Graphics2D g2, 94: RectangleConstraint constraint) { 95: 96: LengthConstraintType w = constraint.getWidthConstraintType(); 97: LengthConstraintType h = constraint.getHeightConstraintType(); 98: if (w == LengthConstraintType.NONE) { 99: if (h == LengthConstraintType.NONE) { 100: return arrangeNN(container, g2); 101: } 102: else if (h == LengthConstraintType.FIXED) { 103: throw new RuntimeException("Not implemented."); 104: } 105: else if (h == LengthConstraintType.RANGE) { 106: throw new RuntimeException("Not implemented."); 107: } 108: } 109: else if (w == LengthConstraintType.FIXED) { 110: if (h == LengthConstraintType.NONE) { 111: return arrangeFN(container, g2, constraint); 112: } 113: else if (h == LengthConstraintType.FIXED) { 114: throw new RuntimeException("Not implemented."); 115: } 116: else if (h == LengthConstraintType.RANGE) { 117: throw new RuntimeException("Not implemented."); 118: } 119: } 120: else if (w == LengthConstraintType.RANGE) { 121: if (h == LengthConstraintType.NONE) { 122: return arrangeRN(container, g2, constraint); 123: } 124: else if (h == LengthConstraintType.FIXED) { 125: return arrangeRF(container, g2, constraint); 126: } 127: else if (h == LengthConstraintType.RANGE) { 128: return arrangeRR(container, g2, constraint); 129: } 130: } 131: throw new IllegalArgumentException("Unknown LengthConstraintType."); 132: 133: } 134: 135: /** 136: * Arranges the blocks in the container with a fixed width and no height 137: * constraint. 138: * 139: * @param container the container. 140: * @param g2 the graphics device. 141: * @param constraint the constraint. 142: * 143: * @return The size. 144: */ 145: protected Size2D arrangeFN(BlockContainer container, Graphics2D g2, 146: RectangleConstraint constraint) { 147: 148: List blocks = container.getBlocks(); 149: Block b = (Block) blocks.get(0); 150: Size2D s = b.arrange(g2, RectangleConstraint.NONE); 151: double width = constraint.getWidth(); 152: Rectangle2D bounds = new Rectangle2D.Double((width - s.width) / 2.0, 153: 0.0, s.width, s.height); 154: b.setBounds(bounds); 155: return new Size2D((width - s.width) / 2.0, s.height); 156: } 157: 158: /** 159: * Arranges the blocks in the container with a fixed with and a range 160: * constraint on the height. 161: * 162: * @param container the container. 163: * @param g2 the graphics device. 164: * @param constraint the constraint. 165: * 166: * @return The size following the arrangement. 167: */ 168: protected Size2D arrangeFR(BlockContainer container, Graphics2D g2, 169: RectangleConstraint constraint) { 170: 171: Size2D s = arrangeFN(container, g2, constraint); 172: if (constraint.getHeightRange().contains(s.height)) { 173: return s; 174: } 175: else { 176: RectangleConstraint c = constraint.toFixedHeight( 177: constraint.getHeightRange().constrain(s.getHeight())); 178: return arrangeFF(container, g2, c); 179: } 180: } 181: 182: /** 183: * Arranges the blocks in the container with the overall height and width 184: * specified as fixed constraints. 185: * 186: * @param container the container. 187: * @param g2 the graphics device. 188: * @param constraint the constraint. 189: * 190: * @return The size following the arrangement. 191: */ 192: protected Size2D arrangeFF(BlockContainer container, Graphics2D g2, 193: RectangleConstraint constraint) { 194: 195: // TODO: implement this properly 196: return arrangeFN(container, g2, constraint); 197: } 198: 199: /** 200: * Arranges the blocks with the overall width and height to fit within 201: * specified ranges. 202: * 203: * @param container the container. 204: * @param g2 the graphics device. 205: * @param constraint the constraint. 206: * 207: * @return The size after the arrangement. 208: */ 209: protected Size2D arrangeRR(BlockContainer container, Graphics2D g2, 210: RectangleConstraint constraint) { 211: 212: // first arrange without constraints, and see if this fits within 213: // the required ranges... 214: Size2D s1 = arrangeNN(container, g2); 215: if (constraint.getWidthRange().contains(s1.width)) { 216: return s1; // TODO: we didn't check the height yet 217: } 218: else { 219: RectangleConstraint c = constraint.toFixedWidth( 220: constraint.getWidthRange().getUpperBound()); 221: return arrangeFR(container, g2, c); 222: } 223: } 224: 225: /** 226: * Arranges the blocks in the container with a range constraint on the 227: * width and a fixed height. 228: * 229: * @param container the container. 230: * @param g2 the graphics device. 231: * @param constraint the constraint. 232: * 233: * @return The size following the arrangement. 234: */ 235: protected Size2D arrangeRF(BlockContainer container, Graphics2D g2, 236: RectangleConstraint constraint) { 237: 238: Size2D s = arrangeNF(container, g2, constraint); 239: if (constraint.getWidthRange().contains(s.width)) { 240: return s; 241: } 242: else { 243: RectangleConstraint c = constraint.toFixedWidth( 244: constraint.getWidthRange().constrain(s.getWidth())); 245: return arrangeFF(container, g2, c); 246: } 247: } 248: 249: /** 250: * Arranges the block with a range constraint on the width, and no 251: * constraint on the height. 252: * 253: * @param container the container. 254: * @param g2 the graphics device. 255: * @param constraint the constraint. 256: * 257: * @return The size following the arrangement. 258: */ 259: protected Size2D arrangeRN(BlockContainer container, Graphics2D g2, 260: RectangleConstraint constraint) { 261: // first arrange without constraints, then see if the width fits 262: // within the required range...if not, call arrangeFN() at max width 263: Size2D s1 = arrangeNN(container, g2); 264: if (constraint.getWidthRange().contains(s1.width)) { 265: return s1; 266: } 267: else { 268: RectangleConstraint c = constraint.toFixedWidth( 269: constraint.getWidthRange().getUpperBound()); 270: return arrangeFN(container, g2, c); 271: } 272: } 273: 274: /** 275: * Arranges the blocks without any constraints. This puts all blocks 276: * into a single row. 277: * 278: * @param container the container. 279: * @param g2 the graphics device. 280: * 281: * @return The size after the arrangement. 282: */ 283: protected Size2D arrangeNN(BlockContainer container, Graphics2D g2) { 284: List blocks = container.getBlocks(); 285: Block b = (Block) blocks.get(0); 286: Size2D s = b.arrange(g2, RectangleConstraint.NONE); 287: b.setBounds(new Rectangle2D.Double(0.0, 0.0, s.width, s.height)); 288: return new Size2D(s.width, s.height); 289: } 290: 291: /** 292: * Arranges the blocks with no width constraint and a fixed height 293: * constraint. This puts all blocks into a single row. 294: * 295: * @param container the container. 296: * @param g2 the graphics device. 297: * @param constraint the constraint. 298: * 299: * @return The size after the arrangement. 300: */ 301: protected Size2D arrangeNF(BlockContainer container, Graphics2D g2, 302: RectangleConstraint constraint) { 303: // TODO: for now we are ignoring the height constraint 304: return arrangeNN(container, g2); 305: } 306: 307: /** 308: * Clears any cached information. 309: */ 310: public void clear() { 311: // no action required. 312: } 313: 314: /** 315: * Tests this instance for equality with an arbitrary object. 316: * 317: * @param obj the object (<code>null</code> permitted). 318: * 319: * @return A boolean. 320: */ 321: public boolean equals(Object obj) { 322: if (obj == this) { 323: return true; 324: } 325: if (!(obj instanceof CenterArrangement)) { 326: return false; 327: } 328: return true; 329: } 330: 331: }