001    /* LabelView.java -- A view to render styled text
002       Copyright (C) 2005  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.swing.text;
040    
041    import java.awt.Color;
042    import java.awt.Container;
043    import java.awt.Font;
044    import java.awt.FontMetrics;
045    import java.awt.Shape;
046    import java.awt.Toolkit;
047    
048    import javax.swing.event.DocumentEvent;
049    
050    /**
051     * A {@link GlyphView} that caches the textattributes for most effective
052     * rendering.
053     *
054     * @author Roman Kennke (kennke@aicas.com)
055     */
056    public class LabelView extends GlyphView
057    {
058    
059      /**
060       * The background color.
061       */
062      Color background;
063    
064      /**
065       * The foreground color.
066       */
067      Color foreground;
068    
069      /**
070       * The background color.
071       */
072      Font font;
073    
074      /**
075       * The strikethrough flag.
076       */
077      boolean strikeThrough;
078    
079      /**
080       * The underline flag.
081       */
082      boolean underline;
083    
084      /**
085       * The subscript flag.
086       */
087      boolean subscript;
088    
089      /**
090       * The superscript flag.
091       */
092      boolean superscript;
093    
094      /**
095       * Indicates if the attributes must be refetched.
096       */
097      private boolean valid;
098    
099      /**
100       * Creates a new <code>GlyphView</code> for the given <code>Element</code>.
101       *
102       * @param element the element that is rendered by this GlyphView
103       */
104      public LabelView(Element element)
105      {
106        super(element);
107        valid = false;
108      }
109    
110      /**
111       * Loads the properties of this label view from the element's text
112       * attributes. This method is called from the constructor and the
113       * {@link #changedUpdate} method
114       */
115      protected void setPropertiesFromAttributes()
116      {
117        AttributeSet atts = getAttributes();
118        setStrikeThrough(StyleConstants.isStrikeThrough(atts));
119        setSubscript(StyleConstants.isSubscript(atts));
120        setSuperscript(StyleConstants.isSuperscript(atts));
121        setUnderline(StyleConstants.isUnderline(atts));
122    
123        // Determine the font and colors.
124        Document d = getDocument();
125        if (d instanceof StyledDocument)
126          {
127            StyledDocument doc = (StyledDocument) d;
128            font = doc.getFont(atts);
129            if (atts.isDefined(StyleConstants.Background))
130              background = doc.getBackground(atts);
131            else
132              background = null;
133            foreground = doc.getForeground(atts);
134          }
135        valid = true;
136      }
137    
138      /**
139       * Receives notification when text attributes change in the chunk of
140       * text that this view is responsible for. This simply calls
141       * {@link #setPropertiesFromAttributes()}.
142       *
143       * @param e the document event
144       * @param a the allocation of this view
145       * @param vf the view factory to use for creating new views
146       */
147      public void changedUpdate(DocumentEvent e, Shape a, ViewFactory vf)
148      {
149        valid = false;
150        super.changedUpdate(e, a, vf);
151      }
152    
153      /**
154       * Returns the background color for the glyphs.
155       *
156       * @return the background color for the glyphs
157       */
158      public Color getBackground()
159      {
160        if (! valid)
161          setPropertiesFromAttributes();
162        return background;
163      }
164    
165      /**
166       * Sets the background color for the glyphs. A value of <code>null</code>
167       * means the background of the parent view should shine through.
168       *
169       * @param bg the background to set or <code>null</code>
170       *
171       * @since 1.5
172       */
173      protected void setBackground(Color bg)
174      {
175        background = bg;
176      }
177    
178      /**
179       * Returns the foreground color for the glyphs.
180       *
181       * @return the foreground color for the glyphs
182       */
183      public Color getForeground()
184      {
185        if (! valid)
186          setPropertiesFromAttributes();
187        return foreground;
188      }
189    
190      /**
191       * Returns the font for the glyphs.
192       *
193       * @return the font for the glyphs
194       */
195      public Font getFont()
196      {
197        if (! valid)
198          setPropertiesFromAttributes();
199        return font;
200      }
201    
202      /**
203       * Returns the font metrics of the current font.
204       *
205       * @return the font metrics of the current font
206       *
207       * @deprecated this is not used anymore
208       */
209      protected FontMetrics getFontMetrics()
210      {
211        if (! valid)
212          setPropertiesFromAttributes();
213    
214        Container c = getContainer();
215        FontMetrics fm;
216        if (c != null)
217          fm = c.getFontMetrics(font);
218        else
219          fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
220        return fm;
221      }
222    
223      /**
224       * Returns <code>true</code> if the glyphs are rendered underlined,
225       * <code>false</code> otherwise.
226       *
227       * @return <code>true</code> if the glyphs are rendered underlined,
228       *         <code>false</code> otherwise
229       */
230      public boolean isUnderline()
231      {
232        if (! valid)
233          setPropertiesFromAttributes();
234        return underline;
235      }
236    
237      /**
238       * Sets the underline flag.
239       *
240       * @param flag <code>true</code> if the glyphs are rendered underlined,
241       *             <code>false</code> otherwise
242       */
243      protected void setUnderline(boolean flag)
244      {
245        underline = flag;
246      }
247    
248      /**
249       * Returns <code>true</code> if the glyphs are rendered as subscript,
250       * <code>false</code> otherwise.
251       *
252       * @return <code>true</code> if the glyphs are rendered as subscript,
253       *         <code>false</code> otherwise
254       */
255      public boolean isSubscript()
256      {
257        if (! valid)
258          setPropertiesFromAttributes();
259        return subscript;
260      }
261    
262      /**
263       * Sets the subscript flag.
264       *
265       * @param flag <code>true</code> if the glyphs are rendered as subscript,
266       *             <code>false</code> otherwise
267       */
268      protected void setSubscript(boolean flag)
269      {
270        subscript = flag;
271      }
272    
273      /**
274       * Returns <code>true</code> if the glyphs are rendered as superscript,
275       * <code>false</code> otherwise.
276       *
277       * @return <code>true</code> if the glyphs are rendered as superscript,
278       *         <code>false</code> otherwise
279       */
280      public boolean isSuperscript()
281      {
282        if (! valid)
283          setPropertiesFromAttributes();
284        return superscript;
285      }
286    
287      /**
288       * Sets the superscript flag.
289       *
290       * @param flag <code>true</code> if the glyphs are rendered as superscript,
291       *             <code>false</code> otherwise
292       */
293      protected void setSuperscript(boolean flag)
294      {
295        superscript = flag;
296      }
297    
298      /**
299       * Returns <code>true</code> if the glyphs are rendered strike-through,
300       * <code>false</code> otherwise.
301       *
302       * @return <code>true</code> if the glyphs are rendered strike-through,
303       *         <code>false</code> otherwise
304       */
305      public boolean isStrikeThrough()
306      {
307        if (! valid)
308          setPropertiesFromAttributes();
309        return strikeThrough;
310      }
311    
312      /**
313       * Sets the strike-through flag.
314       *
315       * @param flag <code>true</code> if the glyphs are rendered strike-through,
316       *             <code>false</code> otherwise
317       */
318      protected void setStrikeThrough(boolean flag)
319      {
320        strikeThrough = flag;
321      }
322    }