1 /*
   2  * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing.text;
  26 
  27 import java.awt.*;
  28 import javax.swing.event.*;
  29 
  30 /**
  31  * A <code>LabelView</code> is a styled chunk of text
  32  * that represents a view mapped over an element in the
  33  * text model.  It caches the character level attributes
  34  * used for rendering.
  35  *
  36  * @author Timothy Prinzing
  37  */
  38 public class LabelView extends GlyphView implements TabableView {
  39 
  40     /**
  41      * Constructs a new view wrapped on an element.
  42      *
  43      * @param elem the element
  44      */
  45     public LabelView(Element elem) {
  46         super(elem);
  47     }
  48 
  49     /**
  50      * Synchronize the view's cached values with the model.
  51      * This causes the font, metrics, color, etc to be
  52      * re-cached if the cache has been invalidated.
  53      */
  54     final void sync() {
  55         if (font == null) {
  56             setPropertiesFromAttributes();
  57         }
  58     }
  59 
  60     /**
  61      * Sets whether or not the view is underlined.
  62      * Note that this setter is protected and is really
  63      * only meant if you need to update some additional
  64      * state when set.
  65      *
  66      * @param u true if the view is underlined, otherwise
  67      *          false
  68      * @see #isUnderline
  69      */
  70     protected void setUnderline(boolean u) {
  71         underline = u;
  72     }
  73 
  74     /**
  75      * Sets whether or not the view has a strike/line
  76      * through it.
  77      * Note that this setter is protected and is really
  78      * only meant if you need to update some additional
  79      * state when set.
  80      *
  81      * @param s true if the view has a strike/line
  82      *          through it, otherwise false
  83      * @see #isStrikeThrough
  84      */
  85     protected void setStrikeThrough(boolean s) {
  86         strike = s;
  87     }
  88 
  89 
  90     /**
  91      * Sets whether or not the view represents a
  92      * superscript.
  93      * Note that this setter is protected and is really
  94      * only meant if you need to update some additional
  95      * state when set.
  96      *
  97      * @param s true if the view represents a
  98      *          superscript, otherwise false
  99      * @see #isSuperscript
 100      */
 101     protected void setSuperscript(boolean s) {
 102         superscript = s;
 103     }
 104 
 105     /**
 106      * Sets whether or not the view represents a
 107      * subscript.
 108      * Note that this setter is protected and is really
 109      * only meant if you need to update some additional
 110      * state when set.
 111      *
 112      * @param s true if the view represents a
 113      *          subscript, otherwise false
 114      * @see #isSubscript
 115      */
 116     protected void setSubscript(boolean s) {
 117         subscript = s;
 118     }
 119 
 120     /**
 121      * Sets the background color for the view. This method is typically
 122      * invoked as part of configuring this <code>View</code>. If you need
 123      * to customize the background color you should override
 124      * <code>setPropertiesFromAttributes</code> and invoke this method. A
 125      * value of null indicates no background should be rendered, so that the
 126      * background of the parent <code>View</code> will show through.
 127      *
 128      * @param bg background color, or null
 129      * @see #setPropertiesFromAttributes
 130      * @since 1.5
 131      */
 132     protected void setBackground(Color bg) {
 133         this.bg = bg;
 134     }
 135 
 136     /**
 137      * Sets the cached properties from the attributes.
 138      */
 139     protected void setPropertiesFromAttributes() {
 140         AttributeSet attr = getAttributes();
 141         if (attr != null) {
 142             Document d = getDocument();
 143             if (d instanceof StyledDocument) {
 144                 StyledDocument doc = (StyledDocument) d;
 145                 font = doc.getFont(attr);
 146                 fg = doc.getForeground(attr);
 147                 if (attr.isDefined(StyleConstants.Background)) {
 148                     bg = doc.getBackground(attr);
 149                 } else {
 150                     bg = null;
 151                 }
 152                 setUnderline(StyleConstants.isUnderline(attr));
 153                 setStrikeThrough(StyleConstants.isStrikeThrough(attr));
 154                 setSuperscript(StyleConstants.isSuperscript(attr));
 155                 setSubscript(StyleConstants.isSubscript(attr));
 156             } else {
 157                 throw new StateInvariantError("LabelView needs StyledDocument");
 158             }
 159         }
 160      }
 161 
 162     /**
 163      * Fetches the <code>FontMetrics</code> used for this view.
 164      * @deprecated FontMetrics are not used for glyph rendering
 165      *  when running in the JDK.
 166      */
 167     @Deprecated
 168     protected FontMetrics getFontMetrics() {
 169         sync();
 170         Container c = getContainer();
 171         return (c != null) ? c.getFontMetrics(font) :
 172             Toolkit.getDefaultToolkit().getFontMetrics(font);
 173     }
 174 
 175     /**
 176      * Fetches the background color to use to render the glyphs.
 177      * This is implemented to return a cached background color,
 178      * which defaults to <code>null</code>.
 179      *
 180      * @return the cached background color
 181      * @since 1.3
 182      */
 183     public Color getBackground() {
 184         sync();
 185         return bg;
 186     }
 187 
 188     /**
 189      * Fetches the foreground color to use to render the glyphs.
 190      * This is implemented to return a cached foreground color,
 191      * which defaults to <code>null</code>.
 192      *
 193      * @return the cached foreground color
 194      * @since 1.3
 195      */
 196     public Color getForeground() {
 197         sync();
 198         return fg;
 199     }
 200 
 201     /**
 202      * Fetches the font that the glyphs should be based upon.
 203      * This is implemented to return a cached font.
 204      *
 205      * @return the cached font
 206      */
 207      public Font getFont() {
 208         sync();
 209         return font;
 210     }
 211 
 212     /**
 213      * Determines if the glyphs should be underlined.  If true,
 214      * an underline should be drawn through the baseline.  This
 215      * is implemented to return the cached underline property.
 216      *
 217      * <p>When you request this property, <code>LabelView</code>
 218      * re-syncs its state with the properties of the
 219      * <code>Element</code>'s <code>AttributeSet</code>.
 220      * If <code>Element</code>'s <code>AttributeSet</code>
 221      * does not have this property set, it will revert to false.
 222      *
 223      * @return the value of the cached
 224      *     <code>underline</code> property
 225      * @since 1.3
 226      */
 227     public boolean isUnderline() {
 228         sync();
 229         return underline;
 230     }
 231 
 232     /**
 233      * Determines if the glyphs should have a strikethrough
 234      * line.  If true, a line should be drawn through the center
 235      * of the glyphs.  This is implemented to return the
 236      * cached <code>strikeThrough</code> property.
 237      *
 238      * <p>When you request this property, <code>LabelView</code>
 239      * re-syncs its state with the properties of the
 240      * <code>Element</code>'s <code>AttributeSet</code>.
 241      * If <code>Element</code>'s <code>AttributeSet</code>
 242      * does not have this property set, it will revert to false.
 243      *
 244      * @return the value of the cached
 245      *     <code>strikeThrough</code> property
 246      * @since 1.3
 247      */
 248     public boolean isStrikeThrough() {
 249         sync();
 250         return strike;
 251     }
 252 
 253     /**
 254      * Determines if the glyphs should be rendered as superscript.
 255      * @return the value of the cached subscript property
 256      *
 257      * <p>When you request this property, <code>LabelView</code>
 258      * re-syncs its state with the properties of the
 259      * <code>Element</code>'s <code>AttributeSet</code>.
 260      * If <code>Element</code>'s <code>AttributeSet</code>
 261      * does not have this property set, it will revert to false.
 262      *
 263      * @return the value of the cached
 264      *     <code>subscript</code> property
 265      * @since 1.3
 266      */
 267     public boolean isSubscript() {
 268         sync();
 269         return subscript;
 270     }
 271 
 272     /**
 273      * Determines if the glyphs should be rendered as subscript.
 274      *
 275      * <p>When you request this property, <code>LabelView</code>
 276      * re-syncs its state with the properties of the
 277      * <code>Element</code>'s <code>AttributeSet</code>.
 278      * If <code>Element</code>'s <code>AttributeSet</code>
 279      * does not have this property set, it will revert to false.
 280      *
 281      * @return the value of the cached
 282      *     <code>superscript</code> property
 283      * @since 1.3
 284      */
 285     public boolean isSuperscript() {
 286         sync();
 287         return superscript;
 288     }
 289 
 290     // --- View methods ---------------------------------------------
 291 
 292     /**
 293      * Gives notification from the document that attributes were changed
 294      * in a location that this view is responsible for.
 295      *
 296      * @param e the change information from the associated document
 297      * @param a the current allocation of the view
 298      * @param f the factory to use to rebuild if the view has children
 299      * @see View#changedUpdate
 300      */
 301     public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
 302         font = null;
 303         super.changedUpdate(e, a, f);
 304     }
 305 
 306     // --- variables ------------------------------------------------
 307 
 308     private Font font;
 309     private Color fg;
 310     private Color bg;
 311     private boolean underline;
 312     private boolean strike;
 313     private boolean superscript;
 314     private boolean subscript;
 315 
 316 }