Source for org.jfree.chart.block.CenterArrangement

   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: }