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