001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2013, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 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 041package org.jfree.chart.title; 042 043import java.awt.FontMetrics; 044import java.awt.Graphics2D; 045import java.awt.geom.Rectangle2D; 046 047import org.jfree.chart.block.LengthConstraintType; 048import org.jfree.chart.block.RectangleConstraint; 049import org.jfree.data.Range; 050import org.jfree.text.TextUtilities; 051import org.jfree.ui.Size2D; 052import 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 */ 063public 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 @Override 086 public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) { 087 RectangleConstraint cc = toContentConstraint(constraint); 088 LengthConstraintType w = cc.getWidthConstraintType(); 089 LengthConstraintType h = cc.getHeightConstraintType(); 090 Size2D contentSize = null; 091 if (w == LengthConstraintType.NONE) { 092 if (h == LengthConstraintType.NONE) { 093 contentSize = arrangeNN(g2); 094 } 095 else if (h == LengthConstraintType.RANGE) { 096 throw new RuntimeException("Not yet implemented."); 097 } 098 else if (h == LengthConstraintType.FIXED) { 099 throw new RuntimeException("Not yet implemented."); 100 } 101 } 102 else if (w == LengthConstraintType.RANGE) { 103 if (h == LengthConstraintType.NONE) { 104 contentSize = arrangeRN(g2, cc.getWidthRange()); 105 } 106 else if (h == LengthConstraintType.RANGE) { 107 contentSize = arrangeRR(g2, cc.getWidthRange(), 108 cc.getHeightRange()); 109 } 110 else if (h == LengthConstraintType.FIXED) { 111 throw new RuntimeException("Not yet implemented."); 112 } 113 } 114 else if (w == LengthConstraintType.FIXED) { 115 if (h == LengthConstraintType.NONE) { 116 contentSize = arrangeFN(g2, cc.getWidth()); 117 } 118 else if (h == LengthConstraintType.RANGE) { 119 throw new RuntimeException("Not yet implemented."); 120 } 121 else if (h == LengthConstraintType.FIXED) { 122 throw new RuntimeException("Not yet implemented."); 123 } 124 } 125 assert contentSize != null; 126 if (contentSize.width <= 0.0 || contentSize.height <= 0.0) { 127 return new Size2D(0.0, 0.0); 128 } 129 else { 130 return new Size2D(calculateTotalWidth(contentSize.getWidth()), 131 calculateTotalHeight(contentSize.getHeight())); 132 } 133 } 134 135 /** 136 * Arranges the content for this title assuming no bounds on the width 137 * or the height, and returns the required size. 138 * 139 * @param g2 the graphics target. 140 * 141 * @return The content size. 142 */ 143 @Override 144 protected Size2D arrangeNN(Graphics2D g2) { 145 Range max = new Range(0.0, Float.MAX_VALUE); 146 return arrangeRR(g2, max, max); 147 } 148 149 /** 150 * Arranges the content for this title assuming a range constraint for the 151 * width and no bounds on the height, and returns the required size. 152 * 153 * @param g2 the graphics target. 154 * @param widthRange the range for the width. 155 * 156 * @return The content size. 157 */ 158 @Override 159 protected Size2D arrangeRN(Graphics2D g2, Range widthRange) { 160 Size2D s = arrangeNN(g2); 161 if (widthRange.contains(s.getWidth())) { 162 return s; 163 } 164 double ww = widthRange.constrain(s.getWidth()); 165 return arrangeFN(g2, ww); 166 } 167 168 /** 169 * Arranges the content for this title assuming a fixed width and no bounds 170 * on the height, and returns the required size. This will reflect the 171 * fact that a text title positioned on the left or right of a chart will 172 * be rotated by 90 degrees. 173 * 174 * @param g2 the graphics target. 175 * @param w the width. 176 * 177 * @return The content size. 178 */ 179 @Override 180 protected Size2D arrangeFN(Graphics2D g2, double w) { 181 g2.setFont(getFont()); 182 FontMetrics fm = g2.getFontMetrics(getFont()); 183 Rectangle2D bounds = TextUtilities.getTextBounds(getText(), g2, fm); 184 if (bounds.getWidth() <= w) { 185 return new Size2D(w, bounds.getHeight()); 186 } 187 else { 188 return new Size2D(0.0, 0.0); 189 } 190 } 191 192 /** 193 * Returns the content size for the title. 194 * 195 * @param g2 the graphics device. 196 * @param widthRange the width range. 197 * @param heightRange the height range. 198 * 199 * @return The content size. 200 */ 201 @Override 202 protected Size2D arrangeRR(Graphics2D g2, Range widthRange, 203 Range heightRange) { 204 205 g2.setFont(getFont()); 206 FontMetrics fm = g2.getFontMetrics(getFont()); 207 Rectangle2D bounds = TextUtilities.getTextBounds(getText(), g2, fm); 208 if (bounds.getWidth() <= widthRange.getUpperBound() 209 && bounds.getHeight() <= heightRange.getUpperBound()) { 210 return new Size2D(bounds.getWidth(), bounds.getHeight()); 211 } 212 else { 213 return new Size2D(0.0, 0.0); 214 } 215 } 216 217 /** 218 * Draws the title using the current font and paint. 219 * 220 * @param g2 the graphics target. 221 * @param area the title area. 222 * @param params optional parameters (ignored here). 223 * 224 * @return <code>null</code>. 225 */ 226 @Override 227 public Object draw(Graphics2D g2, Rectangle2D area, Object params) { 228 if (area.isEmpty()) { 229 return null; 230 } 231 area = trimMargin(area); 232 drawBorder(g2, area); 233 area = trimBorder(area); 234 area = trimPadding(area); 235 g2.setFont(getFont()); 236 g2.setPaint(getPaint()); 237 TextUtilities.drawAlignedString(getText(), g2, (float) area.getMinX(), 238 (float) area.getMinY(), TextAnchor.TOP_LEFT); 239 return null; 240 } 241 242}