    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2008, 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     * ShortTextTitle.java
    029     * -------------------
    030     * (C) Copyright 2008, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * Changes
    036     * -------
    037     * 28-Apr-2008 : Version 1 (DG);
    038     *
    039     */
    040
    041    package org.jfree.chart.title;
    042
    043    import java.awt.FontMetrics;
    044    import java.awt.Graphics2D;
    045    import java.awt.geom.Rectangle2D;
    046
    047    import org.jfree.chart.block.LengthConstraintType;
    048    import org.jfree.chart.block.RectangleConstraint;
    049    import org.jfree.data.Range;
    050    import org.jfree.text.TextUtilities;
    051    import org.jfree.ui.Size2D;
    052    import org.jfree.ui.TextAnchor;
    053
    054    /**
    055     * A text title that is only displayed if the entire text will be visible
    056     * without line wrapping.  It is only intended for use with short titles - for
    057     * general purpose titles, you should use the {@link TextTitle} class.
    058     *
    059     * @since 1.0.10
    060     *
    061     * @see TextTitle
    062     */
    063    public class ShortTextTitle extends TextTitle {
    064
    065        /**
    066         * Creates a new title.
    067         *
    068         * @param text  the text (<code>null</code> not permitted).
    069         */
    070        public ShortTextTitle(String text) {
    071            setText(text);
    072        }
    073
    074        /**
    075         * Performs a layout for this title, subject to the supplied constraint,
    076         * and returns the dimensions required for the title (if the title
    077         * cannot be displayed in the available space, this method will return
    078         * zero width and height for the dimensions).
    079         *
    080         * @param g2  the graphics target.
    081         * @param constraint  the layout constraints.
    082         *
    083         * @return The dimensions for the title.
    084         */
    085        public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
    086            RectangleConstraint cc = toContentConstraint(constraint);
    087            LengthConstraintType w = cc.getWidthConstraintType();
    088            LengthConstraintType h = cc.getHeightConstraintType();
    089            Size2D contentSize = null;
    090            if (w == LengthConstraintType.NONE) {
    091                if (h == LengthConstraintType.NONE) {
    092                    contentSize = arrangeNN(g2);
    093                }
    094                else if (h == LengthConstraintType.RANGE) {
    095                    throw new RuntimeException("Not yet implemented.");
    096                }
    097                else if (h == LengthConstraintType.FIXED) {
    098                    throw new RuntimeException("Not yet implemented.");
    099                }
    100            }
    101            else if (w == LengthConstraintType.RANGE) {
    102                if (h == LengthConstraintType.NONE) {
    103                    contentSize = arrangeRN(g2, cc.getWidthRange());
    104                }
    105                else if (h == LengthConstraintType.RANGE) {
    106                    contentSize = arrangeRR(g2, cc.getWidthRange(),
    107                            cc.getHeightRange());
    108                }
    109                else if (h == LengthConstraintType.FIXED) {
    110                    throw new RuntimeException("Not yet implemented.");
    111                }
    112            }
    113            else if (w == LengthConstraintType.FIXED) {
    114                if (h == LengthConstraintType.NONE) {
    115                    contentSize = arrangeFN(g2, cc.getWidth());
    116                }
    117                else if (h == LengthConstraintType.RANGE) {
    118                    throw new RuntimeException("Not yet implemented.");
    119                }
    120                else if (h == LengthConstraintType.FIXED) {
    121                    throw new RuntimeException("Not yet implemented.");
    122                }
    123            }
    124            if (contentSize.width <= 0.0 || contentSize.height <= 0.0) {
    125                return new Size2D(0.0, 0.0);
    126            }
    127            else {
    128                return new Size2D(calculateTotalWidth(contentSize.getWidth()),
    129                        calculateTotalHeight(contentSize.getHeight()));
    130            }
    131        }
    132
    133        /**
    134         * Arranges the content for this title assuming no bounds on the width
    135         * or the height, and returns the required size.
    136         *
    137         * @param g2  the graphics target.
    138         *
    139         * @return The content size.
    140         */
    141        protected Size2D arrangeNN(Graphics2D g2) {
    142            Range max = new Range(0.0, Float.MAX_VALUE);
    143            return arrangeRR(g2, max, max);
    144        }
    145
    146        /**
    147         * Arranges the content for this title assuming a range constraint for the
    148         * width and no bounds on the height, and returns the required size.
    149         *
    150         * @param g2  the graphics target.
    151         * @param widthRange  the range for the width.
    152         *
    153         * @return The content size.
    154         */
    155        protected Size2D arrangeRN(Graphics2D g2, Range widthRange) {
    156            Size2D s = arrangeNN(g2);
    157            if (widthRange.contains(s.getWidth())) {
    158                return s;
    159            }
    160            double ww = widthRange.constrain(s.getWidth());
    161            return arrangeFN(g2, ww);
    162        }
    163
    164        /**
    165         * Arranges the content for this title assuming a fixed width and no bounds
    166         * on the height, and returns the required size.  This will reflect the
    167         * fact that a text title positioned on the left or right of a chart will
    168         * be rotated by 90 degrees.
    169         *
    170         * @param g2  the graphics target.
    171         * @param w  the width.
    172         *
    173         * @return The content size.
    174         */
    175        protected Size2D arrangeFN(Graphics2D g2, double w) {
    176            g2.setFont(getFont());
    177            FontMetrics fm = g2.getFontMetrics(getFont());
    178            Rectangle2D bounds = TextUtilities.getTextBounds(getText(), g2, fm);
    179            if (bounds.getWidth() <= w) {
    180                return new Size2D(w, bounds.getHeight());
    181            }
    182            else {
    183                return new Size2D(0.0, 0.0);
    184            }
    185        }
    186
    187        /**
    188         * Returns the content size for the title.
    189         *
    190         * @param g2  the graphics device.
    191         * @param widthRange  the width range.
    192         * @param heightRange  the height range.
    193         *
    194         * @return The content size.
    195         */
    196        protected Size2D arrangeRR(Graphics2D g2, Range widthRange,
    197                Range heightRange) {
    198
    199            g2.setFont(getFont());
    200            FontMetrics fm = g2.getFontMetrics(getFont());
    201            Rectangle2D bounds = TextUtilities.getTextBounds(getText(), g2, fm);
    202            if (bounds.getWidth() <= widthRange.getUpperBound()
    203                    && bounds.getHeight() <= heightRange.getUpperBound()) {
    204                return new Size2D(bounds.getWidth(), bounds.getHeight());
    205            }
    206            else {
    207                return new Size2D(0.0, 0.0);
    208            }
    209        }
    210
    211        /**
    212         * Draws the title using the current font and paint.
    213         *
    214         * @param g2  the graphics target.
    215         * @param area  the title area.
    216         * @param params  optional parameters (ignored here).
    217         *
    218         * @return <code>null</code>.
    219         */
    220        public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
    221            if (area.isEmpty()) {
    222                return null;
    223            }
    224            area = trimMargin(area);
    225            drawBorder(g2, area);
    226            area = trimBorder(area);
    227            area = trimPadding(area);
    228            g2.setFont(getFont());
    229            g2.setPaint(getPaint());
    230            TextUtilities.drawAlignedString(getText(), g2, (float) area.getMinX(),
    231                    (float) area.getMinY(), TextAnchor.TOP_LEFT);
    232
    233            return null;
    234        }
    235
    236    }