Package com.positive.charts.block

Source Code of com.positive.charts.block.AbstractBlock

/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jfreechart/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA. 
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------------
* AbstractBlock.java
* ------------------
* (C) Copyright 2004-2007, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* Changes:
* --------
* 22-Oct-2004 : Version 1 (DG);
* 02-Feb-2005 : Added accessor methods for margin (DG);
* 04-Feb-2005 : Added equals() method and implemented Serializable (DG);
* 03-May-2005 : Added null argument checks (DG);
* 06-May-2005 : Added convenience methods for setting margin, border and
*               padding (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 16-Mar-2007 : Changed border from BlockBorder to BlockFrame, updated
*               equals(), and implemented Cloneable (DG);
*
*/

package com.positive.charts.block;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;

import com.positive.charts.data.Range;
import com.positive.charts.data.util.ObjectUtilities;
import com.positive.charts.data.util.PublicCloneable;
import com.positive.charts.util.Size2D;

/**
* A convenience class for creating new classes that implement the {@link Block}
* interface.
*/
public class AbstractBlock implements Cloneable, Serializable {

  /** For serialization. */
  private static final long serialVersionUID = 7689852412141274563L;

  /** The id for the block. */
  private String id;

  /** The margin around the outside of the block. */
  private RectangleInsets margin;

  /** The frame (or border) for the block. */
  private BlockFrame frame;

  /** The padding between the block content and the border. */
  private RectangleInsets padding;

  /**
   * The natural width of the block (may be overridden if there are
   * constraints in sizing).
   */
  private double width;

  /**
   * The natural height of the block (may be overridden if there are
   * constraints in sizing).
   */
  private double height;

  /**
   * The current bounds for the block (position of the block in Java2D space).
   */
  private transient Rectangle bounds;

  /**
   * Creates a new block.
   */
  protected AbstractBlock() {
    this.id = null;
    this.width = 0.0;
    this.height = 0.0;
    this.bounds = new Rectangle(0, 0, 0, 0);
    this.margin = RectangleInsets.ZERO_INSETS;
    this.frame = BlockBorder.NONE;
    this.padding = RectangleInsets.ZERO_INSETS;
  }

  /**
   * Arranges the contents of the block, with no constraints, and returns the
   * block size.
   *
   * @param g2
   *            the graphics device.
   *
   * @return The block size (in Java2D units, never <code>null</code>).
   */
  public Size2D arrange(final GC g2) {
    return this.arrange(g2, RectangleConstraint.NONE);
  }

  /**
   * Arranges the contents of the block, within the given constraints, and
   * returns the block size.
   *
   * @param g2
   *            the graphics device.
   * @param constraint
   *            the constraint (<code>null</code> not permitted).
   *
   * @return The block size (in Java2D units, never <code>null</code>).
   */
  public Size2D arrange(final GC g2, final RectangleConstraint constraint) {
    final Size2D base = new Size2D(this.getWidth(), this.getHeight());
    return constraint.calculateConstrainedSize(base);
  }

  /**
   * Adds the margin, border and padding to the specified content height.
   *
   * @param contentHeight
   *            the content height.
   *
   * @return The adjusted height.
   */
  protected double calculateTotalHeight(final double contentHeight) {
    double result = contentHeight;
    result = this.padding.extendHeight((int) result);
    result = this.frame.getInsets().extendHeight((int) result);
    result = this.margin.extendHeight((int) result);
    return result;
  }

  /**
   * Adds the margin, border and padding to the specified content width.
   *
   * @param contentWidth
   *            the content width.
   *
   * @return The adjusted width.
   */
  protected double calculateTotalWidth(final double contentWidth) {
    double result = contentWidth;
    result = this.padding.extendWidth((int) result);
    result = this.frame.getInsets().extendWidth((int) result);
    result = this.margin.extendWidth((int) result);
    return result;
  }

  /**
   * Returns a clone of this block.
   *
   * @return A clone.
   *
   * @throws CloneNotSupportedException
   *             if there is a problem creating the clone.
   */
  public Object clone() throws CloneNotSupportedException {
    final AbstractBlock clone = (AbstractBlock) super.clone();
    clone.bounds = new Rectangle(this.bounds.x, this.bounds.y,
        this.bounds.width, this.bounds.height);
    if (this.frame instanceof PublicCloneable) {
      final PublicCloneable pc = (PublicCloneable) this.frame;
      clone.frame = (BlockFrame) pc.clone();
    }
    return clone;
  }

  /**
   * Draws the border around the perimeter of the specified area.
   *
   * @param g2
   *            the graphics device.
   * @param area
   *            the area.
   */
  protected void drawBorder(final GC g2, final Rectangle area) {
    // this.frame.draw(g2, area);
  }

  /**
   * Tests this block for equality with an arbitrary object.
   *
   * @param obj
   *            the object (<code>null</code> permitted).
   *
   * @return A boolean.
   */
  public boolean equals(final Object obj) {
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof AbstractBlock)) {
      return false;
    }
    final AbstractBlock that = (AbstractBlock) obj;
    if (!ObjectUtilities.equal(this.id, that.id)) {
      return false;
    }
    if (!this.frame.equals(that.frame)) {
      return false;
    }
    if (!this.bounds.equals(that.bounds)) {
      return false;
    }
    if (!this.margin.equals(that.margin)) {
      return false;
    }
    if (!this.padding.equals(that.padding)) {
      return false;
    }
    if (this.height != that.height) {
      return false;
    }
    if (this.width != that.width) {
      return false;
    }
    return true;
  }

  /**
   * Returns the border.
   *
   * @return The border (never <code>null</code>).
   *
   * @deprecated Use {@link #getFrame()} instead.
   */
  public BlockBorder getBorder() {
    if (this.frame instanceof BlockBorder) {
      return (BlockBorder) this.frame;
    } else {
      return null;
    }
  }

  /**
   * Returns the current bounds of the block.
   *
   * @return The bounds.
   *
   * @see #setBounds(Rectangle)
   */
  public Rectangle getBounds() {
    return this.bounds;
  }

  /**
   * Returns the x-offset for the content within the block.
   *
   * @return The x-offset.
   *
   * @see #getContentYOffset()
   */
  public double getContentXOffset() {
    return this.margin.getLeft() + this.frame.getInsets().getLeft()
        + this.padding.getLeft();
  }

  /**
   * Returns the y-offset for the content within the block.
   *
   * @return The y-offset.
   *
   * @see #getContentXOffset()
   */
  public double getContentYOffset() {
    return this.margin.getTop() + this.frame.getInsets().getTop()
        + this.padding.getTop();
  }

  /**
   * Returns the current frame (border).
   *
   * @return The frame.
   *
   * @since 1.0.5
   * @see #setFrame(BlockFrame)
   */
  public BlockFrame getFrame() {
    return this.frame;
  }

  /**
   * Returns the natural height of the block, if this is known in advance. The
   * actual height of the block may be overridden if layout constraints make
   * this necessary.
   *
   * @return The height.
   *
   * @see #setHeight(double)
   */
  public double getHeight() {
    return this.height;
  }

  /**
   * Returns the id.
   *
   * @return The id (possibly <code>null</code>).
   *
   * @see #setID(String)
   */
  public String getID() {
    return this.id;
  }

  /**
   * Returns the margin.
   *
   * @return The margin (never <code>null</code>).
   *
   * @see #getMargin()
   */
  public RectangleInsets getMargin() {
    return this.margin;
  }

  /**
   * Returns the padding.
   *
   * @return The padding (never <code>null</code>).
   *
   * @see #setPadding(RectangleInsets)
   */
  public RectangleInsets getPadding() {
    return this.padding;
  }

  /**
   * Returns the natural width of the block, if this is known in advance. The
   * actual width of the block may be overridden if layout constraints make
   * this necessary.
   *
   * @return The width.
   *
   * @see #setWidth(double)
   */
  public double getWidth() {
    return this.width;
  }

  /**
   * Provides serialization support.
   *
   * @param stream
   *            the input stream.
   *
   * @throws IOException
   *             if there is an I/O error.
   * @throws ClassNotFoundException
   *             if there is a classpath problem.
   */
  private void readObject(final ObjectInputStream stream) throws IOException,
      ClassNotFoundException {
    stream.defaultReadObject();
    // this.bounds = (Rectangle) SerialUtilities.readShape(stream);
  }

  /**
   * Sets the border for the block (use {@link BlockBorder#NONE} for no
   * border).
   *
   * @param border
   *            the border (<code>null</code> not permitted).
   *
   * @see #getBorder()
   *
   * @deprecated Use {@link #setFrame(BlockFrame)} instead.
   */
  public void setBorder(final BlockBorder border) {
    this.setFrame(border);
  }

  /**
   * Sets a black border with the specified line widths.
   *
   * @param top
   *            the top border line width.
   * @param left
   *            the left border line width.
   * @param bottom
   *            the bottom border line width.
   * @param right
   *            the right border line width.
   */
  public void setBorder(final double top, final double left,
      final double bottom, final double right) {
    this.setFrame(new BlockBorder(top, left, bottom, right));
  }

  /**
   * Sets the bounds of the block.
   *
   * @param bounds
   *            the bounds (<code>null</code> not permitted).
   *
   * @see #getBounds()
   */
  public void setBounds(final Rectangle bounds) {
    if (bounds == null) {
      throw new IllegalArgumentException("Null 'bounds' argument.");
    }
    this.bounds = bounds;
  }

  /**
   * Sets the frame (or border).
   *
   * @param frame
   *            the frame (<code>null</code> not permitted).
   *
   * @since 1.0.5
   * @see #getFrame()
   */
  public void setFrame(final BlockFrame frame) {
    if (frame == null) {
      throw new IllegalArgumentException("Null 'frame' argument.");
    }
    this.frame = frame;
  }

  /**
   * Sets the natural width of the block, if this is known in advance.
   *
   * @param height
   *            the width (in Java2D units)
   *
   * @see #getHeight()
   */
  public void setHeight(final double height) {
    this.height = height;
  }

  /**
   * Sets the id for the block.
   *
   * @param id
   *            the id (<code>null</code> permitted).
   *
   * @see #getID()
   */
  public void setID(final String id) {
    this.id = id;
  }

  /**
   * Sets the margin.
   *
   * @param top
   *            the top margin.
   * @param left
   *            the left margin.
   * @param bottom
   *            the bottom margin.
   * @param right
   *            the right margin.
   *
   * @see #getMargin()
   */
  public void setMargin(final double top, final double left,
      final double bottom, final double right) {
    this.setMargin(new RectangleInsets(top, left, bottom, right));
  }

  /**
   * Sets the margin (use {@link RectangleInsets#ZERO_INSETS} for no padding).
   *
   * @param margin
   *            the margin (<code>null</code> not permitted).
   *
   * @see #getMargin()
   */
  public void setMargin(final RectangleInsets margin) {
    if (margin == null) {
      throw new IllegalArgumentException("Null 'margin' argument.");
    }
    this.margin = margin;
  }

  /**
   * Sets the padding.
   *
   * @param top
   *            the top padding.
   * @param left
   *            the left padding.
   * @param bottom
   *            the bottom padding.
   * @param right
   *            the right padding.
   */
  public void setPadding(final double top, final double left,
      final double bottom, final double right) {
    this.setPadding(new RectangleInsets(top, left, bottom, right));
  }

  /**
   * Sets the padding (use {@link RectangleInsets#ZERO_INSETS} for no
   * padding).
   *
   * @param padding
   *            the padding (<code>null</code> not permitted).
   *
   * @see #getPadding()
   */
  public void setPadding(final RectangleInsets padding) {
    if (padding == null) {
      throw new IllegalArgumentException("Null 'padding' argument.");
    }
    this.padding = padding;
  }

  /**
   * Sets the natural width of the block, if this is known in advance.
   *
   * @param width
   *            the width (in Java2D units)
   *
   * @see #getWidth()
   */
  public void setWidth(final double width) {
    this.width = width;
  }

  /**
   * Returns a constraint for the content of this block that will result in
   * the bounds of the block matching the specified constraint.
   *
   * @param c
   *            the outer constraint (<code>null</code> not permitted).
   *
   * @return The content constraint.
   */
  protected RectangleConstraint toContentConstraint(
      final RectangleConstraint c) {
    if (c == null) {
      throw new IllegalArgumentException("Null 'c' argument.");
    }
    if (c.equals(RectangleConstraint.NONE)) {
      return c;
    }
    final double w = c.getWidth();
    final Range wr = c.getWidthRange();
    final double h = c.getHeight();
    final Range hr = c.getHeightRange();
    final double ww = this.trimToContentWidth(w);
    final double hh = this.trimToContentHeight(h);
    final Range wwr = this.trimToContentWidth(wr);
    final Range hhr = this.trimToContentHeight(hr);
    return new RectangleConstraint(ww, wwr, c.getWidthConstraintType(), hh,
        hhr, c.getHeightConstraintType());
  }

  /**
   * Reduces the specified area by the amount of space consumed by the border.
   *
   * @param area
   *            the area (<code>null</code> not permitted).
   *
   * @return The trimmed area.
   */
  protected Rectangle trimBorder(final Rectangle area) {
    // defer argument checking...
    this.frame.getInsets().trim(area);
    return area;
  }

  /**
   * Reduces the specified area by the amount of space consumed by the margin.
   *
   * @param area
   *            the area (<code>null</code> not permitted).
   *
   * @return The trimmed area.
   */
  protected Rectangle trimMargin(final Rectangle area) {
    // defer argument checking...
    this.margin.trim(area);
    return area;
  }

  /**
   * Reduces the specified area by the amount of space consumed by the
   * padding.
   *
   * @param area
   *            the area (<code>null</code> not permitted).
   *
   * @return The trimmed area.
   */
  protected Rectangle trimPadding(final Rectangle area) {
    // defer argument checking...
    this.padding.trim(area);
    return area;
  }

  /**
   * Calculate the height available for content after subtracting the margin,
   * border and padding space from the specified fixed height.
   *
   * @param fixedHeight
   *            the fixed height.
   *
   * @return The available space.
   *
   * @see #trimToContentWidth(double)
   */
  protected double trimToContentHeight(final double fixedHeight) {
    double result = this.margin.trimHeight((int) fixedHeight);
    result = this.frame.getInsets().trimHeight((int) result);
    result = this.padding.trimHeight((int) result);
    return Math.max(result, 0.0);
  }

  private Range trimToContentHeight(final Range r) {
    if (r == null) {
      return null;
    }
    double lowerBound = 0.0;
    double upperBound = Double.POSITIVE_INFINITY;
    if (r.getLowerBound() > 0.0) {
      lowerBound = this.trimToContentHeight(r.getLowerBound());
    }
    if (r.getUpperBound() < Double.POSITIVE_INFINITY) {
      upperBound = this.trimToContentHeight(r.getUpperBound());
    }
    return new Range(lowerBound, upperBound);
  }

  /**
   * Calculate the width available for content after subtracting the margin,
   * border and padding space from the specified fixed width.
   *
   * @param fixedWidth
   *            the fixed width.
   *
   * @return The available space.
   *
   * @see #trimToContentHeight(double)
   */
  protected double trimToContentWidth(final double fixedWidth) {
    double result = this.margin.trimWidth((int) fixedWidth);
    result = this.frame.getInsets().trimWidth((int) result);
    result = this.padding.trimWidth((int) result);
    return Math.max(result, 0.0);
  }

  private Range trimToContentWidth(final Range r) {
    if (r == null) {
      return null;
    }
    double lowerBound = 0.0;
    double upperBound = Double.POSITIVE_INFINITY;
    if (r.getLowerBound() > 0.0) {
      lowerBound = this.trimToContentWidth(r.getLowerBound());
    }
    if (r.getUpperBound() < Double.POSITIVE_INFINITY) {
      upperBound = this.trimToContentWidth(r.getUpperBound());
    }
    return new Range(lowerBound, upperBound);
  }

  /**
   * Provides serialization support.
   *
   * @param stream
   *            the output stream.
   *
   * @throws IOException
   *             if there is an I/O error.
   */
  private void writeObject(final ObjectOutputStream stream)
      throws IOException {
    stream.defaultWriteObject();
    // SerialUtilities.writeShape(this.bounds, stream);
  }

}
TOP

Related Classes of com.positive.charts.block.AbstractBlock

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.