001 /*
002 * $Id: TextPainter.java 3288 2009-03-10 14:36:28Z kschaefe $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021
022 package org.jdesktop.swingx.painter;
023
024 import org.jdesktop.swingx.painter.effects.AreaEffect;
025
026 import javax.swing.*;
027 import javax.swing.text.JTextComponent;
028 import java.awt.*;
029 import java.awt.font.GlyphVector;
030
031 /**
032 * A painter which draws text. If the font, text, and paint are not provided they will be
033 * obtained from the object being painted if it is a Swing text component.
034 *
035 * @author rbair
036 */
037 public class TextPainter extends AbstractAreaPainter<Object> {
038 private String text = "";
039 private Font font = null;
040
041 /** Creates a new instance of TextPainter */
042 public TextPainter() {
043 this("");
044 }
045
046 /**
047 * Create a new TextPainter which will paint the specified text
048 * @param text the text to paint
049 */
050 public TextPainter(String text) {
051 this(text, null, null);
052 }
053
054 /**
055 * Create a new TextPainter which will paint the specified text with the specified font.
056 * @param text the text to paint
057 * @param font the font to paint the text with
058 */
059 public TextPainter(String text, Font font) {
060 this(text, font, null);
061 }
062
063 /**
064 * Create a new TextPainter which will paint the specified text with the specified paint.
065 * @param text the text to paint
066 * @param paint the paint to paint with
067 */
068 public TextPainter(String text, Paint paint) {
069 this(text, null, paint);
070 }
071
072 /**
073 * Create a new TextPainter which will paint the specified text with the specified font and paint.
074 * @param text the text to paint
075 * @param font the font to paint the text with
076 * @param paint the paint to paint with
077 */
078 public TextPainter(String text, Font font, Paint paint) {
079 this.text = text;
080 this.font = font;
081 setFillPaint(paint);
082 }
083
084 /**
085 * Set the font (and font size and style) to be used when drawing the text
086 * @param f the new font
087 */
088 public void setFont(Font f) {
089 Font old = getFont();
090 this.font = f;
091 setDirty(true);
092 firePropertyChange("font", old, getFont());
093 }
094
095 /**
096 * gets the font (and font size and style) to be used when drawing the text
097 * @return the current font
098 */
099 public Font getFont() {
100 return font;
101 }
102
103 /**
104 * Sets the text to draw
105 * @param text the text to draw
106 */
107 public void setText(String text) {
108 String old = getText();
109 this.text = text == null ? "" : text;
110 setDirty(true);
111 firePropertyChange("text", old, getText());
112 }
113
114 /**
115 * gets the text currently used to draw
116 * @return the text to be drawn
117 */
118 public String getText() {
119 return text;
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 @Override
126 protected void doPaint(Graphics2D g, Object component, int width, int height) {
127 Font font = calculateFont(component);
128 if (font != null) {
129 g.setFont(font);
130 }
131
132 Paint paint = getFillPaint();
133 if(paint == null) {
134 if(component instanceof JComponent) {
135 paint = ((JComponent)component).getForeground();
136 }
137 }
138
139 String text = calculateText(component);
140
141 // get the font metrics
142 FontMetrics metrics = g.getFontMetrics(g.getFont());
143 //Rectangle2D rect = metrics.getStringBounds(text,g);
144
145 int tw = metrics.stringWidth(text);
146 int th = metrics.getHeight();
147 Rectangle res = calculateLayout(tw, th, width, height);
148
149 g.translate(res.x, res.y);
150
151 if(isPaintStretched()) {
152 paint = calculateSnappedPaint(paint, res.width, res.height);
153 }
154
155 if (paint != null) {
156 g.setPaint(paint);
157 }
158
159 g.drawString(text, 0, 0 + metrics.getAscent());
160 if(getAreaEffects() != null) {
161 Shape shape = provideShape(g, component, width, height);
162 for(AreaEffect ef : getAreaEffects()) {
163 ef.apply(g, shape, width, height);
164 }
165 }
166 g.translate(-res.x,-res.y);
167 }
168
169 private String calculateText(final Object component) {
170 // prep the text
171 String text = getText();
172 //make components take priority if(text == null || text.trim().equals("")) {
173 if(text != null && !text.trim().equals("")) {
174 return text;
175 }
176 if(component instanceof JTextComponent) {
177 text = ((JTextComponent)component).getText();
178 }
179 if(component instanceof JLabel) {
180 text = ((JLabel)component).getText();
181 }
182 if(component instanceof AbstractButton) {
183 text = ((AbstractButton)component).getText();
184 }
185 return text;
186 }
187
188 private Font calculateFont(final Object component) {
189 // prep the various text attributes
190 Font font = getFont();
191 if (font == null) {
192 if(component instanceof JComponent) {
193 font = ((JComponent)component).getFont();
194 }
195 }
196 if (font == null) {
197 font = new Font("Dialog", Font.PLAIN, 18);
198 }
199 return font;
200 }
201
202 /**
203 * {@inheritDoc}
204 */
205 @Override
206 protected Shape provideShape(Graphics2D g2, Object comp, int width, int height) {
207 Font font = calculateFont(comp);
208 String text = calculateText(comp);
209 FontMetrics metrics = g2.getFontMetrics(font);
210 GlyphVector vect = font.createGlyphVector(g2.getFontRenderContext(),text);
211 return vect.getOutline(0f,0f+ metrics.getAscent());
212 }
213 }