📄 typemanager.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.types;
import java.awt.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.border.*;
import com.sun.stylesheet.*;
import com.sun.stylesheet.styleable.*;
/**
* Returns converters and wrappers for the various types supported by the CSS
* engine. Additional types can be registered with {@link
* #registerTypeConverter registerTypeConverter}, {@link
* #registerStyleableWrapper registerStyleableWrapper}, and {@link
* #registerStyleSupport registerStyleSupport}.
*
*@author Ethan Nicholas
*/
public class TypeManager {
private static boolean initialized;
// stores styleable wrappers so we can guarantee that the same wrapper is
// always used for the same object
private static Map<Object, Styleable> styleables =
new WeakHashMap<Object, Styleable>();
// *** IMPORTANT ***
// Note that the converters and styleSupport maps are ClassMaps, which means
// they automatically handle subclasses of the keys inserted into them.
private static ClassMap<Object> converters = new ClassMap<Object>();
private static Map<Class, TypeConverter> cachedConverters =
new HashMap<Class, TypeConverter>();
private static ClassMap<Class<? extends Styleable>> wrappers =
new ClassMap<Class<? extends Styleable>>();
private static ClassMap<Class<? extends StyleSupport>> styleSupportClasses =
new ClassMap<Class<? extends StyleSupport>>();
private static Map<Class, StyleSupport> styleSupportInstances =
new HashMap<Class, StyleSupport>();
private static Map<Class, Constructor> objectConstructors =
new HashMap<Class, Constructor>();
private static Map<Class, Constructor> classConstructors =
new HashMap<Class, Constructor>();
private TypeManager() { /* not instantiable */ }
static {
registerPrimitiveConverter(boolean.class);
registerPrimitiveConverter(Boolean.class);
registerPrimitiveConverter(byte.class);
registerPrimitiveConverter(Byte.class);
registerPrimitiveConverter(short.class);
registerPrimitiveConverter(Short.class);
registerPrimitiveConverter(int.class);
registerPrimitiveConverter(Integer.class);
registerPrimitiveConverter(long.class);
registerPrimitiveConverter(Long.class);
registerPrimitiveConverter(float.class);
registerPrimitiveConverter(Float.class);
registerPrimitiveConverter(double.class);
registerPrimitiveConverter(Double.class);
registerPrimitiveConverter(char.class);
registerPrimitiveConverter(Character.class);
registerPrimitiveConverter(String.class);
registerTypeConverter(String.class, new StringConverter());
registerTypeConverter(Color.class, new ColorConverter());
registerTypeConverter(Insets.class, new InsetsConverter());
registerTypeConverter(Dimension.class, new DimensionConverter());
registerTypeConverter(KeyStroke.class, new KeyStrokeConverter());
registerTypeConverter(Border.class, new BorderConverter());
registerTypeConverter(Font.class, new FontConverter());
registerTypeConverter(Size.class, new SizeConverter());
registerTypeConverter(Time.class, new TimeConverter());
registerTypeConverter(TextDecorationHandler.Decoration.class,
new TextDecorationConverter());
registerTypeConverterClass(Enum.class, EnumConverter.class);
registerStyleableWrapper(Object.class, DefaultStyleable.class);
registerStyleSupport(Component.class, ComponentStyleSupport.class);
registerStyleSupport(AbstractButton.class,
AbstractButtonStyleSupport.class);
registerStyleSupport(JLabel.class, JLabelStyleSupport.class);
registerStyleSupport(Window.class, WindowStyleSupport.class);
try {
Class sgNode = Class.forName("com.sun.scenario.scenegraph.SGNode");
registerStyleSupport(sgNode, SGNodeStyleSupport.class);
}
catch (ClassNotFoundException e) {
}
try {
Class fxObject = Class.forName("com.sun.javafx.runtime.FXObject");
registerStyleSupport(fxObject, FXObjectStyleSupport.class);
}
catch (ClassNotFoundException e) {
}
initialized = true;
}
/**
* Registers a new <code>StyleSupport</code>, which allows {@link
* DefaultStyleable} to provide support for additional classes. The support
* class will be used whenever the specified class or any of its descendents
* (which are not registered with more specific support classes) is
* encountered.
* <p>
* The support class must have a constructor which takes a
* <code>Class</code>; this constructor will be invoked once for each
* specific class that requires a <code>StyleSupport</code>.
* For example {@link ComponentStyleSupport} is registered to
* <code>Component</code> by default. Each specific subclass of
* <code>Component</code> will receive its own instance of
* <code>ComponentStyleSupport</code>, created by passing the class to its
* constructor.
* <p>
* <code>StyleSupport</code> instances are used by
* <code>DefaultStyleable</code> to support specific classes. If a
* different wrapper class has been registered, the new wrapper may ignore
* registered <code>StyleSupport</code> classes. This call does not replace
* any <code>StyleSupport</code> instances which may already have been
* created.
* <p>
* This call requires the <code>setGlobalStylesheet</code> AWTPermission.
*
*@param cls the class to support
*@param support the <code>StyleSupport</code> class which provides support
* for the class
*@throws SecurityException if the required permission is not available
*/
public static void registerStyleSupport(Class cls,
Class<? extends StyleSupport> support) {
if (initialized) {
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkPermission(
new AWTPermission("setGlobalStylesheet"));
}
styleSupportClasses.put(cls, support);
}
/**
* Registers a new <code>Styleable</code> wrapper, which allows the CSS
* engine to support additional classes. An instance of the wrapper class
* will be created whenever the specified class or any of its descendents
* (which are not registered with more specific wrapper classes) is
* encountered.
* <p>
* The wrapper class must have a constructor which takes an
* <code>Object</code>; this constructor will be invoked once for each
* specific object that requires a <code>Styleable</code> wrapper. For
* example {@link DefaultStyleable} is registered to <code>Object</code> by
* default. This means that, unless a more specific wrapper is registered,
* any instance of any class will have a <code>DefaultStyleable</code>
* constructed for it by passing the object to DefaultStyleable's
* constructor.
* <p>
* Internally, <code>DefaultStyleable</code> uses <code>StyleSupport</code>
* instances to provide support for specific classes. Generally developers
* will want to provide new <code>StyleSupport</code> classes using {@link
* #registerStyleSupport} rather than replace the
* <code>DefaultStyleable</code> altogether.
* <p>
* Wrappers are only created for classes which do not implement
* <code>Styleable</code>. This call does not replace any wrappers which
* may already have been created. A <code>StylesheetException</code> will be
* thrown if you attempt to register a wrapper for a class which
* implements <code>Styleable</code>.
* <p>
* This call requires the <code>setGlobalStylesheet</code> AWTPermission.
*
*@param cls the class to wrap
*@param wrapperClass the <code>Styleable</code> class which wraps the class
*@throws SecurityException if the required permission is not available
*@throws StylesheetException if you attempt to register a wrapper for a
* <code>Styleable</code>
*@see #registerStyleSupport
*/
public static void registerStyleableWrapper(Class cls,
Class<? extends Styleable> wrapperClass) {
if (initialized) {
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkPermission(
new AWTPermission("setGlobalStylesheet"));
}
if (Styleable.class.isAssignableFrom(cls))
throw new StylesheetException("cannot register wrapper for Styleable " +
cls);
wrappers.put(cls, wrapperClass);
}
/**
* Returns a <code>Styleable</code> for the specified object. If the object
* implements <code>Styleable</code>, the object itself is returned,
* otherwise a wrapper is created for it. Wrappers are stable over time:
* repeated calls to this method for the same object will always return the
* same result.
* <p>
* By default the wrapper class is always <code>DefaultStyleable</code>,
* which obtains support for specific classes by calling {@link
* #getStyleSupport}. Additional <code>StyleSupport</code> classes may be
* registered with {@link #registerStyleSupport} and different wrappers may
* be registered with {@link #registerStyleableWrapper}.
*
*@param object the object to wrap
*@return a <code>Styleable</code> wrapper for the object
*@throws StylesheetException if an error occurs creating the wrapper
*@see #registerStyleableWrapper
*/
public static Styleable getStyleable(Object object) throws StylesheetException {
if (object instanceof Styleable)
return (Styleable) object;
else {
Styleable result = styleables.get(object);
if (result == null) {
Class<? extends Styleable> wrapper = null;
wrapper = wrappers.get(object.getClass());
if (wrapper == null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -