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 public Object draw(Graphics2D g2, Rectangle2D area, Object params) { 219 if (area.isEmpty()) { 220 return null; 221 } 222 area = trimMargin(area); 223 drawBorder(g2, area); 224 area = trimBorder(area); 225 area = trimPadding(area); 226 g2.setFont(getFont()); 227 g2.setPaint(getPaint()); 228 TextUtilities.drawAlignedString(getText(), g2, (float) area.getMinX(), 229 (float) area.getMinY(), TextAnchor.TOP_LEFT); 230 231 return null; 232 } 233 234 }