    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * ---------------
    028     * LabelBlock.java
    029     * ---------------
    030     * (C) Copyright 2004-2007, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   Pierre-Marie Le Biot;
    034     *
    035     * Changes:
    036     * --------
    037     * 22-Oct-2004 : Version 1 (DG);
    038     * 19-Apr-2005 : Added optional tooltip and URL text items,
    039     *               draw() method now returns entities if
    040     *               requested (DG);
    041     * 13-May-2005 : Added methods to set the font (DG);
    042     * 01-Sep-2005 : Added paint management (PMLB);
    043     *               Implemented equals() and clone() (PublicCloneable) (DG);
    044     * ------------- JFREECHART 1.0.x ---------------------------------------------
    045     * 20-Jul-2006 : Fixed entity area in draw() method (DG);
    046     * 16-Mar-2007 : Fixed serialization when using GradientPaint (DG);
    047     *
    048     */
    049
    050    package org.jfree.chart.block;
    051
    052    import java.awt.Color;
    053    import java.awt.Font;
    054    import java.awt.Graphics2D;
    055    import java.awt.Paint;
    056    import java.awt.Shape;
    057    import java.awt.geom.Rectangle2D;
    058    import java.io.IOException;
    059    import java.io.ObjectInputStream;
    060    import java.io.ObjectOutputStream;
    061
    062    import org.jfree.chart.entity.ChartEntity;
    063    import org.jfree.chart.entity.StandardEntityCollection;
    064    import org.jfree.io.SerialUtilities;
    065    import org.jfree.text.TextBlock;
    066    import org.jfree.text.TextBlockAnchor;
    067    import org.jfree.text.TextUtilities;
    068    import org.jfree.ui.Size2D;
    069    import org.jfree.util.ObjectUtilities;
    070    import org.jfree.util.PaintUtilities;
    071    import org.jfree.util.PublicCloneable;
    072
    073    /**
    074     * A block containing a label.
    075     */
    076    public class LabelBlock extends AbstractBlock
    077                                    implements Block, PublicCloneable {
    078
    079        /** For serialization. */
    080        static final long serialVersionUID = 249626098864178017L;
    081
    082        /**
    083         * The text for the label - retained in case the label needs
    084         * regenerating (for example, to change the font).
    085         */
    086        private String text;
    087
    088        /** The label. */
    089        private TextBlock label;
    090
    091        /** The font. */
    092        private Font font;
    093
    094        /** The tool tip text (can be <code>null</code>). */
    095        private String toolTipText;
    096
    097        /** The URL text (can be <code>null</code>). */
    098        private String urlText;
    099
    100        /** The default color. */
    101        public static final Paint DEFAULT_PAINT = Color.black;
    102
    103        /** The paint. */
    104        private transient Paint paint;
    105
    106        /**
    107         * Creates a new label block.
    108         *
    109         * @param label  the label (<code>null</code> not permitted).
    110         */
    111        public LabelBlock(String label) {
    112            this(label, new Font("SansSerif", Font.PLAIN, 10), DEFAULT_PAINT);
    113        }
    114
    115        /**
    116         * Creates a new label block.
    117         *
    118         * @param text  the text for the label (<code>null</code> not permitted).
    119         * @param font  the font (<code>null</code> not permitted).
    120         */
    121        public LabelBlock(String text, Font font) {
    122            this(text, font, DEFAULT_PAINT);
    123        }
    124
    125        /**
    126         * Creates a new label block.
    127         *
    128         * @param text  the text for the label (<code>null</code> not permitted).
    129         * @param font  the font (<code>null</code> not permitted).
    130         * @param paint the paint (<code>null</code> not permitted).
    131         */
    132        public LabelBlock(String text, Font font, Paint paint) {
    133            this.text = text;
    134            this.paint = paint;
    135            this.label = TextUtilities.createTextBlock(text, font, this.paint);
    136            this.font = font;
    137            this.toolTipText = null;
    138            this.urlText = null;
    139        }
    140
    141        /**
    142         * Returns the font.
    143         *
    144         * @return The font (never <code>null</code>).
    145         *
    146         * @see #setFont(Font)
    147         */
    148        public Font getFont() {
    149            return this.font;
    150        }
    151
    152        /**
    153         * Sets the font and regenerates the label.
    154         *
    155         * @param font  the font (<code>null</code> not permitted).
    156         *
    157         * @see #getFont()
    158         */
    159        public void setFont(Font font) {
    160            if (font == null) {
    161                throw new IllegalArgumentException("Null 'font' argument.");
    162            }
    163            this.font = font;
    164            this.label = TextUtilities.createTextBlock(this.text, font, this.paint);
    165        }
    166
    167        /**
    168         * Returns the paint.
    169         *
    170         * @return The paint (never <code>null</code>).
    171         *
    172         * @see #setPaint(Paint)
    173         */
    174        public Paint getPaint() {
    175            return this.paint;
    176        }
    177
    178        /**
    179         * Sets the paint and regenerates the label.
    180         *
    181         * @param paint  the paint (<code>null</code> not permitted).
    182         *
    183         * @see #getPaint()
    184         */
    185        public void setPaint(Paint paint) {
    186            if (paint == null) {
    187                throw new IllegalArgumentException("Null 'paint' argument.");
    188            }
    189            this.paint = paint;
    190            this.label = TextUtilities.createTextBlock(this.text, this.font,
    191                    this.paint);
    192        }
    193
    194        /**
    195         * Returns the tool tip text.
    196         *
    197         * @return The tool tip text (possibly <code>null</code>).
    198         *
    199         * @see #setToolTipText(String)
    200         */
    201        public String getToolTipText() {
    202            return this.toolTipText;
    203        }
    204
    205        /**
    206         * Sets the tool tip text.
    207         *
    208         * @param text  the text (<code>null</code> permitted).
    209         *
    210         * @see #getToolTipText()
    211         */
    212        public void setToolTipText(String text) {
    213            this.toolTipText = text;
    214        }
    215
    216        /**
    217         * Returns the URL text.
    218         *
    219         * @return The URL text (possibly <code>null</code>).
    220         *
    221         * @see #setURLText(String)
    222         */
    223        public String getURLText() {
    224            return this.urlText;
    225        }
    226
    227        /**
    228         * Sets the URL text.
    229         *
    230         * @param text  the text (<code>null</code> permitted).
    231         *
    232         * @see #getURLText()
    233         */
    234        public void setURLText(String text) {
    235            this.urlText = text;
    236        }
    237
    238        /**
    239         * Arranges the contents of the block, within the given constraints, and
    240         * returns the block size.
    241         *
    242         * @param g2  the graphics device.
    243         * @param constraint  the constraint (<code>null</code> not permitted).
    244         *
    245         * @return The block size (in Java2D units, never <code>null</code>).
    246         */
    247        public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
    248            g2.setFont(this.font);
    249            Size2D s = this.label.calculateDimensions(g2);
    250            return new Size2D(calculateTotalWidth(s.getWidth()),
    251                    calculateTotalHeight(s.getHeight()));
    252        }
    253
    254        /**
    255         * Draws the block.
    256         *
    257         * @param g2  the graphics device.
    258         * @param area  the area.
    259         */
    260        public void draw(Graphics2D g2, Rectangle2D area) {
    261            draw(g2, area, null);
    262        }
    263
    264        /**
    265         * Draws the block within the specified area.
    266         *
    267         * @param g2  the graphics device.
    268         * @param area  the area.
    269         * @param params  ignored (<code>null</code> permitted).
    270         *
    271         * @return Always <code>null</code>.
    272         */
    273        public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
    274            area = trimMargin(area);
    275            drawBorder(g2, area);
    276            area = trimBorder(area);
    277            area = trimPadding(area);
    278
    279            // check if we need to collect chart entities from the container
    280            EntityBlockParams ebp = null;
    281            StandardEntityCollection sec = null;
    282            Shape entityArea = null;
    283            if (params instanceof EntityBlockParams) {
    284                ebp = (EntityBlockParams) params;
    285                if (ebp.getGenerateEntities()) {
    286                    sec = new StandardEntityCollection();
    287                    entityArea = (Shape) area.clone();
    288                }
    289            }
    290            g2.setPaint(this.paint);
    291            g2.setFont(this.font);
    292            this.label.draw(g2, (float) area.getX(), (float) area.getY(),
    293                    TextBlockAnchor.TOP_LEFT);
    294            BlockResult result = null;
    295            if (ebp != null && sec != null) {
    296                if (this.toolTipText != null || this.urlText != null) {
    297                    ChartEntity entity = new ChartEntity(entityArea,
    298                            this.toolTipText, this.urlText);
    299                    sec.add(entity);
    300                    result = new BlockResult();
    301                    result.setEntityCollection(sec);
    302                }
    303            }
    304            return result;
    305        }
    306
    307        /**
    308         * Tests this <code>LabelBlock</code> for equality with an arbitrary
    309         * object.
    310         *
    311         * @param obj  the object (<code>null</code> permitted).
    312         *
    313         * @return A boolean.
    314         */
    315        public boolean equals(Object obj) {
    316            if (!(obj instanceof LabelBlock)) {
    317                return false;
    318            }
    319            LabelBlock that = (LabelBlock) obj;
    320            if (!this.text.equals(that.text)) {
    321                return false;
    322            }
    323            if (!this.font.equals(that.font)) {
    324                return false;
    325            }
    326            if (!PaintUtilities.equal(this.paint, that.paint)) {
    327                return false;
    328            }
    329            if (!ObjectUtilities.equal(this.toolTipText, that.toolTipText)) {
    330                return false;
    331            }
    332            if (!ObjectUtilities.equal(this.urlText, that.urlText)) {
    333                return false;
    334            }
    335            return super.equals(obj);
    336        }
    337
    338        /**
    339         * Returns a clone of this <code>LabelBlock</code> instance.
    340         *
    341         * @return A clone.
    342         *
    343         * @throws CloneNotSupportedException if there is a problem cloning.
    344         */
    345        public Object clone() throws CloneNotSupportedException {
    346            return super.clone();
    347        }
    348
    349        /**
    350         * Provides serialization support.
    351         *
    352         * @param stream  the output stream.
    353         *
    354         * @throws IOException if there is an I/O error.
    355         */
    356        private void writeObject(ObjectOutputStream stream) throws IOException {
    357            stream.defaultWriteObject();
    358            SerialUtilities.writePaint(this.paint, stream);
    359        }
    360
    361        /**
    362         * Provides serialization support.
    363         *
    364         * @param stream  the input stream.
    365         *
    366         * @throws IOException  if there is an I/O error.
    367         * @throws ClassNotFoundException  if there is a classpath problem.
    368         */
    369        private void readObject(ObjectInputStream stream)
    370            throws IOException, ClassNotFoundException {
    371            stream.defaultReadObject();
    372            this.paint = SerialUtilities.readPaint(stream);
    373        }
    374
    375    }