001/*
002 * $Id: TextPainter.java 4147 2012-02-01 17:13:24Z 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
022package org.jdesktop.swingx.painter;
023
024import static org.jdesktop.swingx.painter.PainterUtils.getComponentFont;
025import static org.jdesktop.swingx.painter.PainterUtils.getForegroundPaint;
026
027import java.awt.Font;
028import java.awt.FontMetrics;
029import java.awt.Graphics2D;
030import java.awt.Paint;
031import java.awt.Rectangle;
032import java.awt.Shape;
033import java.awt.font.GlyphVector;
034
035import javax.swing.AbstractButton;
036import javax.swing.JLabel;
037import javax.swing.text.JTextComponent;
038
039import org.jdesktop.beans.JavaBean;
040import org.jdesktop.swingx.painter.effects.AreaEffect;
041
042/**
043 * A painter which draws text. If the font, text, and paint are not provided they will be
044 * obtained from the object being painted if it is a Swing text component.
045 *
046 * @author rbair
047 */
048@JavaBean
049@SuppressWarnings("nls")
050public class TextPainter extends AbstractAreaPainter<Object> {
051    private String text = "";
052    private Font font = null;
053    
054    /** Creates a new instance of TextPainter */
055    public TextPainter() {
056        this("");
057    }
058    
059    /**
060     * Create a new TextPainter which will paint the specified text
061     * @param text the text to paint
062     */
063    public TextPainter(String text) {
064        this(text, null, null);
065    }
066    
067    /**
068     * Create a new TextPainter which will paint the specified text with the specified font.
069     * @param text the text to paint
070     * @param font the font to paint the text with
071     */
072    public TextPainter(String text, Font font) {
073        this(text, font, null);
074    }
075    
076    /**
077     * Create a new TextPainter which will paint the specified text with the specified paint.
078     * @param text the text to paint
079     * @param paint the paint to paint with
080     */
081    public TextPainter(String text, Paint paint) {
082        this(text, null, paint);
083    }
084    
085    /**
086     * Create a new TextPainter which will paint the specified text with the specified font and paint.
087     * @param text the text to paint
088     * @param font the font to paint the text with
089     * @param paint the paint to paint with
090     */
091    public TextPainter(String text, Font font, Paint paint) {
092        this.text = text;
093        this.font = font;
094        setFillPaint(paint);
095    }
096    
097    /**
098     * Set the font (and font size and style) to be used when drawing the text
099     * @param f the new font
100     */
101    public void setFont(Font f) {
102        Font old = getFont();
103        this.font = f;
104        setDirty(true);
105        firePropertyChange("font", old, getFont());
106    }
107    
108    /**
109     * gets the font (and font size and style) to be used when drawing the text
110     * @return the current font
111     */
112    public Font getFont() {
113        return font;
114    }
115    
116    /**
117     * Sets the text to draw
118     * @param text the text to draw
119     */
120    public void setText(String text) {
121        String old = getText();
122        this.text = text == null ? "" : text;
123        setDirty(true);
124        firePropertyChange("text", old, getText());
125    }
126    
127    /**
128     * gets the text currently used to draw
129     * @return the text to be drawn
130     */
131    public String getText() {
132        return text;
133    }
134
135    /**
136     * {@inheritDoc}
137     */
138    @Override
139    protected void doPaint(Graphics2D g, Object component, int width, int height) {
140        Font f = calculateFont(component);
141        if (f != null) {
142            g.setFont(f);
143        }
144        
145        Paint paint = getForegroundPaint(getFillPaint(), component);
146        String t = calculateText(component);
147        
148        // get the font metrics
149        FontMetrics metrics = g.getFontMetrics(g.getFont());
150        //Rectangle2D rect = metrics.getStringBounds(text,g);
151        
152        int tw = metrics.stringWidth(t);
153        int th = metrics.getHeight();
154        Rectangle res = calculateLayout(tw, th, width, height);
155        
156        g.translate(res.x, res.y);
157        
158        if(isPaintStretched()) {
159            paint = calculateSnappedPaint(paint, res.width, res.height);
160        }
161        
162        if (paint != null) {
163            g.setPaint(paint);
164        }
165        
166        g.drawString(t, 0, 0 + metrics.getAscent());
167        if(getAreaEffects() != null) {
168            Shape shape = provideShape(g, component, width, height);
169            for(AreaEffect ef : getAreaEffects()) {
170                ef.apply(g, shape, width, height);
171            }
172        }
173        g.translate(-res.x,-res.y);
174    }
175    
176    private String calculateText(final Object component) {
177        // prep the text
178        String t = getText();
179        //make components take priority if(text == null || text.trim().equals("")) {
180        if(t != null && !t.trim().equals("")) {
181            return t;
182        }
183        if(component instanceof JTextComponent) {
184            t = ((JTextComponent)component).getText();
185        }
186        if(component instanceof JLabel) {
187            t = ((JLabel)component).getText();
188        }
189        if(component instanceof AbstractButton) {
190            t = ((AbstractButton)component).getText();
191        }
192        return t;
193    }
194    
195    private Font calculateFont(final Object component) {
196        // prep the various text attributes
197        Font f = getComponentFont(getFont(), component);
198        if (f == null) {
199            f = new Font("Dialog", Font.PLAIN, 18);
200        }
201        return f;
202    }
203
204    /**
205     * {@inheritDoc}
206     */
207    @Override
208    protected Shape provideShape(Graphics2D g2, Object comp, int width, int height) {
209        Font f = calculateFont(comp);
210        String t = calculateText(comp);
211        FontMetrics metrics = g2.getFontMetrics(f);
212        GlyphVector vect = f.createGlyphVector(g2.getFontRenderContext(),t);
213        return vect.getOutline(0f,0f+ metrics.getAscent());
214    }
215}