    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     * ImageTitle.java
    029     * ---------------
    030     * (C) Copyright 2000-2007, by David Berry and Contributors;
    031     *
    032     * Original Author:  David Berry;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * $Id: ImageTitle.java,v 1.8.2.3 2007/02/02 15:03:19 mungady Exp $
    036     *
    037     * Changes (from 18-Sep-2001)
    038     * --------------------------
    039     * 18-Sep-2001 : Added standard header (DG);
    040     * 07-Nov-2001 : Separated the JCommon Class Library classes, JFreeChart now
    041     *               requires jcommon.jar (DG);
    042     * 09-Jan-2002 : Updated Javadoc comments (DG);
    043     * 07-Feb-2002 : Changed blank space around title from Insets --> Spacer, to
    044     *               allow for relative or absolute spacing (DG);
    045     * 25-Jun-2002 : Updated import statements (DG);
    046     * 23-Sep-2002 : Fixed errors reported by Checkstyle (DG);
    047     * 26-Nov-2002 : Added method for drawing images at left or right (DG);
    048     * 22-Sep-2003 : Added checks that the Image can never be null (TM).
    049     * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0
    050     *               release (DG);
    051     * 02-Feb-2005 : Changed padding mechanism for all titles (DG);
    052     * 20-Apr-2005 : Added new draw() method (DG);
    053     * ------------- JFREECHART 1.0.x ---------------------------------------------
    054     * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG);
    055     *
    056     */
    057
    058    package org.jfree.chart.title;
    059
    060    import java.awt.Graphics2D;
    061    import java.awt.Image;
    062    import java.awt.geom.Rectangle2D;
    063
    064    import org.jfree.chart.event.TitleChangeEvent;
    065    import org.jfree.ui.HorizontalAlignment;
    066    import org.jfree.ui.RectangleEdge;
    067    import org.jfree.ui.RectangleInsets;
    068    import org.jfree.ui.Size2D;
    069    import org.jfree.ui.VerticalAlignment;
    070
    071    /**
    072     * A chart title that displays an image.  This is useful, for example, if you
    073     * have an image of your corporate logo and want to use as a footnote or part
    074     * of a title in a chart you create.
    075     * <P>
    076     * ImageTitle needs an image passed to it in the constructor.  For ImageTitle
    077     * to work, you must have already loaded this image from its source (disk or
    078     * URL).  It is recomended you use something like
    079     * Toolkit.getDefaultToolkit().getImage() to get the image.  Then, use
    080     * MediaTracker or some other message to make sure the image is fully loaded
    081     * from disk.
    082     */
    083    public class ImageTitle extends Title {
    084
    085        /** The title image. */
    086        private Image image;
    087
    088        /**
    089         * Creates a new image title.
    090         *
    091         * @param image  the image (<code>null</code> not permitted).
    092         */
    093        public ImageTitle(Image image) {
    094            this(image, image.getHeight(null), image.getWidth(null),
    095                    Title.DEFAULT_POSITION, Title.DEFAULT_HORIZONTAL_ALIGNMENT,
    096                    Title.DEFAULT_VERTICAL_ALIGNMENT, Title.DEFAULT_PADDING);
    097        }
    098
    099        /**
    100         * Creates a new image title.
    101         *
    102         * @param image  the image (<code>null</code> not permitted).
    103         * @param position  the title position.
    104         * @param horizontalAlignment  the horizontal alignment.
    105         * @param verticalAlignment  the vertical alignment.
    106         */
    107        public ImageTitle(Image image, RectangleEdge position,
    108                          HorizontalAlignment horizontalAlignment,
    109                          VerticalAlignment verticalAlignment) {
    110
    111            this(image, image.getHeight(null), image.getWidth(null),
    112                    position, horizontalAlignment, verticalAlignment,
    113                    Title.DEFAULT_PADDING);
    114        }
    115
    116        /**
    117         * Creates a new image title with the given image scaled to the given
    118         * width and height in the given location.
    119         *
    120         * @param image  the image (<code>null</code> not permitted).
    121         * @param height  the height used to draw the image.
    122         * @param width  the width used to draw the image.
    123         * @param position  the title position.
    124         * @param horizontalAlignment  the horizontal alignment.
    125         * @param verticalAlignment  the vertical alignment.
    126         * @param padding  the amount of space to leave around the outside of the
    127         *                 title.
    128         */
    129        public ImageTitle(Image image, int height, int width,
    130                          RectangleEdge position,
    131                          HorizontalAlignment horizontalAlignment,
    132                          VerticalAlignment verticalAlignment,
    133                          RectangleInsets padding) {
    134
    135            super(position, horizontalAlignment, verticalAlignment, padding);
    136            if (image == null) {
    137                throw new NullPointerException("Null 'image' argument.");
    138            }
    139            this.image = image;
    140            setHeight(height);
    141            setWidth(width);
    142
    143        }
    144
    145        /**
    146         * Returns the image for the title.
    147         *
    148         * @return The image for the title (never <code>null</code>).
    149         */
    150        public Image getImage() {
    151            return this.image;
    152        }
    153
    154        /**
    155         * Sets the image for the title and notifies registered listeners that the
    156         * title has been modified.
    157         *
    158         * @param image  the new image (<code>null</code> not permitted).
    159         */
    160        public void setImage(Image image) {
    161            if (image == null) {
    162                throw new NullPointerException("Null 'image' argument.");
    163            }
    164            this.image = image;
    165            notifyListeners(new TitleChangeEvent(this));
    166        }
    167
    168        /**
    169         * Draws the title on a Java 2D graphics device (such as the screen or a
    170         * printer).
    171         *
    172         * @param g2  the graphics device.
    173         * @param titleArea  the area within which the title (and plot) should be
    174         *                   drawn.
    175         */
    176        public void draw(Graphics2D g2, Rectangle2D titleArea) {
    177
    178            RectangleEdge position = getPosition();
    179            if (position == RectangleEdge.TOP || position == RectangleEdge.BOTTOM) {
    180                drawHorizontal(g2, titleArea);
    181            }
    182            else if (position == RectangleEdge.LEFT
    183                         || position == RectangleEdge.RIGHT) {
    184                drawVertical(g2, titleArea);
    185            }
    186            else {
    187                throw new RuntimeException("Invalid title position.");
    188            }
    189        }
    190
    191        /**
    192         * Draws the title on a Java 2D graphics device (such as the screen or a
    193         * printer).
    194         *
    195         * @param g2  the graphics device.
    196         * @param chartArea  the area within which the title (and plot) should be
    197         *                   drawn.
    198         *
    199         * @return The size of the area used by the title.
    200         */
    201        protected Size2D drawHorizontal(Graphics2D g2, Rectangle2D chartArea) {
    202
    203            double startY = 0.0;
    204            double topSpace = 0.0;
    205            double bottomSpace = 0.0;
    206            double leftSpace = 0.0;
    207            double rightSpace = 0.0;
    208
    209            double w = getWidth();
    210            double h = getHeight();
    211            RectangleInsets padding = getPadding();
    212            topSpace = padding.calculateTopOutset(h);
    213            bottomSpace = padding.calculateBottomOutset(h);
    214            leftSpace = padding.calculateLeftOutset(w);
    215            rightSpace = padding.calculateRightOutset(w);
    216
    217            if (getPosition() == RectangleEdge.TOP) {
    218                startY = chartArea.getY() + topSpace;
    219            }
    220            else {
    221                startY = chartArea.getY() + chartArea.getHeight() - bottomSpace - h;
    222            }
    223
    224            // what is our alignment?
    225            HorizontalAlignment horizontalAlignment = getHorizontalAlignment();
    226            double startX = 0.0;
    227            if (horizontalAlignment == HorizontalAlignment.CENTER) {
    228                startX = chartArea.getX() + leftSpace + chartArea.getWidth() / 2.0
    229                         - w / 2.0;
    230            }
    231            else if (horizontalAlignment == HorizontalAlignment.LEFT) {
    232                startX = chartArea.getX() + leftSpace;
    233            }
    234            else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
    235                startX = chartArea.getX() + chartArea.getWidth() - rightSpace - w;
    236            }
    237            g2.drawImage(this.image, (int) startX, (int) startY, (int) w, (int) h,
    238                    null);
    239
    240            return new Size2D(chartArea.getWidth() + leftSpace + rightSpace,
    241                h + topSpace + bottomSpace);
    242
    243        }
    244
    245        /**
    246         * Draws the title on a Java 2D graphics device (such as the screen or a
    247         * printer).
    248         *
    249         * @param g2  the graphics device.
    250         * @param chartArea  the area within which the title (and plot) should be
    251         *                   drawn.
    252         *
    253         * @return The size of the area used by the title.
    254         */
    255        protected Size2D drawVertical(Graphics2D g2, Rectangle2D chartArea) {
    256
    257            double startX = 0.0;
    258            double topSpace = 0.0;
    259            double bottomSpace = 0.0;
    260            double leftSpace = 0.0;
    261            double rightSpace = 0.0;
    262
    263            double w = getWidth();
    264            double h = getHeight();
    265
    266            RectangleInsets padding = getPadding();
    267            if (padding != null) {
    268                topSpace = padding.calculateTopOutset(h);
    269                bottomSpace = padding.calculateBottomOutset(h);
    270                leftSpace = padding.calculateLeftOutset(w);
    271                rightSpace = padding.calculateRightOutset(w);
    272            }
    273
    274            if (getPosition() == RectangleEdge.LEFT) {
    275                startX = chartArea.getX() + leftSpace;
    276            }
    277            else {
    278                startX = chartArea.getMaxX() - rightSpace - w;
    279            }
    280
    281            // what is our alignment?
    282            VerticalAlignment alignment = getVerticalAlignment();
    283            double startY = 0.0;
    284            if (alignment == VerticalAlignment.CENTER) {
    285                startY = chartArea.getMinY() + topSpace
    286                         + chartArea.getHeight() / 2.0 - h / 2.0;
    287            }
    288            else if (alignment == VerticalAlignment.TOP) {
    289                startY = chartArea.getMinY() + topSpace;
    290            }
    291            else if (alignment == VerticalAlignment.BOTTOM) {
    292                startY = chartArea.getMaxY() - bottomSpace - h;
    293            }
    294
    295            g2.drawImage(this.image, (int) startX, (int) startY, (int) w, (int) h,
    296                    null);
    297
    298            return new Size2D(chartArea.getWidth() + leftSpace + rightSpace,
    299                h + topSpace + bottomSpace);
    300
    301        }
    302
    303        /**
    304         * Draws the block within the specified area.
    305         *
    306         * @param g2  the graphics device.
    307         * @param area  the area.
    308         * @param params  ignored (<code>null</code> permitted).
    309         *
    310         * @return Always <code>null</code>.
    311         */
    312        public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
    313            draw(g2, area);
    314            return null;
    315        }
    316
    317    }