/*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.text;
import java.awt.*;
import javax.swing.event.*;
/**
* A <code>LabelView</code> is a styled chunk of text
* that represents a view mapped over an element in the
* text model. It caches the character level attributes
* used for rendering.
*
* @author Timothy Prinzing
*/
public class LabelView extends GlyphView implements TabableView {
/**
* Constructs a new view wrapped on an element.
*
* @param elem the element
*/
public LabelView(Element elem) {
super(elem);
}
/**
* Synchronize the view's cached values with the model.
* This causes the font, metrics, color, etc to be
* re-cached if the cache has been invalidated.
*/
final void sync() {
if (font == null) {
setPropertiesFromAttributes();
}
}
/**
* Sets whether or not the view is underlined.
* Note that this setter is protected and is really
* only meant if you need to update some additional
* state when set.
*
* @param u true if the view is underlined, otherwise
* false
* @see #isUnderline
*/
protected void setUnderline(boolean u) {
underline = u;
}
/**
* Sets whether or not the view has a strike/line
* through it.
* Note that this setter is protected and is really
* only meant if you need to update some additional
* state when set.
*
* @param s true if the view has a strike/line
* through it, otherwise false
* @see #isStrikeThrough
*/
protected void setStrikeThrough(boolean s) {
strike = s;
}
/**
* Sets whether or not the view represents a
* superscript.
* Note that this setter is protected and is really
* only meant if you need to update some additional
* state when set.
*
* @param s true if the view represents a
* superscript, otherwise false
* @see #isSuperscript
*/
protected void setSuperscript(boolean s) {
superscript = s;
}
/**
* Sets whether or not the view represents a
* subscript.
* Note that this setter is protected and is really
* only meant if you need to update some additional
* state when set.
*
* @param s true if the view represents a
* subscript, otherwise false
* @see #isSubscript
*/
protected void setSubscript(boolean s) {
subscript = s;
}
/**
* Sets the background color for the view. This method is typically
* invoked as part of configuring this <code>View</code>. If you need
* to customize the background color you should override
* <code>setPropertiesFromAttributes</code> and invoke this method. A
* value of null indicates no background should be rendered, so that the
* background of the parent <code>View</code> will show through.
*
* @param bg background color, or null
* @see #setPropertiesFromAttributes
* @since 1.5
*/
protected void setBackground(Color bg) {
this.bg = bg;
}
/**
* Sets the cached properties from the attributes.
*/
protected void setPropertiesFromAttributes() {
AttributeSet attr = getAttributes();
if (attr != null) {
Document d = getDocument();
if (d instanceof StyledDocument) {
StyledDocument doc = (StyledDocument) d;
font = doc.getFont(attr);
fg = doc.getForeground(attr);
if (attr.isDefined(StyleConstants.Background)) {
bg = doc.getBackground(attr);
} else {
bg = null;
}
setUnderline(StyleConstants.isUnderline(attr));
setStrikeThrough(StyleConstants.isStrikeThrough(attr));
setSuperscript(StyleConstants.isSuperscript(attr));
setSubscript(StyleConstants.isSubscript(attr));
} else {
throw new StateInvariantError("LabelView needs StyledDocument");
}
}
}
/**
* Fetches the <code>FontMetrics</code> used for this view.
* @deprecated FontMetrics are not used for glyph rendering
* when running in the JDK.
*/
@Deprecated
protected FontMetrics getFontMetrics() {
sync();
Container c = getContainer();
return (c != null) ? c.getFontMetrics(font) :
Toolkit.getDefaultToolkit().getFontMetrics(font);
}
/**
* Fetches the background color to use to render the glyphs.
* This is implemented to return a cached background color,
* which defaults to <code>null</code>.
*
* @return the cached background color
* @since 1.3
*/
public Color getBackground() {
sync();
return bg;
}
/**
* Fetches the foreground color to use to render the glyphs.
* This is implemented to return a cached foreground color,
* which defaults to <code>null</code>.
*
* @return the cached foreground color
* @since 1.3
*/
public Color getForeground() {
sync();
return fg;
}
/**
* Fetches the font that the glyphs should be based upon.
* This is implemented to return a cached font.
*
* @return the cached font
*/
public Font getFont() {
sync();
return font;
}
/**
* Determines if the glyphs should be underlined. If true,
* an underline should be drawn through the baseline. This
* is implemented to return the cached underline property.
*
* <p>When you request this property, <code>LabelView</code>
* re-syncs its state with the properties of the
* <code>Element</code>'s <code>AttributeSet</code>.
* If <code>Element</code>'s <code>AttributeSet</code>
* does not have this property set, it will revert to false.
*
* @return the value of the cached
* <code>underline</code> property
* @since 1.3
*/
public boolean isUnderline() {
sync();
return underline;
}
/**
* Determines if the glyphs should have a strikethrough
* line. If true, a line should be drawn through the center
* of the glyphs. This is implemented to return the
* cached <code>strikeThrough</code> property.
*
* <p>When you request this property, <code>LabelView</code>
* re-syncs its state with the properties of the
* <code>Element</code>'s <code>AttributeSet</code>.
* If <code>Element</code>'s <code>AttributeSet</code>
* does not have this property set, it will revert to false.
*
* @return the value of the cached
* <code>strikeThrough</code> property
* @since 1.3
*/
public boolean isStrikeThrough() {
sync();
return strike;
}
/**
* Determines if the glyphs should be rendered as superscript.
* @return the value of the cached subscript property
*
* <p>When you request this property, <code>LabelView</code>
* re-syncs its state with the properties of the
* <code>Element</code>'s <code>AttributeSet</code>.
* If <code>Element</code>'s <code>AttributeSet</code>
* does not have this property set, it will revert to false.
*
* @return the value of the cached
* <code>subscript</code> property
* @since 1.3
*/
public boolean isSubscript() {
sync();
return subscript;
}
/**
* Determines if the glyphs should be rendered as subscript.
*
* <p>When you request this property, <code>LabelView</code>
* re-syncs its state with the properties of the
* <code>Element</code>'s <code>AttributeSet</code>.
* If <code>Element</code>'s <code>AttributeSet</code>
* does not have this property set, it will revert to false.
*
* @return the value of the cached
* <code>superscript</code> property
* @since 1.3
*/
public boolean isSuperscript() {
sync();
return superscript;
}
// --- View methods ---------------------------------------------
/**
* Gives notification from the document that attributes were changed
* in a location that this view is responsible for.
*
* @param e the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#changedUpdate
*/
public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
font = null;
super.changedUpdate(e, a, f);
}
// --- variables ------------------------------------------------
private Font font;
private Color fg;
private Color bg;
private boolean underline;
private boolean strike;
private boolean superscript;
private boolean subscript;
}