/* * Copyright (c) 1997, 2008, 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 java.util.*;import java.io.*; import javax.swing.SwingUtilities;import javax.swing.event.ChangeListener;import javax.swing.event.EventListenerList;import javax.swing.event.ChangeEvent;import java.lang.ref.WeakReference;import java.util.WeakHashMap; import sun.font.FontUtilities; /** * 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. * <p> * 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. * <p> * <strong>Warning:</strong> * 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 JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @author Timothy Prinzing */public class StyleContext implements Serializable, AbstractDocument.AttributeContext { /** * Returns default AttributeContext shared by all documents that * don't bother to define/supply their own context. * * @return the context */ public static final StyleContext getDefaultStyleContext() { if (defaultContext == null) { defaultContext = new StyleContext(); } return defaultContext; } private static StyleContext defaultContext; /** * Creates a new StyleContext object. */ public StyleContext() { styles = new NamedStyle(null); addStyle(DEFAULT_STYLE, null); } /** * 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 */ public Style addStyle(String nm, Style parent) { Style style = new NamedStyle(nm, parent); if (nm != null) { // add a named style, a class of attributes styles.addAttribute(nm, style); } return style; } /** * Removes a named style previously added to the document. * * @param nm the name of the style to remove */ public void removeStyle(String nm) { styles.removeAttribute(nm); } /** * Fetches a named style previously added to the document * * @param nm the name of the style * @return the style */ public Style getStyle(String nm) { return (Style) styles.getAttribute(nm); } /** * Fetches the names of the styles defined. * * @return the list of names as an enumeration */ public Enumeration<?> getStyleNames() { return styles.getAttributeNames(); } /** * Adds a listener to track when styles are added * or removed. * * @param l the change listener */ public void addChangeListener(ChangeListener l) { styles.addChangeListener(l); } /** * Removes a listener that was tracking styles being * added or removed. * * @param l the change listener */ public void removeChangeListener(ChangeListener l) { styles.removeChangeListener(l); } /** * Returns an array of all the <code>ChangeListener</code>s added * to this StyleContext with addChangeListener(). * * @return all of the <code>ChangeListener</code>s added or an empty * array if no listeners have been added * @since 1.4 */ public ChangeListener[] getChangeListeners() { return ((NamedStyle)styles).getChangeListeners(); } /** * 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 */ public Font getFont(AttributeSet attr) { // 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); } /** * 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 */ public Color getForeground(AttributeSet attr) { return StyleConstants.getForeground(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 */ public Color getBackground(AttributeSet attr) { return StyleConstants.getBackground(attr); } /** * 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 */ public Font getFont(String family, int style, int size) { fontSearch.setValue(family, style, size); Font f = fontTable.get(fontSearch); if (f == null) { // haven't seen this one yet. Style defaultStyle = getStyle(StyleContext.DEFAULT_STYLE); if (defaultStyle != null) { final String FONT_ATTRIBUTE_KEY = "FONT_ATTRIBUTE_KEY"; Font defaultFont = (Font) defaultStyle.getAttribute(FONT_ATTRIBUTE_KEY); if (defaultFont != null && defaultFont.getFamily().equalsIgnoreCase(family)) { f = defaultFont.deriveFont(style, size); } } if (f == null) { f = new Font(family, style, size); } if (! FontUtilities.fontSupportsDefaultEncoding(f)) { f = FontUtilities.getCompositeFontUIResource(f); } FontKey key = new FontKey(family, style, size); fontTable.put(key, f); } return f; } /** * Returns font metrics for a font. * * @param f the font * @return the metrics */ public FontMetrics getFontMetrics(Font f) { // The Toolkit implementations cache, so we just forward // to the default toolkit. return Toolkit.getDefaultToolkit().getFontMetrics(f); } // --- AttributeContext methods -------------------- /** * Adds an attribute to the given set, and returns * the new representative set. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> 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 */ public synchronized AttributeSet addAttribute(AttributeSet old, Object name, Object value) { 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; } /** * Adds a set of attributes to the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param attr the attributes to add * @return the updated attribute set * @see MutableAttributeSet#addAttribute */ public synchronized AttributeSet addAttributes(AttributeSet old, AttributeSet attr) { 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; } /** * Removes an attribute from the set. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> 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 */ public synchronized AttributeSet removeAttribute(AttributeSet old, Object name) { 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; } /** * Removes a set of attributes for the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param names the attribute names * @return the updated attribute set * @see MutableAttributeSet#removeAttributes */ public synchronized AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { 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; } /** * Removes a set of attributes for the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param attrs the attributes * @return the updated attribute set * @see MutableAttributeSet#removeAttributes */ public synchronized AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) { 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; } /** * Fetches an empty AttributeSet. * * @return the set */ public AttributeSet getEmptySet() { return SimpleAttributeSet.EMPTY; } /** * 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. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param a the set to reclaim */ public void reclaim(AttributeSet a) { 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. } // --- local methods ----------------------------------------------- /** * 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 */ protected int getCompressionThreshold() { return THRESHOLD; } /** * 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. */ protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) { return new SmallAttributeSet(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. */ protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {Lines 1–500 of 1621. Load more
/* * Copyright (c) 1997, 2008, 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 java.util.*; import java.io.*; import javax.swing.SwingUtilities; import javax.swing.event.ChangeListener; import javax.swing.event.EventListenerList; import javax.swing.event.ChangeEvent; import java.lang.ref.WeakReference; import java.util.WeakHashMap; import sun.font.FontUtilities; /** * 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. * <p> * 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. * <p> * <strong>Warning:</strong> * 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 JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @author Timothy Prinzing */ public class StyleContext implements Serializable, AbstractDocument.AttributeContext { /** * Returns default AttributeContext shared by all documents that * don't bother to define/supply their own context. * * @return the context */ public static final StyleContext getDefaultStyleContext() { if (defaultContext == null) { defaultContext = new StyleContext(); } return defaultContext; } private static StyleContext defaultContext; /** * Creates a new StyleContext object. */ public StyleContext() { styles = new NamedStyle(null); addStyle(DEFAULT_STYLE, null); } /** * 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 */ public Style addStyle(String nm, Style parent) { Style style = new NamedStyle(nm, parent); if (nm != null) { // add a named style, a class of attributes styles.addAttribute(nm, style); } return style; } /** * Removes a named style previously added to the document. * * @param nm the name of the style to remove */ public void removeStyle(String nm) { styles.removeAttribute(nm); } /** * Fetches a named style previously added to the document * * @param nm the name of the style * @return the style */ public Style getStyle(String nm) { return (Style) styles.getAttribute(nm); } /** * Fetches the names of the styles defined. * * @return the list of names as an enumeration */ public Enumeration<?> getStyleNames() { return styles.getAttributeNames(); } /** * Adds a listener to track when styles are added * or removed. * * @param l the change listener */ public void addChangeListener(ChangeListener l) { styles.addChangeListener(l); } /** * Removes a listener that was tracking styles being * added or removed. * * @param l the change listener */ public void removeChangeListener(ChangeListener l) { styles.removeChangeListener(l); } /** * Returns an array of all the <code>ChangeListener</code>s added * to this StyleContext with addChangeListener(). * * @return all of the <code>ChangeListener</code>s added or an empty * array if no listeners have been added * @since 1.4 */ public ChangeListener[] getChangeListeners() { return ((NamedStyle)styles).getChangeListeners(); } /** * 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 */ public Font getFont(AttributeSet attr) { // 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); } /** * 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 */ public Color getForeground(AttributeSet attr) { return StyleConstants.getForeground(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 */ public Color getBackground(AttributeSet attr) { return StyleConstants.getBackground(attr); } /** * 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 */ public Font getFont(String family, int style, int size) { fontSearch.setValue(family, style, size); Font f = fontTable.get(fontSearch); if (f == null) { // haven't seen this one yet. Style defaultStyle = getStyle(StyleContext.DEFAULT_STYLE); if (defaultStyle != null) { final String FONT_ATTRIBUTE_KEY = "FONT_ATTRIBUTE_KEY"; Font defaultFont = (Font) defaultStyle.getAttribute(FONT_ATTRIBUTE_KEY); if (defaultFont != null && defaultFont.getFamily().equalsIgnoreCase(family)) { f = defaultFont.deriveFont(style, size); } } if (f == null) { f = new Font(family, style, size); } if (! FontUtilities.fontSupportsDefaultEncoding(f)) { f = FontUtilities.getCompositeFontUIResource(f); } FontKey key = new FontKey(family, style, size); fontTable.put(key, f); } return f; } /** * Returns font metrics for a font. * * @param f the font * @return the metrics */ public FontMetrics getFontMetrics(Font f) { // The Toolkit implementations cache, so we just forward // to the default toolkit. return Toolkit.getDefaultToolkit().getFontMetrics(f); } // --- AttributeContext methods -------------------- /** * Adds an attribute to the given set, and returns * the new representative set. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> 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 */ public synchronized AttributeSet addAttribute(AttributeSet old, Object name, Object value) { 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; } /** * Adds a set of attributes to the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param attr the attributes to add * @return the updated attribute set * @see MutableAttributeSet#addAttribute */ public synchronized AttributeSet addAttributes(AttributeSet old, AttributeSet attr) { 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; } /** * Removes an attribute from the set. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> 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 */ public synchronized AttributeSet removeAttribute(AttributeSet old, Object name) { 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; } /** * Removes a set of attributes for the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param names the attribute names * @return the updated attribute set * @see MutableAttributeSet#removeAttributes */ public synchronized AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { 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; } /** * Removes a set of attributes for the element. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param old the old attribute set * @param attrs the attributes * @return the updated attribute set * @see MutableAttributeSet#removeAttributes */ public synchronized AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) { 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; } /** * Fetches an empty AttributeSet. * * @return the set */ public AttributeSet getEmptySet() { return SimpleAttributeSet.EMPTY; } /** * 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. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How * to Use Threads</A> for more information. * * @param a the set to reclaim */ public void reclaim(AttributeSet a) { 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. } // --- local methods ----------------------------------------------- /** * 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 */ protected int getCompressionThreshold() { return THRESHOLD; } /** * 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. */ protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) { return new SmallAttributeSet(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. */ protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {