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 }