FileDocCategorySizeDatePackage
SynthParser.javaAPI DocJava SE 6 API47792Tue Jun 10 00:26:54 BST 2008javax.swing.plaf.synth

SynthParser

public class SynthParser extends HandlerBase
version
1.23, 09/12/05

Fields Summary
private static final String
ELEMENT_SYNTH
private static final String
ELEMENT_STYLE
private static final String
ELEMENT_STATE
private static final String
ELEMENT_FONT
private static final String
ELEMENT_COLOR
private static final String
ELEMENT_IMAGE_PAINTER
private static final String
ELEMENT_PAINTER
private static final String
ELEMENT_PROPERTY
private static final String
ELEMENT_SYNTH_GRAPHICS
private static final String
ELEMENT_IMAGE_ICON
private static final String
ELEMENT_BIND
private static final String
ELEMENT_BIND_KEY
private static final String
ELEMENT_INSETS
private static final String
ELEMENT_OPAQUE
private static final String
ELEMENT_DEFAULTS_PROPERTY
private static final String
ELEMENT_INPUT_MAP
private static final String
ATTRIBUTE_ACTION
private static final String
ATTRIBUTE_ID
private static final String
ATTRIBUTE_IDREF
private static final String
ATTRIBUTE_CLONE
private static final String
ATTRIBUTE_VALUE
private static final String
ATTRIBUTE_NAME
private static final String
ATTRIBUTE_STYLE
private static final String
ATTRIBUTE_SIZE
private static final String
ATTRIBUTE_TYPE
private static final String
ATTRIBUTE_TOP
private static final String
ATTRIBUTE_LEFT
private static final String
ATTRIBUTE_BOTTOM
private static final String
ATTRIBUTE_RIGHT
private static final String
ATTRIBUTE_KEY
private static final String
ATTRIBUTE_SOURCE_INSETS
private static final String
ATTRIBUTE_DEST_INSETS
private static final String
ATTRIBUTE_PATH
private static final String
ATTRIBUTE_STRETCH
private static final String
ATTRIBUTE_PAINT_CENTER
private static final String
ATTRIBUTE_METHOD
private static final String
ATTRIBUTE_DIRECTION
private static final String
ATTRIBUTE_CENTER
private com.sun.beans.ObjectHandler
_handler
Lazily created, used for anything we don't understand.
private int
_depth
Indicates the depth of how many elements we've encountered but don't understand. This is used when forwarding to beans persistance to know when we hsould stop forwarding.
private DefaultSynthStyleFactory
_factory
Factory that new styles are added to.
private List
_stateInfos
Array of state infos for the current style. These are pushed to the style when is received.
private ParsedSynthStyle
_style
Current style.
private ParsedSynthStyle$StateInfo
_stateInfo
Current state info.
private List
_inputMapBindings
Bindings for the current InputMap
private String
_inputMapID
ID for the input map. This is cached as the InputMap is created AFTER the inputMapProperty has ended.
private Map
_mapping
Object references outside the scope of persistance.
private URL
_urlResourceBase
Based URL used to resolve paths.
private Class
_classResourceBase
Based class used to resolve paths.
private List
_colorTypes
List of ColorTypes. This is populated in startColorType.
private Map
_defaultsMap
defaultsPropertys are placed here.
private List
_stylePainters
List of SynthStyle.Painters that will be applied to the current style.
private List
_statePainters
List of SynthStyle.Painters that will be applied to the current state.
Constructors Summary
SynthParser()


     
        _mapping = new HashMap<String,Object>();
        _stateInfos = new ArrayList();
        _colorTypes = new ArrayList();
        _inputMapBindings = new ArrayList();
        _stylePainters = new ArrayList();
        _statePainters = new ArrayList();
    
Methods Summary
private voidaddPainterOrMerge(java.util.List painters, java.lang.String method, javax.swing.plaf.synth.SynthPainter painter, int direction)

        ParsedSynthStyle.PainterInfo painterInfo;
        painterInfo = new ParsedSynthStyle.PainterInfo(method,
                                                       painter,
                                                       direction);

        for (Object infoObject: painters) {
            ParsedSynthStyle.PainterInfo info;
            info = (ParsedSynthStyle.PainterInfo) infoObject;

            if (painterInfo.equalsPainter(info)) {
                info.addPainter(painter);
                return;
            }
        }

        painters.add(painterInfo);
    
public voidcharacters(char[] ch, int start, int length)

        if (isForwarding()) {
            getHandler().characters(ch, start, length);
        }
    
private java.lang.ObjectcheckCast(java.lang.Object value, java.lang.Class type)
If value is an instance of type it is returned, otherwise a SAXException is thrown.

        if (!type.isInstance(value)) {
            throw new SAXException("Expected type " + type + " got " +
                                   value.getClass());
        }
        return value;
    
public voidendDocument()

        if (isForwarding()) {
            getHandler().endDocument();
        }
    
public voidendElement(java.lang.String name)

        if (isForwarding()) {
            getHandler().endElement(name);
            _depth--;
            if (!isForwarding()) {
                getHandler().reset();
            }
        }
        else {
            name = name.intern();
            if (name == ELEMENT_STYLE) {
                endStyle();
            }
            else if (name == ELEMENT_STATE) {
                endState();
            }
            else if (name == ELEMENT_INPUT_MAP) {
                endInputMap();
            }
        }
    
private voidendInputMap()

        if (_inputMapID != null) {
            register(_inputMapID, new UIDefaults.LazyInputMap(
                     _inputMapBindings.toArray(new Object[_inputMapBindings.
                     size()])));
        }
        _inputMapBindings.clear();
        _inputMapID = null;
    
private voidendState()

        int size = _statePainters.size();
        if (size > 0) {
            _stateInfo.setPainters((ParsedSynthStyle.PainterInfo[])
                  _statePainters.toArray(new ParsedSynthStyle.
                  PainterInfo[size]));
            _statePainters.clear();
        }
        _stateInfo = null;
    
private voidendStyle()

        int size = _stylePainters.size();
        if (size > 0) {
            _style.setPainters((ParsedSynthStyle.PainterInfo[])
                  _stylePainters.toArray(new ParsedSynthStyle.
                  PainterInfo[size]));
            _stylePainters.clear();
        }
        size = _stateInfos.size();
        if (size > 0) {
            _style.setStateInfo((ParsedSynthStyle.StateInfo[])_stateInfos.
                 toArray(new ParsedSynthStyle.StateInfo[size]));
            _stateInfos.clear();
        }
        _style = null;
    
public voiderror(org.xml.sax.SAXParseException e)

        if (isForwarding()) {
            getHandler().error(e);
        }
    
public voidfatalError(org.xml.sax.SAXParseException e)

        if (isForwarding()) {
            getHandler().fatalError(e);
        }
	throw e;
    
private com.sun.beans.ObjectHandlergetHandler()
Handles beans persistance.

        if (_handler == null) {
            if (_urlResourceBase != null) {
                // getHandler() is never called before parse() so it is safe
                // to create a URLClassLoader with _resourceBase.
                //
                // getResource(".") is called to ensure we have the directory
                // containing the resources in the case the resource base is a
                // .class file.
                URL[] urls = new URL[] { getResource(".") };
                ClassLoader parent = Thread.currentThread().getContextClassLoader();
                ClassLoader urlLoader = new URLClassLoader(urls, parent);
                _handler = new ObjectHandler(null, urlLoader);
            } else {
                _handler = new ObjectHandler(null,
                    _classResourceBase.getClassLoader());
            }

            for (String key : _mapping.keySet()) {
                _handler.register(key, _mapping.get(key));
            }
        }
        return _handler;
    
private java.net.URLgetResource(java.lang.String path)
Returns the path to a resource.

        if (_classResourceBase != null) {
            return _classResourceBase.getResource(path);
        } else {
            try {
                return new URL(_urlResourceBase, path);
            } catch (MalformedURLException mue) {
                return null;
            }
        }
    
public voidignorableWhitespace(char[] ch, int start, int length)

        if (isForwarding()) {
            getHandler().ignorableWhitespace(ch, start, length);
        }
    
private booleanisForwarding()
Returns true if we are forwarding to persistance.

        return (_depth > 0);
    
private java.lang.Objectlookup(java.lang.String key, java.lang.Class type)
Returns an object created with id=key. If the object is not of type type, this will throw an exception.

        Object value = null;
        if (_handler != null) {
            if ((value = _handler.lookup(key)) != null) {
                return checkCast(value, type);
            }
        }
        value = _mapping.get(key);
        if (value == null) {
            throw new SAXException("ID " + key + " has not been defined");
        }
        return checkCast(value, type);
    
private intnextInt(java.util.StringTokenizer tok, java.lang.String errorMsg)
Convenience method to return the next int, or throw if there are no more valid ints.

        if (!tok.hasMoreTokens()) {
            throw new SAXException(errorMsg);
        }
        try {
            return Integer.parseInt(tok.nextToken());
        } catch (NumberFormatException nfe) {
            throw new SAXException(errorMsg);
        }
    
public voidnotationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)

        if (isForwarding()) {
            getHandler().notationDecl(name, publicId, systemId);
        }
    
public voidparse(java.io.InputStream inputStream, javax.swing.plaf.synth.DefaultSynthStyleFactory factory, java.net.URL urlResourceBase, java.lang.Class classResourceBase, java.util.Map defaultsMap)
Parses a set of styles from inputStream, adding the resulting styles to the passed in DefaultSynthStyleFactory. Resources are resolved either from a URL or from a Class. When calling this method, one of the URL or the Class must be null but not both at the same time.

param
inputStream XML document containing the styles to read
param
factory DefaultSynthStyleFactory that new styles are added to
param
urlResourceBase the URL used to resolve any resources, such as Images
param
classResourceBase the Class used to resolve any resources, such as Images
param
defaultsMap Map that UIDefaults properties are placed in

        if (inputStream == null || factory == null ||
            (urlResourceBase == null && classResourceBase == null)) {
            throw new IllegalArgumentException(
                "You must supply an InputStream, StyleFactory and Class or URL");
        }
        
        assert(!(urlResourceBase != null && classResourceBase != null));
        
        _factory = factory;
        _classResourceBase = classResourceBase;
        _urlResourceBase = urlResourceBase;
        _defaultsMap = defaultsMap;
        try {
            try {
                SAXParser saxParser = SAXParserFactory.newInstance().
                                                   newSAXParser();
                saxParser.parse(new BufferedInputStream(inputStream), this);
            } catch (ParserConfigurationException e) {
                throw new ParseException("Error parsing: " + e, 0);
            } 
            catch (SAXException se) {
                throw new ParseException("Error parsing: " + se + " " + 
                                         se.getException(), 0);
            }
            catch (IOException ioe) { 
                throw new ParseException("Error parsing: " + ioe, 0);
            }
        } finally {
            reset();
        }
    
private java.awt.InsetsparseInsets(java.lang.String insets, java.lang.String errorMsg)
Convenience method to return an Insets object.

        StringTokenizer tokenizer = new StringTokenizer(insets);
        return new Insets(nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg),
                          nextInt(tokenizer, errorMsg));
    
public voidprocessingInstruction(java.lang.String target, java.lang.String data)

        if (isForwarding()) {
            getHandler().processingInstruction(target, data);
        }
    
private voidregister(java.lang.String key, java.lang.Object value)
Registers an object by name. This will throw an exception if an object has already been registered under the given name.

        if (key != null) {
            if (_mapping.get(key) != null ||
                     (_handler != null && _handler.lookup(key) != null)) {
                throw new SAXException("ID " + key + " is already defined");
            }
            if (_handler != null) {
                _handler.register(key, value);
            }
            else {
                _mapping.put(key, value);
            }
        }
    
private voidreset()
Clears our internal state.

        _handler = null;
        _depth = 0;
        _mapping.clear();
        _stateInfos.clear();
        _colorTypes.clear();
        _statePainters.clear();
        _stylePainters.clear();
    
public org.xml.sax.InputSourceresolveEntity(java.lang.String publicId, java.lang.String systemId)

        if (isForwarding()) {
            return getHandler().resolveEntity(publicId, systemId);
        }
        return null;
    
public voidsetDocumentLocator(org.xml.sax.Locator locator)

        if (isForwarding()) {
            getHandler().setDocumentLocator(locator);
        }
    
private voidstartBind(org.xml.sax.AttributeList attributes)

        ParsedSynthStyle style = null;
        String path = null;
        int type = -1;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            if (key.equals(ATTRIBUTE_STYLE)) {
                style = (ParsedSynthStyle)lookup(attributes.getValue(i),
                                                  ParsedSynthStyle.class);
            }
            else if (key.equals(ATTRIBUTE_TYPE)) {
                String typeS = attributes.getValue(i).toUpperCase();

                if (typeS.equals("NAME")) {
                    type = DefaultSynthStyleFactory.NAME;
                }
                else if (typeS.equals("REGION")) {
                    type = DefaultSynthStyleFactory.REGION;
                }
                else {
                    throw new SAXException("bind: unknown type " + typeS);
                }
            }
            else if (key.equals(ATTRIBUTE_KEY)) {
                path = attributes.getValue(i); 
            }
        }
        if (style == null || path == null || type == -1) {
            throw new SAXException("bind: you must specify a style, type " +
                                   "and key");
        }
        try {
            _factory.addStyle(style, path, type);
        } catch (PatternSyntaxException pse) {
            throw new SAXException("bind: " + path + " is not a valid " +
                                   "regular expression");
        }
    
private voidstartBindKey(org.xml.sax.AttributeList attributes)

        if (_inputMapID == null) {
            // Not in an inputmap, bail.
            return;
        }
        if (_style != null) {
            String key = null;
            String value = null;
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String aKey = attributes.getName(i);

                if (aKey.equals(ATTRIBUTE_KEY)) {
                    key = attributes.getValue(i);
                }
                else if (aKey.equals(ATTRIBUTE_ACTION)) {
                    value = attributes.getValue(i);
                }
            }
            if (key == null || value == null) {
                throw new SAXException(
                    "bindKey: you must supply a key and action");
            }
            _inputMapBindings.add(key);
            _inputMapBindings.add(value);
        }
    
private voidstartColor(org.xml.sax.AttributeList attributes)

        Color color = null;
        String id = null;

        _colorTypes.clear();
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                color = (Color)lookup(attributes.getValue(i), Color.class);
            }
            else if (key.equals(ATTRIBUTE_NAME)) {
            }
            else if (key.equals(ATTRIBUTE_VALUE)) {
                String value = attributes.getValue(i);

                if (value.startsWith("#")) {
                    try {
                        int argb;
                        boolean hasAlpha;

                        int length = value.length();
                        if (length < 8) {
                            // Just RGB, or some portion of it.
                            argb = Integer.decode(value);
                            hasAlpha = false;
                        } else if (length == 8) {
                            // Single character alpha: #ARRGGBB.
                            argb = Integer.decode(value);
                            hasAlpha = true;
                        } else if (length == 9) {
                            // Color has alpha and is of the form 
                            // #AARRGGBB.
                            // The following split decoding is mandatory due to
                            // Integer.decode() behavior which won't decode
                            // hexadecimal values higher than #7FFFFFFF.
                            // Thus, when an alpha channel is detected, it is
                            // decoded separately from the RGB channels.
                            int rgb = Integer.decode('#" +
                                                     value.substring(3, 9));
                            int a = Integer.decode(value.substring(0, 3));
                            argb = (a << 24) | rgb;
                            hasAlpha = true;
                        } else {
                            throw new SAXException("Invalid Color value: "
                                + value);
                        }

                        color = new ColorUIResource(new Color(argb, hasAlpha));
                    } catch (NumberFormatException nfe) {
                        throw new SAXException("Invalid Color value: " +value);
                    }
                }
                else {
                    try {
                        color = new ColorUIResource((Color)Color.class.
                              getField(value.toUpperCase()).get(Color.class));
                    } catch (NoSuchFieldException nsfe) {
                        throw new SAXException("Invalid color name: " + value);
                    } catch (IllegalAccessException iae) {
                        throw new SAXException("Invalid color name: " + value);
                    }
                }
            }
            else if (key.equals(ATTRIBUTE_TYPE)) {
                StringTokenizer tokenizer = new StringTokenizer(
                                   attributes.getValue(i));
                while (tokenizer.hasMoreTokens()) {
                    String typeName = tokenizer.nextToken();
                    int classIndex = typeName.lastIndexOf('.");
                    Class typeClass;

                    if (classIndex == -1) {
                        typeClass = ColorType.class;
                        classIndex = 0;
                    }
                    else {
                        try {
                            typeClass = Class.forName(typeName.substring(
                                                      0, classIndex));
                        } catch (ClassNotFoundException cnfe) {
                            throw new SAXException("Unknown class: " +
                                      typeName.substring(0, classIndex));
                        }
                        classIndex++;
                    }
                    try {
                        _colorTypes.add((ColorType)checkCast(typeClass.
                              getField(typeName.substring(classIndex,
                              typeName.length() - classIndex)).
                              get(typeClass), ColorType.class));
                    } catch (NoSuchFieldException nsfe) {
                        throw new SAXException("Unable to find color type: " +
                                               typeName);
                    } catch (IllegalAccessException iae) {
                        throw new SAXException("Unable to find color type: " +
                                               typeName);
                    }
                }
            }
        }
        if (color == null) {
            throw new SAXException("color: you must specificy a value");
        }
        register(id, color);
        if (_stateInfo != null && _colorTypes.size() > 0) {
            Color[] colors = _stateInfo.getColors();
            int max = 0;
            for (int counter = _colorTypes.size() - 1; counter >= 0;
                     counter--) {
                max = Math.max(max, ((ColorType)_colorTypes.get(counter)).
                               getID());
            }
            if (colors == null || colors.length <= max) {
                Color[] newColors = new Color[max + 1];
                if (colors != null) {
                    System.arraycopy(colors, 0, newColors, 0, colors.length);
                }
                colors = newColors;
            }
            for (int counter = _colorTypes.size() - 1; counter >= 0;
                     counter--) {
                colors[((ColorType)_colorTypes.get(counter)).getID()] = color;
            }
            _stateInfo.setColors(colors);
        }
    
public voidstartDocument()

        if (isForwarding()) {
            getHandler().startDocument();
        }
    
public voidstartElement(java.lang.String name, org.xml.sax.AttributeList attributes)

        name = name.intern();
        if (name == ELEMENT_STYLE) {
            startStyle(attributes);
        }
        else if (name == ELEMENT_STATE) {
            startState(attributes);
        }
        else if (name == ELEMENT_FONT) {
            startFont(attributes);
        }
        else if (name == ELEMENT_COLOR) {
            startColor(attributes);
        }
        else if (name == ELEMENT_PAINTER) {
            startPainter(attributes, name);
        }
        else if (name == ELEMENT_IMAGE_PAINTER) {
            startPainter(attributes, name);
        }
        else if (name == ELEMENT_PROPERTY) {
            startProperty(attributes, ELEMENT_PROPERTY);
        }
        else if (name == ELEMENT_DEFAULTS_PROPERTY) {
            startProperty(attributes, ELEMENT_DEFAULTS_PROPERTY);
        }
        else if (name == ELEMENT_SYNTH_GRAPHICS) {
            startGraphics(attributes);
        }
        else if (name == ELEMENT_INSETS) {
            startInsets(attributes);
        }
        else if (name == ELEMENT_BIND) {
            startBind(attributes);
        }
        else if (name == ELEMENT_BIND_KEY) {
            startBindKey(attributes);
        }
        else if (name == ELEMENT_IMAGE_ICON) {
            startImageIcon(attributes);
        }
        else if (name == ELEMENT_OPAQUE) {
            startOpaque(attributes);
        }
        else if (name == ELEMENT_INPUT_MAP) {
            startInputMap(attributes);
        }
        else if (name != ELEMENT_SYNTH) {
            if (_depth++ == 0) {
                getHandler().reset();
            }
            getHandler().startElement(name, attributes);
        }
    
private voidstartFont(org.xml.sax.AttributeList attributes)

        Font font = null;
        int style = Font.PLAIN;
        int size = 0;
        String id = null;
        String name = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                font = (Font)lookup(attributes.getValue(i), Font.class);
            }
            else if (key.equals(ATTRIBUTE_NAME)) {
                name = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_SIZE)) {
                try {
                    size = Integer.parseInt(attributes.getValue(i));
                } catch (NumberFormatException nfe) {
                    throw new SAXException("Invalid font size: " +
                                           attributes.getValue(i));
                }
            }
            else if (key.equals(ATTRIBUTE_STYLE)) {
                StringTokenizer tok = new StringTokenizer(
                                                attributes.getValue(i));
                while (tok.hasMoreTokens()) {
                    String token = tok.nextToken().intern();
                    if (token == "BOLD") {
                        style = ((style | Font.PLAIN) ^ Font.PLAIN) |
                                Font.BOLD;
                    }
                    else if (token == "ITALIC") {
                        style |= Font.ITALIC;
                    }
                }
            }
        }
        if (font == null) {
            if (name == null) {
                throw new SAXException("You must define a name for the font");
            }
            if (size == 0) {
                throw new SAXException("You must define a size for the font");
            }
            font = new FontUIResource(name, style, size);
        }
        else if (name != null || size != 0 || style != Font.PLAIN) {
            throw new SAXException("Name, size and style are not for use " +
                                   "with idref");
        }
        register(id, font);
        if (_stateInfo != null) {
            _stateInfo.setFont(font);
        }
        else if (_style != null) {
            _style.setFont(font);
        }
    
private voidstartGraphics(org.xml.sax.AttributeList attributes)

        SynthGraphicsUtils graphics = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_IDREF)) {
                graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i),
                                                 SynthGraphicsUtils.class);
            }
        }
        if (graphics == null) {
            throw new SAXException("graphicsUtils: you must supply an idref");
        }
        if (_style != null) {
            _style.setGraphicsUtils(graphics);
        }
    
private voidstartImageIcon(org.xml.sax.AttributeList attributes)

        String path = null;
        String id = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_PATH)) {
                path = attributes.getValue(i);
            }
        }
        if (path == null) {
            throw new SAXException("imageIcon: you must specify a path");
        }
        register(id, new LazyImageIcon(getResource(path))); 
       
private voidstartInputMap(org.xml.sax.AttributeList attributes)

        _inputMapBindings.clear();
        _inputMapID = null;
        if (_style != null) {
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String key = attributes.getName(i);

                if (key.equals(ATTRIBUTE_ID)) {
                    _inputMapID = attributes.getValue(i);
                }
            }
        }
    
private voidstartInsets(org.xml.sax.AttributeList attributes)

        int top = 0;
        int bottom = 0;
        int left = 0;
        int right = 0;
        Insets insets = null;
        String id = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);

            try {
                if (key.equals(ATTRIBUTE_IDREF)) {
                    insets = (Insets)lookup(attributes.getValue(i),
                                                   Insets.class);
                }
                else if (key.equals(ATTRIBUTE_ID)) {
                    id = attributes.getValue(i);
                }
                else if (key.equals(ATTRIBUTE_TOP)) {
                    top = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_LEFT)) {
                    left = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_BOTTOM)) {
                    bottom = Integer.parseInt(attributes.getValue(i));
                }
                else if (key.equals(ATTRIBUTE_RIGHT)) {
                    right = Integer.parseInt(attributes.getValue(i));
                }
            } catch (NumberFormatException nfe) {
                throw new SAXException("insets: bad integer value for " +
                                       attributes.getValue(i));
            }
        }
        if (insets == null) {
            insets = new InsetsUIResource(top, left, bottom, right);
        }
        register(id, insets);
        if (_style != null) {
            _style.setInsets(insets);
        }
    
private voidstartOpaque(org.xml.sax.AttributeList attributes)

        if (_style != null) {
            _style.setOpaque(true);
            for(int i = attributes.getLength() - 1; i >= 0; i--) {
                String key = attributes.getName(i);

                if (key.equals(ATTRIBUTE_VALUE)) {
                    _style.setOpaque("true".equals(attributes.getValue(i).
                                                   toLowerCase()));
                }
            }
        }
    
private voidstartPainter(org.xml.sax.AttributeList attributes, java.lang.String type)

        Insets sourceInsets = null;
        Insets destInsets = null;
        String path = null;
        boolean paintCenter = true;
        boolean stretch = true;
        SynthPainter painter = null;
        String method = null;
        String id = null;
        int direction = -1;
        boolean center = false;

        boolean stretchSpecified = false;
        boolean paintCenterSpecified = false;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            String value = attributes.getValue(i);

            if (key.equals(ATTRIBUTE_ID)) {
                id = value;
            }
            else if (key.equals(ATTRIBUTE_METHOD)) {
                method = value.toLowerCase(Locale.ENGLISH);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                painter = (SynthPainter)lookup(value, SynthPainter.class);
            }
            else if (key.equals(ATTRIBUTE_PATH)) {
                path = value;
            }
            else if (key.equals(ATTRIBUTE_SOURCE_INSETS)) {
                sourceInsets = parseInsets(value, type +
                   ": sourceInsets must be top left bottom right");
            }
            else if (key.equals(ATTRIBUTE_DEST_INSETS)) {
                destInsets = parseInsets(value, type +
                  ": destinationInsets must be top left bottom right");
            }
            else if (key.equals(ATTRIBUTE_PAINT_CENTER)) {
                paintCenter = value.toLowerCase().equals("true");
                paintCenterSpecified = true;
            }
            else if (key.equals(ATTRIBUTE_STRETCH)) {
                stretch = value.toLowerCase().equals("true");
                stretchSpecified = true;
            }
            else if (key.equals(ATTRIBUTE_DIRECTION)) {
                value = value.toUpperCase().intern();
                if (value == "EAST") {
                    direction = SwingConstants.EAST;
                }
                else if (value == "NORTH") {
                    direction = SwingConstants.NORTH;
                }
                else if (value == "SOUTH") {
                    direction = SwingConstants.SOUTH;
                }
                else if (value == "WEST") {
                    direction = SwingConstants.WEST;
                }
                else if (value == "TOP") {
                    direction = SwingConstants.TOP;
                }
                else if (value == "LEFT") {
                    direction = SwingConstants.LEFT;
                }
                else if (value == "BOTTOM") {
                    direction = SwingConstants.BOTTOM;
                }
                else if (value == "RIGHT") {
                    direction = SwingConstants.RIGHT;
                }
                else if (value == "HORIZONTAL") {
                    direction = SwingConstants.HORIZONTAL;
                }
                else if (value == "VERTICAL") {
                    direction = SwingConstants.VERTICAL;
                }
                else if (value == "HORIZONTAL_SPLIT") {
                    direction = JSplitPane.HORIZONTAL_SPLIT;
                }
                else if (value == "VERTICAL_SPLIT") {
                    direction = JSplitPane.VERTICAL_SPLIT;
                }
                else {
                    throw new SAXException(type + ": unknown direction");
                }
            }
            else if (key.equals(ATTRIBUTE_CENTER)) {
                center = value.toLowerCase().equals("true");
            }
        }
        if (painter == null) {
            if (type == ELEMENT_PAINTER) {
                throw new SAXException(type + 
                             ": you must specify an idref");
            }
            if (sourceInsets == null && !center) {
                throw new SAXException(
                             "property: you must specify sourceInsets");
            }
            if (path == null) {
                throw new SAXException("property: you must specify a path");
            }
            if (center && (sourceInsets != null || destInsets != null ||
                           paintCenterSpecified || stretchSpecified)) {
                throw new SAXException("The attributes: sourceInsets, " +
                                       "destinationInsets, paintCenter and stretch " +
                                       " are not legal when center is true");
            }
            painter = new ImagePainter(!stretch, paintCenter,
                     sourceInsets, destInsets, getResource(path), center);
        }
        register(id, painter);
        if (_stateInfo != null) {
            addPainterOrMerge(_statePainters, method, painter, direction);
        }
        else if (_style != null) {
            addPainterOrMerge(_stylePainters, method, painter, direction);
        }
    
private voidstartProperty(org.xml.sax.AttributeList attributes, java.lang.Object property)

        Object value = null;
        Object key = null;
        // Type of the value: 0=idref, 1=boolean, 2=dimension, 3=insets,
        // 4=integer,5=string
        int iType = 0;
        String aValue = null;

        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String aName = attributes.getName(i);
            if (aName.equals(ATTRIBUTE_TYPE)) {
                String type = attributes.getValue(i).toUpperCase();
                if (type.equals("IDREF")) {
                    iType = 0;
                }
                else if (type.equals("BOOLEAN")) {
                    iType = 1;
                }
                else if (type.equals("DIMENSION")) {
                    iType = 2;
                }
                else if (type.equals("INSETS")) {
                    iType = 3;
                }
                else if (type.equals("INTEGER")) {
                    iType = 4;
                }
                else if (type.equals("STRING")) {
                    iType = 5;
                }
                else {
                    throw new SAXException(property + " unknown type, use" +
                        "idref, boolean, dimension, insets or integer");
                }
            }
            else if (aName.equals(ATTRIBUTE_VALUE)) {
                aValue = attributes.getValue(i);
            }
            else if (aName.equals(ATTRIBUTE_KEY)) {
                key = attributes.getValue(i);
            }
        }
        if (aValue != null) {
            switch (iType) {
            case 0: // idref
                value = lookup(aValue, Object.class);
                break;
            case 1: // boolean
                if (aValue.toUpperCase().equals("TRUE")) {
                    value = Boolean.TRUE;
                }
                else {
                    value = Boolean.FALSE;
                }
                break;
            case 2: // dimension
                StringTokenizer tok = new StringTokenizer(aValue);
                value = new DimensionUIResource(
                    nextInt(tok, "Invalid dimension"),
                    nextInt(tok, "Invalid dimension"));
                break;
            case 3: // insets
                value = parseInsets(aValue, property + " invalid insets");
                break;
            case 4: // integer
                try {
                    value = new Integer(Integer.parseInt(aValue));
                } catch (NumberFormatException nfe) {
                    throw new SAXException(property + " invalid value");
                }
                break;
            case 5: //string
                value = aValue;
                break;
            }
        }
        if (value == null || key == null) {
            throw new SAXException(property + ": you must supply a " +
                                   "key and value");
        }
        if (property == ELEMENT_DEFAULTS_PROPERTY) {
            _defaultsMap.put(key, value);
        }
        else if (_stateInfo != null) {
            if (_stateInfo.getData() == null) {
                _stateInfo.setData(new HashMap());
            }
            _stateInfo.getData().put(key, value);
        }
        else if (_style != null) {
            if (_style.getData() == null) {
                _style.setData(new HashMap());
            }
            _style.getData().put(key, value);
        }
    
private voidstartState(org.xml.sax.AttributeList attributes)

        ParsedSynthStyle.StateInfo stateInfo = null;
        int state = 0;
        String id = null;

        _stateInfo = null;
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
            else if (key.equals(ATTRIBUTE_IDREF)) {
                _stateInfo = (ParsedSynthStyle.StateInfo)lookup(
                   attributes.getValue(i), ParsedSynthStyle.StateInfo.class);
            }
            else if (key.equals(ATTRIBUTE_CLONE)) {
                _stateInfo = (ParsedSynthStyle.StateInfo)((ParsedSynthStyle.
                             StateInfo)lookup(attributes.getValue(i),
                             ParsedSynthStyle.StateInfo.class)).clone();
            }
            else if (key.equals(ATTRIBUTE_VALUE)) {
                StringTokenizer tokenizer = new StringTokenizer(
                                   attributes.getValue(i));
                while (tokenizer.hasMoreTokens()) {
                    String stateString = tokenizer.nextToken().toUpperCase().
                                                   intern();
                    if (stateString == "ENABLED") {
                        state |= SynthConstants.ENABLED;
                    }
                    else if (stateString == "MOUSE_OVER") {
                        state |= SynthConstants.MOUSE_OVER;
                    }
                    else if (stateString == "PRESSED") {
                        state |= SynthConstants.PRESSED;
                    }
                    else if (stateString == "DISABLED") {
                        state |= SynthConstants.DISABLED;
                    }
                    else if (stateString == "FOCUSED") {
                        state |= SynthConstants.FOCUSED;
                    }
                    else if (stateString == "SELECTED") {
                        state |= SynthConstants.SELECTED;
                    }
                    else if (stateString == "DEFAULT") {
                        state |= SynthConstants.DEFAULT;
                    }
                    else if (stateString != "AND") {
                        throw new SAXException("Unknown state: " + state);
                    }
                }
            }
        }
        if (_stateInfo == null) {
            _stateInfo = new ParsedSynthStyle.StateInfo();
        }
        _stateInfo.setComponentState(state);
        register(id, _stateInfo);
        _stateInfos.add(_stateInfo);
    
private voidstartStyle(org.xml.sax.AttributeList attributes)

        String id = null;

        _style = null;
        for(int i = attributes.getLength() - 1; i >= 0; i--) {
            String key = attributes.getName(i);
            if (key.equals(ATTRIBUTE_CLONE)) {
                _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup(
                         attributes.getValue(i), ParsedSynthStyle.class)).
                         clone();
            }
            else if (key.equals(ATTRIBUTE_ID)) {
                id = attributes.getValue(i);
            }
        }
        if (_style == null) {
            _style = new ParsedSynthStyle();
        }
        register(id, _style);
    
public voidunparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName)

        if (isForwarding()) {
            getHandler().unparsedEntityDecl(name, publicId, systemId,
                                            notationName);
        }
    
public voidwarning(org.xml.sax.SAXParseException e)

        if (isForwarding()) {
            getHandler().warning(e);
        }