Source for org.jfree.chart.block.BlockContainer

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, 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:  * BlockContainer.java
  29:  * -------------------
  30:  * (C) Copyright 2004-2007, by Object Refinery Limited.
  31:  *
  32:  * Original Author:  David Gilbert (for Object Refinery Limited);
  33:  * Contributor(s):   -;
  34:  *
  35:  * $Id: BlockContainer.java,v 1.11.2.3 2007/03/16 14:10:12 mungady Exp $
  36:  *
  37:  * Changes:
  38:  * --------
  39:  * 22-Oct-2004 : Version 1 (DG);
  40:  * 02-Feb-2005 : Added isEmpty() method (DG);
  41:  * 04-Feb-2005 : Added equals(), clone() and implemented Serializable (DG);
  42:  * 08-Feb-2005 : Updated for changes in RectangleConstraint (DG);
  43:  * 20-Apr-2005 : Added new draw() method (DG);
  44:  * ------------- JFREECHART 1.0.0 ---------------------------------------------
  45:  * 20-Jul-2006 : Perform translation directly on drawing area, not via 
  46:  *               Graphics2D (DG);
  47:  * 
  48:  */
  49: 
  50: package org.jfree.chart.block;
  51: 
  52: import java.awt.Graphics2D;
  53: import java.awt.geom.Rectangle2D;
  54: import java.io.Serializable;
  55: import java.util.ArrayList;
  56: import java.util.Collections;
  57: import java.util.Iterator;
  58: import java.util.List;
  59: 
  60: import org.jfree.chart.entity.EntityCollection;
  61: import org.jfree.chart.entity.StandardEntityCollection;
  62: import org.jfree.ui.Size2D;
  63: import org.jfree.util.PublicCloneable;
  64: 
  65: /**
  66:  * A container for a collection of {@link Block} objects.  The container uses 
  67:  * an {@link Arrangement} object to handle the position of each block.
  68:  */
  69: public class BlockContainer extends AbstractBlock 
  70:                             implements Block, 
  71:                                        Cloneable, PublicCloneable,
  72:                                        Serializable {
  73: 
  74:     /** For serialization. */
  75:     private static final long serialVersionUID = 8199508075695195293L;
  76:     
  77:     /** The blocks within the container. */
  78:     private List blocks;
  79:     
  80:     /** The object responsible for laying out the blocks. */
  81:     private Arrangement arrangement;
  82:     
  83:     /**
  84:      * Creates a new instance with default settings.
  85:      */
  86:     public BlockContainer() {
  87:         this(new BorderArrangement());
  88:     }
  89:     
  90:     /**
  91:      * Creates a new instance with the specified arrangement.
  92:      * 
  93:      * @param arrangement  the arrangement manager (<code>null</code> not 
  94:      *                     permitted).
  95:      */
  96:     public BlockContainer(Arrangement arrangement) {
  97:         if (arrangement == null) {
  98:             throw new IllegalArgumentException("Null 'arrangement' argument.");
  99:         }
 100:         this.arrangement = arrangement;
 101:         this.blocks = new ArrayList();
 102:     }    
 103: 
 104:     /**
 105:      * Returns the arrangement (layout) manager for the container.
 106:      * 
 107:      * @return The arrangement manager (never <code>null</code>).
 108:      */
 109:     public Arrangement getArrangement() {
 110:         return this.arrangement;    
 111:     }
 112:     
 113:     /**
 114:      * Sets the arrangement (layout) manager.
 115:      * 
 116:      * @param arrangement  the arrangement (<code>null</code> not permitted).
 117:      */
 118:     public void setArrangement(Arrangement arrangement) {
 119:         if (arrangement == null) {
 120:             throw new IllegalArgumentException("Null 'arrangement' argument.");
 121:         }
 122:         this.arrangement = arrangement;   
 123:     }
 124:     
 125:     /**
 126:      * Returns <code>true</code> if there are no blocks in the container, and
 127:      * <code>false</code> otherwise.
 128:      * 
 129:      * @return A boolean.
 130:      */
 131:     public boolean isEmpty() {
 132:         return this.blocks.isEmpty();   
 133:     }
 134:     
 135:     /**
 136:      * Returns an unmodifiable list of the {@link Block} objects managed by 
 137:      * this arrangement.
 138:      * 
 139:      * @return A list of blocks.
 140:      */
 141:     public List getBlocks() {
 142:         return Collections.unmodifiableList(this.blocks);
 143:     }
 144:     
 145:     /**
 146:      * Adds a block to the container.
 147:      * 
 148:      * @param block  the block (<code>null</code> permitted).
 149:      */
 150:     public void add(Block block) {
 151:         add(block, null);
 152:     }
 153:     
 154:     /**
 155:      * Adds a block to the container.
 156:      * 
 157:      * @param block  the block (<code>null</code> permitted).
 158:      * @param key  the key (<code>null</code> permitted).
 159:      */
 160:     public void add(Block block, Object key) {
 161:         this.blocks.add(block);
 162:         this.arrangement.add(block, key);
 163:     }
 164:     
 165:     /**
 166:      * Clears all the blocks from the container.
 167:      */
 168:     public void clear() {
 169:         this.blocks.clear();
 170:         this.arrangement.clear();
 171:     }
 172:     
 173:     /**
 174:      * Arranges the contents of the block, within the given constraints, and 
 175:      * returns the block size.
 176:      * 
 177:      * @param g2  the graphics device.
 178:      * @param constraint  the constraint (<code>null</code> not permitted).
 179:      * 
 180:      * @return The block size (in Java2D units, never <code>null</code>).
 181:      */
 182:     public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
 183:         return this.arrangement.arrange(this, g2, constraint);
 184:     }
 185: 
 186:     /**
 187:      * Draws the container and all the blocks within it.
 188:      * 
 189:      * @param g2  the graphics device.
 190:      * @param area  the area.
 191:      */
 192:     public void draw(Graphics2D g2, Rectangle2D area) {
 193:         draw(g2, area, null);
 194:     }
 195:     
 196:     /**
 197:      * Draws the block within the specified area.
 198:      * 
 199:      * @param g2  the graphics device.
 200:      * @param area  the area.
 201:      * @param params  passed on to blocks within the container 
 202:      *                (<code>null</code> permitted).
 203:      * 
 204:      * @return An instance of {@link EntityBlockResult}, or <code>null</code>.
 205:      */
 206:     public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
 207:         // check if we need to collect chart entities from the container
 208:         EntityBlockParams ebp = null;
 209:         StandardEntityCollection sec = null;
 210:         if (params instanceof EntityBlockParams) {
 211:             ebp = (EntityBlockParams) params;
 212:             if (ebp.getGenerateEntities()) {
 213:                 sec = new StandardEntityCollection();   
 214:             }
 215:         }
 216:         Rectangle2D contentArea = (Rectangle2D) area.clone();
 217:         contentArea = trimMargin(contentArea);
 218:         drawBorder(g2, contentArea);
 219:         contentArea = trimBorder(contentArea);
 220:         contentArea = trimPadding(contentArea);
 221:         Iterator iterator = this.blocks.iterator();
 222:         while (iterator.hasNext()) {
 223:             Block block = (Block) iterator.next();
 224:             Rectangle2D bounds = block.getBounds();
 225:             Rectangle2D drawArea = new Rectangle2D.Double(bounds.getX() 
 226:                     + area.getX(), bounds.getY() + area.getY(), 
 227:                     bounds.getWidth(), bounds.getHeight());
 228:             Object r = block.draw(g2, drawArea, params);
 229:             if (sec != null) {
 230:                 if (r instanceof EntityBlockResult) {
 231:                     EntityBlockResult ebr = (EntityBlockResult) r;
 232:                     EntityCollection ec = ebr.getEntityCollection();
 233:                     sec.addAll(ec);
 234:                 }
 235:             }
 236:         }
 237:         BlockResult result = null;
 238:         if (sec != null) {
 239:             result = new BlockResult();
 240:             result.setEntityCollection(sec);
 241:         }
 242:         return result;
 243:     }
 244: 
 245:     /**
 246:      * Tests this container for equality with an arbitrary object.
 247:      * 
 248:      * @param obj  the object (<code>null</code> permitted).
 249:      * 
 250:      * @return A boolean.
 251:      */
 252:     public boolean equals(Object obj) {
 253:         if (obj == this) {
 254:             return true;   
 255:         }
 256:         if (!(obj instanceof BlockContainer)) {
 257:             return false;   
 258:         }
 259:         if (!super.equals(obj)) {
 260:             return false;   
 261:         }
 262:         BlockContainer that = (BlockContainer) obj;
 263:         if (!this.arrangement.equals(that.arrangement)) {
 264:             return false;   
 265:         }
 266:         if (!this.blocks.equals(that.blocks)) {
 267:             return false;   
 268:         }
 269:         return true;
 270:     }
 271:     
 272:     /**
 273:      * Returns a clone of the container.
 274:      * 
 275:      * @return A clone.
 276:      * 
 277:      * @throws CloneNotSupportedException if there is a problem cloning.
 278:      */
 279:     public Object clone() throws CloneNotSupportedException {
 280:         BlockContainer clone = (BlockContainer) super.clone();
 281:         // TODO : complete this
 282:         return clone;
 283:     }
 284:     
 285: }