📄 stylesheet.java
字号:
/*
* Copyright 2008 Sun Microsystems, Inc. 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.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.stylesheet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;
import java.util.List;
import java.util.jar.*;
import com.sun.stylesheet.styleable.*;
import com.sun.stylesheet.css.*;
import com.sun.stylesheet.types.*;
/**
* A stylesheet which can apply properties to a tree of objects. A stylesheet
* is a collection of zero or more {@link Rule Rules}, each of which is applied
* to each object in the tree. Typically the rule will examine the object to
* determine whether or not it is applicable, and if so it will apply certain
* property values to the object.
* <p>
* Objects to be styled must either implement the {@link Styleable} interface,
* or have a Styleable wrapper created for them. AWT and Swing Components along
* with SceneGraph nodes will be wrapped in Styleables automatically.
* <p>
* Stylesheets can be parsed from CSS documents or created programmatically.
* Once created, stylesheets can be freely modified, but the modifications do
* not affect styled objects until a subsequent {@link #applyTo} or
* {@link #reapply}.
*
*@author Ethan Nicholas
*/
public class Stylesheet implements Serializable {
/**
* Key used to store an object's style class. JComponents store their style
* class via putClientProperty and SGNodes via setAttribute.
*/
public static final String STYLE_CLASS_KEY = "styleClass";
private static Stylesheet globalStylesheet;
private static AWTEventListener globalEventListener;
private static DebugWindow debugWindow;
/**
* Objects to which this stylesheet has been applied. WeakHashMap is used
* as a set; the keys are pointed to themselves in order to obtain the weak
* reference behavior.
*/
private transient Map<Styleable, Styleable> roots =
new WeakHashMap<Styleable, Styleable>();
private List<Rule> rules = new ArrayList<Rule>() {
public boolean add(Rule rule) {
rule.setStylesheet(Stylesheet.this);
return super.add(rule);
}
public void add(int index, Rule rule) {
rule.setStylesheet(Stylesheet.this);
super.add(index, rule);
}
public Rule set(int index, Rule rule) {
rule.setStylesheet(Stylesheet.this);
return super.set(index,rule);
}
public boolean addAll(Collection<? extends Rule> c) {
for (Rule r : c)
r.setStylesheet(Stylesheet.this);
return super.addAll(c);
}
public boolean addAll(int index, Collection<? extends Rule> c) {
for (Rule r : c)
r.setStylesheet(Stylesheet.this);
return super.addAll(index, c);
}
};
/** True to automatically re-pack too-small windows. */
private boolean autopack = true;
/** Creates a new stylesheet which contains no rules. */
public Stylesheet() {
if (debugWindow != null)
debugWindow.addStylesheet(this);
}
/**
* Creates a stylesheet from an array of rules.
*
*@param rules the stylesheet's rules
*/
public Stylesheet(Rule[] rules) {
this();
this.rules.addAll(Arrays.asList(rules));
}
/**
* Creates a stylesheet from a collection of rules.
*
*@param rules the stylesheet's rules
*/
public Stylesheet(Collection<Rule> rules) {
this();
this.rules.addAll(rules);
}
/**
* Returns the stylesheet's rules. The list may be freely modified, but
* modifications will have no effect on styled objects until a subsequent
* call to {@link #applyTo or #reapply}.
*
*@return the current list of rules
*@see #applyTo
*@see #reapply
*/
public List<Rule> getRules() {
return rules;
}
/**
* Applies this stylesheet to an object tree. The root object must either
* implement {@link Styleable} or have a wrapper class registered with
* {@link TypeManager}. If the stylesheet is already in effect on the
* object, it will be removed and reapplied.
*
*@throws IllegalArgumentException if root cannot be converted to a
* Styleable
*@throws StylesheetException if an error occurs while applying the stylesheet
*/
public void applyTo(Object root) throws StylesheetException {
Styleable styleable = TypeManager.getStyleable(root);
if (getRoots().containsKey(styleable))
removeFrom(styleable);
roots.put(styleable, styleable);
applyTo(styleable, 0);
if (styleable instanceof DefaultStyleable) {
Object object = ((DefaultStyleable) styleable).getBaseObject();
if (object instanceof Window)
processWindow((Window) object);
}
}
/** INTERNAL USE ONLY. */
public void applyTo(Styleable node, int depth) throws StylesheetException {
if (debugWindow != null)
debugWindow.stylesheetApplied(this, node);
node.addStylesheet(this, depth);
PropertyManager.cascadeTo(node, false);
for (int i = 0; i < rules.size(); i++)
rules.get(i).applyTo(node, depth, i);
Styleable[] children = node.getStyleableChildren();
if (children != null) {
for (Styleable child : children)
applyTo(child, depth + 1);
}
}
/**
* Returns <code>true</code> if autopacking of windows is enabled. If
* autopacking is enabled, {@link #processWindow} may resize windows as they
* are styled. The default value is <code>true</code>.
*
*@return <code>true</code> if windows are being automatically resized as
* needed
*@see #setAutopackingEnabled
*/
public boolean isAutopackingEnabled() {
return autopack;
}
/**
* Sets the window autopacking flag. If autopacking is enabled,
* {@link #processWindow} may resize windows as they are styled. The
* default value is <code>true</code>.
*
*@param autopack <code>true</code> to automatically resize windows as
* needed
*@see #isAutopackingEnabled
*/
public void setAutopackingEnabled(boolean autopack) {
this.autopack = autopack;
}
/**
* Called after a Window instance has been styled. Windows present a
* special challenge, namely that the styles are often applied after the
* window's size has been set and often cause the window's minimum size to
* change, meaning that they would (without additional measures) be created
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -