FileDocCategorySizeDatePackage
StyleContext.javaAPI DocJava SE 5 API52667Fri Aug 26 14:58:16 BST 2005javax.swing.text

StyleContext

public class StyleContext extends Object implements Serializable, AbstractDocument$AttributeContext
A pool of styles and their associated resources. This class determines the lifetime of a group of resources by being a container that holds caches for various resources such as font and color that get reused by the various style definitions. This can be shared by multiple documents if desired to maximize the sharing of related resources.

This class also provides efficient support for small sets of attributes and compresses them by sharing across uses and taking advantage of their immutable nature. Since many styles are replicated, the potential for sharing is significant, and copies can be extremely cheap. Larger sets reduce the possibility of sharing, and therefore revert automatically to a less space-efficient implementation.

Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see {@link java.beans.XMLEncoder}.

author
Timothy Prinzing
version
1.78 05/05/04

Fields Summary
private static StyleContext
defaultContext
public static final String
DEFAULT_STYLE
The name given to the default logical style attached to paragraphs.
private static Hashtable
freezeKeyMap
private static Hashtable
thawKeyMap
private Style
styles
private transient FontKey
fontSearch
private transient Hashtable
fontTable
private transient Map
attributesPool
private transient MutableAttributeSet
search
private int
unusedSets
Number of immutable sets that are not currently being used. This helps indicate when the sets need to be cleaned out of the hashtable they are stored in.
static final int
THRESHOLD
The threshold for no longer sharing the set of attributes in an immutable table.
Constructors Summary
public StyleContext()
Creates a new StyleContext object.

        styles = new NamedStyle(null);
        addStyle(DEFAULT_STYLE, null);
    
Methods Summary
public synchronized javax.swing.text.AttributeSetaddAttribute(javax.swing.text.AttributeSet old, java.lang.Object name, java.lang.Object value)
Adds an attribute to the given set, and returns the new representative set.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
old the old attribute set
param
name the non-null attribute name
param
value the attribute value
return
the updated attribute set
see
MutableAttributeSet#addAttribute

        if ((old.getAttributeCount() + 1) <= getCompressionThreshold()) {
            // build a search key and find/create an immutable and unique
            // set.
            search.removeAttributes(search);
            search.addAttributes(old);
            search.addAttribute(name, value);
            reclaim(old);
            return getImmutableUniqueSet();
        }
        MutableAttributeSet ma = getMutableAttributeSet(old);
        ma.addAttribute(name, value);
        return ma;
    
public synchronized javax.swing.text.AttributeSetaddAttributes(javax.swing.text.AttributeSet old, javax.swing.text.AttributeSet attr)
Adds a set of attributes to the element.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
old the old attribute set
param
attr the attributes to add
return
the updated attribute set
see
MutableAttributeSet#addAttribute

        if ((old.getAttributeCount() + attr.getAttributeCount()) <= getCompressionThreshold()) {
            // build a search key and find/create an immutable and unique
            // set.
            search.removeAttributes(search);
            search.addAttributes(old);
            search.addAttributes(attr);
            reclaim(old);
            return getImmutableUniqueSet();
        }
        MutableAttributeSet ma = getMutableAttributeSet(old);
        ma.addAttributes(attr);
        return ma;
    
public voidaddChangeListener(javax.swing.event.ChangeListener l)
Adds a listener to track when styles are added or removed.

param
l the change listener

        styles.addChangeListener(l);
    
public javax.swing.text.StyleaddStyle(java.lang.String nm, javax.swing.text.Style parent)
Adds a new style into the style hierarchy. Style attributes resolve from bottom up so an attribute specified in a child will override an attribute specified in the parent.

param
nm the name of the style (must be unique within the collection of named styles in the document). The name may be null if the style is unnamed, but the caller is responsible for managing the reference returned as an unnamed style can't be fetched by name. An unnamed style may be useful for things like character attribute overrides such as found in a style run.
param
parent the parent style. This may be null if unspecified attributes need not be resolved in some other style.
return
the created style

        Style style = new NamedStyle(nm, parent); 
        if (nm != null) {
            // add a named style, a class of attributes
            styles.addAttribute(nm, style);
        }
        return style;
    
protected javax.swing.text.MutableAttributeSetcreateLargeAttributeSet(javax.swing.text.AttributeSet a)
Create a large set of attributes that should trade off space for time. This set will not be shared. This is a hook for subclasses that want to alter the behavior of the larger attribute storage format (which is SimpleAttributeSet by default). This can be reimplemented to return a MutableAttributeSet that provides some sort of attribute conversion.

param
a The set of attributes to be represented in the the larger form.

        return new SimpleAttributeSet(a);
    
protected javax.swing.text.StyleContext$SmallAttributeSetcreateSmallAttributeSet(javax.swing.text.AttributeSet a)
Create a compact set of attributes that might be shared. This is a hook for subclasses that want to alter the behavior of SmallAttributeSet. This can be reimplemented to return an AttributeSet that provides some sort of attribute conversion.

param
a The set of attributes to be represented in the the compact form.

	return new SmallAttributeSet(a);
    
public java.awt.ColorgetBackground(javax.swing.text.AttributeSet attr)
Takes a set of attributes and turn it into a background color specification. This might be used to specify things like brighter, more hue, etc. By default it simply returns the value specified by the StyleConstants.Background attribute.

param
attr the set of attributes
return
the color

	return StyleConstants.getBackground(attr);
    
public javax.swing.event.ChangeListener[]getChangeListeners()
Returns an array of all the ChangeListeners added to this StyleContext with addChangeListener().

return
all of the ChangeListeners added or an empty array if no listeners have been added
since
1.4

        return ((NamedStyle)styles).getChangeListeners();
    
protected intgetCompressionThreshold()
Returns the maximum number of key/value pairs to try and compress into unique/immutable sets. Any sets above this limit will use hashtables and be a MutableAttributeSet.

return
the threshold

        return THRESHOLD;
    
public static final javax.swing.text.StyleContextgetDefaultStyleContext()
Returns default AttributeContext shared by all documents that don't bother to define/supply their own context.

return
the context

        if (defaultContext == null) {
            defaultContext = new StyleContext();
        }
        return defaultContext;
    
public javax.swing.text.AttributeSetgetEmptySet()
Fetches an empty AttributeSet.

return
the set

        return SimpleAttributeSet.EMPTY;
    
public java.awt.FontgetFont(javax.swing.text.AttributeSet attr)
Gets the font from an attribute set. This is implemented to try and fetch a cached font for the given AttributeSet, and if that fails the font features are resolved and the font is fetched from the low-level font cache.

param
attr the attribute set
return
the font

        // PENDING(prinz) add cache behavior
        int style = Font.PLAIN;
        if (StyleConstants.isBold(attr)) {
            style |= Font.BOLD;
        }
        if (StyleConstants.isItalic(attr)) {
            style |= Font.ITALIC;
        }
        String family = StyleConstants.getFontFamily(attr);
        int size = StyleConstants.getFontSize(attr);

	/**
	 * if either superscript or subscript is
	 * is set, we need to reduce the font size
	 * by 2.
	 */
	if (StyleConstants.isSuperscript(attr) ||
	    StyleConstants.isSubscript(attr)) {
	    size -= 2;
	}

        return getFont(family, style, size);
    
public java.awt.FontgetFont(java.lang.String family, int style, int size)
Gets a new font. This returns a Font from a cache if a cached font exists. If not, a Font is added to the cache. This is basically a low-level cache for 1.1 font features.

param
family the font family (such as "Monospaced")
param
style the style of the font (such as Font.PLAIN)
param
size the point size >= 1
return
the new font

        fontSearch.setValue(family, style, size);
        Font f = (Font) fontTable.get(fontSearch);
        if (f == null) {
            // haven't seen this one yet.
            f = new Font(family, style, size);
            if (! FontManager.fontSupportsDefaultEncoding(f)) {
                f = FontManager.getCompositeFontUIResource(f);
            }
            FontKey key = new FontKey(family, style, size);
            fontTable.put(key, f);
        }
        return f;
    
public java.awt.FontMetricsgetFontMetrics(java.awt.Font f)
Returns font metrics for a font.

param
f the font
return
the metrics

        // The Toolkit implementations cache, so we just forward
        // to the default toolkit.
        return Toolkit.getDefaultToolkit().getFontMetrics(f);
    
public java.awt.ColorgetForeground(javax.swing.text.AttributeSet attr)
Takes a set of attributes and turn it into a foreground color specification. This might be used to specify things like brighter, more hue, etc. By default it simply returns the value specified by the StyleConstants.Foreground attribute.

param
attr the set of attributes
return
the color

	return StyleConstants.getForeground(attr);
    
javax.swing.text.AttributeSetgetImmutableUniqueSet()
Search for an existing attribute set using the current search parameters. If a matching set is found, return it. If a match is not found, we create a new set and add it to the pool.

	// PENDING(prinz) should consider finding a alternative to
	// generating extra garbage on search key.
	SmallAttributeSet key = createSmallAttributeSet(search);
	WeakReference reference = (WeakReference)attributesPool.get(key);
        SmallAttributeSet a;
        if (reference == null 
	    || (a = (SmallAttributeSet)reference.get()) == null) {
            a = key;
            attributesPool.put(a, new WeakReference(a));
        } 
        return a;
    
javax.swing.text.MutableAttributeSetgetMutableAttributeSet(javax.swing.text.AttributeSet a)
Creates a mutable attribute set to hand out because the current needs are too big to try and use a shared version.

        if (a instanceof MutableAttributeSet &&
	    a != SimpleAttributeSet.EMPTY) {
            return (MutableAttributeSet) a;
        }
        return createLargeAttributeSet(a);
    
public static java.lang.ObjectgetStaticAttribute(java.lang.Object key)
Returns the object previously registered with registerStaticAttributeKey.

	if (thawKeyMap == null || key == null) {
	    return null;
	}
	return thawKeyMap.get(key);
    
public static java.lang.ObjectgetStaticAttributeKey(java.lang.Object key)
Returns the String that key will be registered with

see
#getStaticAttribute
see
#registerStaticAttributeKey

        return key.getClass().getName() + "." + key.toString();
    
public javax.swing.text.StylegetStyle(java.lang.String nm)
Fetches a named style previously added to the document

param
nm the name of the style
return
the style

        return (Style) styles.getAttribute(nm);
    
public java.util.EnumerationgetStyleNames()
Fetches the names of the styles defined.

return
the list of names as an enumeration

        return styles.getAttributeNames();
    
public static voidreadAttributeSet(java.io.ObjectInputStream in, javax.swing.text.MutableAttributeSet a)
Reads a set of attributes from the given object input stream that have been previously written out with writeAttributeSet. This will try to restore keys that were static objects to the static objects in the current virtual machine considering only those keys that have been registered with the registerStaticAttributeKey method. The attributes retrieved from the stream will be placed into the given mutable set.

param
in the object stream to read the attribute data from.
param
a the attribute set to place the attribute definitions in.
exception
ClassNotFoundException passed upward if encountered when reading the object stream.
exception
IOException passed upward if encountered when reading the object stream.


        int n = in.readInt();
        for (int i = 0; i < n; i++) {
            Object key = in.readObject();
            Object value = in.readObject();
	    if (thawKeyMap != null) {
		Object staticKey = thawKeyMap.get(key);
		if (staticKey != null) {
		    key = staticKey;
		}
		Object staticValue = thawKeyMap.get(value);
		if (staticValue != null) {
		    value = staticValue;
		}
	    }
            a.addAttribute(key, value);
        }
    
public voidreadAttributes(java.io.ObjectInputStream in, javax.swing.text.MutableAttributeSet a)
Context-specific handling of reading in attributes

        readAttributeSet(in, a);
    
private voidreadObject(java.io.ObjectInputStream s)

        fontSearch = new FontKey(null, 0, 0);
        fontTable = new Hashtable();
        search = new SimpleAttributeSet();
        attributesPool = Collections.
	    synchronizedMap(new WeakHashMap());
        s.defaultReadObject();
    
public voidreclaim(javax.swing.text.AttributeSet a)
Returns a set no longer needed by the MutableAttributeSet implmentation. This is useful for operation under 1.1 where there are no weak references. This would typically be called by the finalize method of the MutableAttributeSet implementation.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
a the set to reclaim

	if (SwingUtilities.isEventDispatchThread()) {
	    attributesPool.size(); // force WeakHashMap to expunge stale entries
	} 
	// if current thread is not event dispatching thread
	// do not bother with expunging stale entries.
    
public static voidregisterStaticAttributeKey(java.lang.Object key)
Registers an object as a static object that is being used as a key in attribute sets. This allows the key to be treated specially for serialization.

For operation under a 1.1 virtual machine, this uses the value returned by toString concatenated to the classname. The value returned by toString should not have the class reference in it (ie it should be reimplemented from the definition in Object) in order to be the same when recomputed later.

param
key the non-null object key

        String ioFmt = key.getClass().getName() + "." + key.toString();
        if (freezeKeyMap == null) {
            freezeKeyMap = new Hashtable();
            thawKeyMap = new Hashtable();
        }
        freezeKeyMap.put(key, ioFmt);
        thawKeyMap.put(ioFmt, key);
    
public synchronized javax.swing.text.AttributeSetremoveAttribute(javax.swing.text.AttributeSet old, java.lang.Object name)
Removes an attribute from the set.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
old the old set of attributes
param
name the non-null attribute name
return
the updated attribute set
see
MutableAttributeSet#removeAttribute

        if ((old.getAttributeCount() - 1) <= getCompressionThreshold()) {
            // build a search key and find/create an immutable and unique
            // set.
            search.removeAttributes(search);
            search.addAttributes(old);
            search.removeAttribute(name);
            reclaim(old);
            return getImmutableUniqueSet();
        }
        MutableAttributeSet ma = getMutableAttributeSet(old);
        ma.removeAttribute(name);
        return ma;
    
public synchronized javax.swing.text.AttributeSetremoveAttributes(javax.swing.text.AttributeSet old, java.util.Enumeration names)
Removes a set of attributes for the element.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
old the old attribute set
param
names the attribute names
return
the updated attribute set
see
MutableAttributeSet#removeAttributes

        if (old.getAttributeCount() <= getCompressionThreshold()) {
            // build a search key and find/create an immutable and unique
            // set.
            search.removeAttributes(search);
            search.addAttributes(old);
            search.removeAttributes(names);
            reclaim(old);
            return getImmutableUniqueSet();
        }
        MutableAttributeSet ma = getMutableAttributeSet(old);
        ma.removeAttributes(names);
        return ma;
    
public synchronized javax.swing.text.AttributeSetremoveAttributes(javax.swing.text.AttributeSet old, javax.swing.text.AttributeSet attrs)
Removes a set of attributes for the element.

This method is thread safe, although most Swing methods are not. Please see Threads and Swing for more information.

param
old the old attribute set
param
attrs the attributes
return
the updated attribute set
see
MutableAttributeSet#removeAttributes

        if (old.getAttributeCount() <= getCompressionThreshold()) {
            // build a search key and find/create an immutable and unique
            // set.
            search.removeAttributes(search);
            search.addAttributes(old);
            search.removeAttributes(attrs);
            reclaim(old);
            return getImmutableUniqueSet();
        }
        MutableAttributeSet ma = getMutableAttributeSet(old);
        ma.removeAttributes(attrs);
        return ma;
    
public voidremoveChangeListener(javax.swing.event.ChangeListener l)
Removes a listener that was tracking styles being added or removed.

param
l the change listener

        styles.removeChangeListener(l);
    
public voidremoveStyle(java.lang.String nm)
Removes a named style previously added to the document.

param
nm the name of the style to remove

        styles.removeAttribute(nm);
    
synchronized voidremoveUnusedSets()
Clean the unused immutable sets out of the hashtable.

	attributesPool.size(); // force WeakHashMap to expunge stale entries
    
public java.lang.StringtoString()
Converts a StyleContext to a String.

return
the string

        removeUnusedSets();
        String s = "";
        Iterator iterator = attributesPool.keySet().iterator();
        while (iterator.hasNext()) {
            SmallAttributeSet set = (SmallAttributeSet)iterator.next();
            s = s + set + "\n";
        }
        return s;
    
public static voidwriteAttributeSet(java.io.ObjectOutputStream out, javax.swing.text.AttributeSet a)
Writes a set of attributes to the given object stream for the purpose of serialization. This will take special care to deal with static attribute keys that have been registered wit the registerStaticAttributeKey method. Any attribute key not regsitered as a static key will be serialized directly. All values are expected to be serializable.

param
out the output stream
param
a the attribute set
exception
IOException on any I/O error

        int n = a.getAttributeCount();
        out.writeInt(n);
        Enumeration keys = a.getAttributeNames();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            if (key instanceof Serializable) {
                out.writeObject(key);
            } else {
                Object ioFmt = freezeKeyMap.get(key);
		if (ioFmt == null) {
		    throw new NotSerializableException(key.getClass().
			         getName() + " is not serializable as a key in an AttributeSet");
		}
                out.writeObject(ioFmt);
            }
            Object value = a.getAttribute(key);
            Object ioFmt = freezeKeyMap.get(value);
            if (value instanceof Serializable) {
                out.writeObject((ioFmt != null) ? ioFmt : value);
            } else {
		if (ioFmt == null) {
		    throw new NotSerializableException(value.getClass().
			         getName() + " is not serializable as a value in an AttributeSet");
		}
                out.writeObject(ioFmt);
            }
        }
    
public voidwriteAttributes(java.io.ObjectOutputStream out, javax.swing.text.AttributeSet a)
Context-specific handling of writing out attributes

        writeAttributeSet(out, a);				      
    
private voidwriteObject(java.io.ObjectOutputStream s)

        // clean out unused sets before saving
        removeUnusedSets();

        s.defaultWriteObject();