⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stylesheet.java

📁 JAVA 所有包
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * @(#)StyleSheet.java	1.91 05/11/30 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package javax.swing.text.html;import sun.swing.SwingUtilities2;import java.util.*;import java.awt.*;import java.io.*;import java.net.*;import javax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.border.*;import javax.swing.event.ChangeListener;import javax.swing.text.*;/** * Support for defining the visual characteristics of * HTML views being rendered.  The StyleSheet is used to * translate the HTML model into visual characteristics. * This enables views to be customized by a look-and-feel, * multiple views over the same model can be rendered * differently, etc.  This can be thought of as a CSS * rule repository.  The key for CSS attributes is an * object of type CSS.Attribute.  The type of the value * is up to the StyleSheet implementation, but the * <code>toString</code> method is required * to return a string representation of CSS value. * <p> * The primary entry point for HTML View implementations * to get their attributes is the  * <a href="#getViewAttributes">getViewAttributes</a> * method.  This should be implemented to establish the * desired policy used to associate attributes with the view. * Each HTMLEditorKit (i.e. and therefore each associated * JEditorPane) can have its own StyleSheet, but by default one * sheet will be shared by all of the HTMLEditorKit instances. * HTMLDocument instance can also have a StyleSheet, which * holds the document-specific CSS specifications. * <p> * In order for Views to store less state and therefore be * more lightweight, the StyleSheet can act as a factory for * painters that handle some of the rendering tasks.  This allows * implementations to determine what they want to cache * and have the sharing potentially at the level that a * selector is common to multiple views.  Since the StyleSheet * may be used by views over multiple documents and typically * the HTML attributes don't effect the selector being used, * the potential for sharing is significant. * <p> * The rules are stored as named styles, and other information * is stored to translate the context of an element to a  * rule quickly.  The following code fragment will display * the named styles, and therefore the CSS rules contained. * <code><pre> * &nbsp;  * &nbsp; import java.util.*; * &nbsp; import javax.swing.text.*; * &nbsp; import javax.swing.text.html.*; * &nbsp;  * &nbsp; public class ShowStyles { * &nbsp;  * &nbsp;     public static void main(String[] args) { * &nbsp; 	HTMLEditorKit kit = new HTMLEditorKit(); * &nbsp; 	HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); * &nbsp; 	StyleSheet styles = doc.getStyleSheet(); * &nbsp; 	 * &nbsp; 	Enumeration rules = styles.getStyleNames(); * &nbsp; 	while (rules.hasMoreElements()) { * &nbsp; 	    String name = (String) rules.nextElement(); * &nbsp; 	    Style rule = styles.getStyle(name); * &nbsp; 	    System.out.println(rule.toString()); * &nbsp; 	} * &nbsp; 	System.exit(0); * &nbsp;     } * &nbsp; } * &nbsp;  * </pre></code> * <p> * The semantics for when a CSS style should overide visual attributes * defined by an element are not well defined. For example, the html * <code>&lt;body bgcolor=red&gt;</code> makes the body have a red * background. But if the html file also contains the CSS rule * <code>body { background: blue }</code> it becomes less clear as to * what color the background of the body should be. The current * implemention gives visual attributes defined in the element the * highest precedence, that is they are always checked before any styles. * Therefore, in the previous example the background would have a * red color as the body element defines the background color to be red. * <p> * As already mentioned this supports CSS. We don't support the full CSS * spec. Refer to the javadoc of the CSS class to see what properties * we support. The two major CSS parsing related * concepts we do not currently * support are pseudo selectors, such as <code>A:link { color: red }</code>, * and the <code>important</code> modifier. * <p> * <font color="red">Note: This implementation is currently * incomplete.  It can be replaced with alternative implementations * that are complete.  Future versions of this class will provide * better CSS support.</font> * * @author  Timothy Prinzing * @author  Sunita Mani * @author  Sara Swanson * @author  Jill Nakata * @version 1.91 11/30/05 */public class StyleSheet extends StyleContext {    // As the javadoc states, this class maintains a mapping between    // a CSS selector (such as p.bar) and a Style.    // This consists of a number of parts:    // . Each selector is broken down into its constituent simple selectors,    //   and stored in an inverted graph, for example:    //     p { color: red } ol p { font-size: 10pt } ul p { font-size: 12pt }    //   results in the graph:    //          root    //           |    //           p    //          / \    //         ol ul    //   each node (an instance of SelectorMapping) has an associated    //   specificity and potentially a Style.    // . Every rule that is asked for (either by way of getRule(String) or    //   getRule(HTML.Tag, Element)) results in a unique instance of    //   ResolvedStyle. ResolvedStyles contain the AttributeSets from the    //   SelectorMapping.    // . When a new rule is created it is inserted into the graph, and    //   the AttributeSets of each ResolvedStyles are updated appropriately.    // . This class creates special AttributeSets, LargeConversionSet and    //   SmallConversionSet, that maintain a mapping between StyleConstants    //   and CSS so that developers that wish to use the StyleConstants    //   methods can do so.    // . When one of the AttributeSets is mutated by way of a    //   StyleConstants key, all the associated CSS keys are removed. This is    //   done so that the two representations don't get out of sync. For    //   example, if the developer adds StyleConsants.BOLD, FALSE to an    //   AttributeSet that contains HTML.Tag.B, the HTML.Tag.B entry will    //   be removed.    /**     * Construct a StyleSheet     */    public StyleSheet() {	super();	selectorMapping = new SelectorMapping(0);	resolvedStyles = new Hashtable();	if (css == null) {	    css = new CSS();	}    }    /**     * Fetches the style to use to render the given type     * of HTML tag.  The element given is representing     * the tag and can be used to determine the nesting     * for situations where the attributes will differ     * if nesting inside of elements.     *     * @param t the type to translate to visual attributes     * @param e the element representing the tag; the element     *  can be used to determine the nesting for situations where     *  the attributes will differ if nested inside of other     *  elements     * @return the set of CSS attributes to use to render     *  the tag     */    public Style getRule(HTML.Tag t, Element e) {        SearchBuffer sb = SearchBuffer.obtainSearchBuffer();        try {            // Build an array of all the parent elements.            Vector searchContext = sb.getVector();            for (Element p = e; p != null; p = p.getParentElement()) {                searchContext.addElement(p);            }            // Build a fully qualified selector.            int              n = searchContext.size();            StringBuffer     cacheLookup = sb.getStringBuffer();            AttributeSet     attr;            String           eName;            Object           name;            // >= 1 as the HTML.Tag for the 0th element is passed in.            for (int counter = n - 1; counter >= 1; counter--) {                e = (Element)searchContext.elementAt(counter);                attr = e.getAttributes();                name = attr.getAttribute(StyleConstants.NameAttribute);		eName = name.toString();                cacheLookup.append(eName);                if (attr != null) {                    if (attr.isDefined(HTML.Attribute.ID)) {                        cacheLookup.append('#');                        cacheLookup.append(attr.getAttribute					   (HTML.Attribute.ID));                    }                    else if (attr.isDefined(HTML.Attribute.CLASS)) {                        cacheLookup.append('.');                        cacheLookup.append(attr.getAttribute					   (HTML.Attribute.CLASS));                    }                }                cacheLookup.append(' ');            }            cacheLookup.append(t.toString());	    e = (Element)searchContext.elementAt(0);	    attr = e.getAttributes();	    if (e.isLeaf()) {		// For leafs, we use the second tier attributes.		Object testAttr = attr.getAttribute(t);		if (testAttr instanceof AttributeSet) {		    attr = (AttributeSet)testAttr;		}		else {		    attr = null;		}	    }            if (attr != null) {                if (attr.isDefined(HTML.Attribute.ID)) {                    cacheLookup.append('#');                    cacheLookup.append(attr.getAttribute(HTML.Attribute.ID));                }                else if (attr.isDefined(HTML.Attribute.CLASS)) {                    cacheLookup.append('.');                    cacheLookup.append(attr.getAttribute				       (HTML.Attribute.CLASS));                }            }            Style style = getResolvedStyle(cacheLookup.toString(),					   searchContext, t);	    return style;        }        finally {            SearchBuffer.releaseSearchBuffer(sb);        }    }    /**     * Fetches the rule that best matches the selector given     * in string form. Where <code>selector</code> is a space separated     * String of the element names. For example, <code>selector</code>     * might be 'html body tr td''<p>     * The attributes of the returned Style will change     * as rules are added and removed. That is if you to ask for a rule     * with a selector "table p" and a new rule was added with a selector     * of "p" the returned Style would include the new attributes from     * the rule "p".     */    public Style getRule(String selector) {	selector = cleanSelectorString(selector);	if (selector != null) {	    Style style = getResolvedStyle(selector);	    return style;	}	return null;    }    /**     * Adds a set of rules to the sheet.  The rules are expected to     * be in valid CSS format.  Typically this would be called as     * a result of parsing a &lt;style&gt; tag.     */    public void addRule(String rule) {	if (rule != null) {            //tweaks to control display properties            //see BasicEditorPaneUI            final String baseUnitsDisable = "BASE_SIZE_DISABLE";            final String baseUnits = "BASE_SIZE ";            final String w3cLengthUnitsEnable = "W3C_LENGTH_UNITS_ENABLE";            final String w3cLengthUnitsDisable = "W3C_LENGTH_UNITS_DISABLE";            if (rule == baseUnitsDisable) {                sizeMap = sizeMapDefault;            } else if (rule.startsWith(baseUnits)) {                rebaseSizeMap(Integer.                              parseInt(rule.substring(baseUnits.length())));            } else if (rule == w3cLengthUnitsEnable) {                w3cLengthUnits = true;            } else if (rule == w3cLengthUnitsDisable) {                w3cLengthUnits = false;            } else {                CssParser parser = new CssParser();                try {                    parser.parse(getBase(), new StringReader(rule), false, false);                } catch (IOException ioe) { }            }	}    }    /**     * Translates a CSS declaration to an AttributeSet that represents     * the CSS declaration.  Typically this would be called as a     * result of encountering an HTML style attribute.     */    public AttributeSet getDeclaration(String decl) {	if (decl == null) {	    return SimpleAttributeSet.EMPTY;	}	CssParser parser = new CssParser();	return parser.parseDeclaration(decl);    }    /**     * Loads a set of rules that have been specified in terms of     * CSS1 grammar.  If there are collisions with existing rules,     * the newly specified rule will win.     *     * @param in the stream to read the CSS grammar from     * @param ref the reference URL.  This value represents the     *  location of the stream and may be null.  All relative     *  URLs specified in the stream will be based upon this     *  parameter.     */    public void loadRules(Reader in, URL ref) throws IOException {	CssParser parser = new CssParser();	parser.parse(ref, in, false, false);    }    /**     * Fetches a set of attributes to use in the view for     * displaying.  This is basically a set of attributes that     * can be used for View.getAttributes.     */    public AttributeSet getViewAttributes(View v) {	return new ViewAttributeSet(v);    }    /**     * Removes a named style previously added to the document.     *     * @param nm  the name of the style to remove     */    public void removeStyle(String nm) {	Style       aStyle = getStyle(nm);	if (aStyle != null) {	    String selector = cleanSelectorString(nm);	    String[] selectors = getSimpleSelectors(selector);	    synchronized(this) {		SelectorMapping mapping = getRootSelectorMapping();		for (int i = selectors.length - 1; i >= 0; i--) {		    mapping = mapping.getChildSelectorMapping(selectors[i],                                                              true);		}		Style rule = mapping.getStyle();		if (rule != null) {		    mapping.setStyle(null);		    if (resolvedStyles.size() > 0) {			Enumeration values = resolvedStyles.elements();			while (values.hasMoreElements()) {			    ResolvedStyle style = (ResolvedStyle)values.				                    nextElement();			    style.removeStyle(rule);			}		    }		}	    }	}	super.removeStyle(nm);    }    /**     * Adds the rules from the StyleSheet <code>ss</code> to those of     * the receiver. <code>ss's</code> rules will override the rules of     * any previously added style sheets. An added StyleSheet will never     * override the rules of the receiving style sheet.     *     * @since 1.3     */    public void addStyleSheet(StyleSheet ss) {	synchronized(this) {	    if (linkedStyleSheets == null) {		linkedStyleSheets = new Vector();	    }	    if (!linkedStyleSheets.contains(ss)) {                int index = 0;                if (ss instanceof javax.swing.plaf.UIResource                    && linkedStyleSheets.size() > 1) {                    index = linkedStyleSheets.size() - 1;                }		linkedStyleSheets.insertElementAt(ss, index);		linkStyleSheetAt(ss, index);	    }	}    }    /**     * Removes the StyleSheet <code>ss</code> from those of the receiver.     *     * @since 1.3

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -