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