0N/A/*
3261N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage javax.swing.plaf.synth;
0N/A
0N/Aimport java.awt.Color;
0N/Aimport java.awt.Component;
0N/Aimport java.awt.Font;
0N/Aimport java.awt.Graphics;
0N/Aimport java.awt.Image;
0N/Aimport java.awt.Insets;
0N/Aimport java.awt.Toolkit;
0N/Aimport java.io.BufferedInputStream;
0N/Aimport java.io.IOException;
0N/Aimport java.io.InputStream;
0N/Aimport java.net.MalformedURLException;
0N/Aimport java.net.URL;
0N/Aimport java.net.URLClassLoader;
0N/Aimport java.text.ParseException;
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.HashMap;
614N/Aimport java.util.List;
0N/Aimport java.util.Locale;
0N/Aimport java.util.Map;
0N/Aimport java.util.StringTokenizer;
0N/Aimport java.util.regex.PatternSyntaxException;
0N/A
0N/Aimport javax.swing.ImageIcon;
0N/Aimport javax.swing.JSplitPane;
0N/Aimport javax.swing.SwingConstants;
0N/Aimport javax.swing.UIDefaults;
0N/Aimport javax.swing.plaf.ColorUIResource;
0N/Aimport javax.swing.plaf.DimensionUIResource;
0N/Aimport javax.swing.plaf.FontUIResource;
0N/Aimport javax.swing.plaf.InsetsUIResource;
0N/Aimport javax.swing.plaf.UIResource;
0N/Aimport javax.xml.parsers.ParserConfigurationException;
0N/Aimport javax.xml.parsers.SAXParser;
0N/Aimport javax.xml.parsers.SAXParserFactory;
0N/A
827N/Aimport org.xml.sax.Attributes;
0N/Aimport org.xml.sax.InputSource;
0N/Aimport org.xml.sax.Locator;
0N/Aimport org.xml.sax.SAXException;
0N/Aimport org.xml.sax.SAXParseException;
827N/Aimport org.xml.sax.helpers.DefaultHandler;
0N/A
827N/Aimport com.sun.beans.decoder.DocumentHandler;
0N/A
827N/Aclass SynthParser extends DefaultHandler {
0N/A //
0N/A // Known element names
0N/A //
0N/A private static final String ELEMENT_SYNTH = "synth";
0N/A private static final String ELEMENT_STYLE = "style";
0N/A private static final String ELEMENT_STATE = "state";
0N/A private static final String ELEMENT_FONT = "font";
0N/A private static final String ELEMENT_COLOR = "color";
0N/A private static final String ELEMENT_IMAGE_PAINTER = "imagePainter";
0N/A private static final String ELEMENT_PAINTER = "painter";
0N/A private static final String ELEMENT_PROPERTY = "property";
0N/A private static final String ELEMENT_SYNTH_GRAPHICS = "graphicsUtils";
0N/A private static final String ELEMENT_IMAGE_ICON = "imageIcon";
0N/A private static final String ELEMENT_BIND = "bind";
0N/A private static final String ELEMENT_BIND_KEY = "bindKey";
0N/A private static final String ELEMENT_INSETS = "insets";
0N/A private static final String ELEMENT_OPAQUE = "opaque";
0N/A private static final String ELEMENT_DEFAULTS_PROPERTY =
0N/A "defaultsProperty";
0N/A private static final String ELEMENT_INPUT_MAP = "inputMap";
0N/A
0N/A //
0N/A // Known attribute names
0N/A //
0N/A private static final String ATTRIBUTE_ACTION = "action";
0N/A private static final String ATTRIBUTE_ID = "id";
0N/A private static final String ATTRIBUTE_IDREF = "idref";
0N/A private static final String ATTRIBUTE_CLONE = "clone";
0N/A private static final String ATTRIBUTE_VALUE = "value";
0N/A private static final String ATTRIBUTE_NAME = "name";
0N/A private static final String ATTRIBUTE_STYLE = "style";
0N/A private static final String ATTRIBUTE_SIZE = "size";
0N/A private static final String ATTRIBUTE_TYPE = "type";
0N/A private static final String ATTRIBUTE_TOP = "top";
0N/A private static final String ATTRIBUTE_LEFT = "left";
0N/A private static final String ATTRIBUTE_BOTTOM = "bottom";
0N/A private static final String ATTRIBUTE_RIGHT = "right";
0N/A private static final String ATTRIBUTE_KEY = "key";
0N/A private static final String ATTRIBUTE_SOURCE_INSETS = "sourceInsets";
0N/A private static final String ATTRIBUTE_DEST_INSETS = "destinationInsets";
0N/A private static final String ATTRIBUTE_PATH = "path";
0N/A private static final String ATTRIBUTE_STRETCH = "stretch";
0N/A private static final String ATTRIBUTE_PAINT_CENTER = "paintCenter";
0N/A private static final String ATTRIBUTE_METHOD = "method";
0N/A private static final String ATTRIBUTE_DIRECTION = "direction";
0N/A private static final String ATTRIBUTE_CENTER = "center";
0N/A
0N/A /**
0N/A * Lazily created, used for anything we don't understand.
0N/A */
827N/A private DocumentHandler _handler;
0N/A
0N/A /**
0N/A * Indicates the depth of how many elements we've encountered but don't
0N/A * understand. This is used when forwarding to beans persistance to know
0N/A * when we hsould stop forwarding.
0N/A */
0N/A private int _depth;
0N/A
0N/A /**
0N/A * Factory that new styles are added to.
0N/A */
0N/A private DefaultSynthStyleFactory _factory;
0N/A
0N/A /**
0N/A * Array of state infos for the current style. These are pushed to the
0N/A * style when </style> is received.
0N/A */
614N/A private List<ParsedSynthStyle.StateInfo> _stateInfos;
0N/A
0N/A /**
0N/A * Current style.
0N/A */
0N/A private ParsedSynthStyle _style;
0N/A
0N/A /**
0N/A * Current state info.
0N/A */
0N/A private ParsedSynthStyle.StateInfo _stateInfo;
0N/A
0N/A /**
0N/A * Bindings for the current InputMap
0N/A */
614N/A private List<String> _inputMapBindings;
0N/A
0N/A /**
0N/A * ID for the input map. This is cached as
0N/A * the InputMap is created AFTER the inputMapProperty has ended.
0N/A */
0N/A private String _inputMapID;
0N/A
0N/A /**
0N/A * Object references outside the scope of persistance.
0N/A */
0N/A private Map<String,Object> _mapping;
0N/A
0N/A /**
0N/A * Based URL used to resolve paths.
0N/A */
0N/A private URL _urlResourceBase;
0N/A
0N/A /**
0N/A * Based class used to resolve paths.
0N/A */
0N/A private Class<?> _classResourceBase;
0N/A
0N/A /**
0N/A * List of ColorTypes. This is populated in startColorType.
0N/A */
614N/A private List<ColorType> _colorTypes;
0N/A
0N/A /**
0N/A * defaultsPropertys are placed here.
0N/A */
614N/A private Map<String, Object> _defaultsMap;
0N/A
0N/A /**
0N/A * List of SynthStyle.Painters that will be applied to the current style.
0N/A */
614N/A private List<ParsedSynthStyle.PainterInfo> _stylePainters;
0N/A
0N/A /**
0N/A * List of SynthStyle.Painters that will be applied to the current state.
0N/A */
614N/A private List<ParsedSynthStyle.PainterInfo> _statePainters;
0N/A
0N/A SynthParser() {
0N/A _mapping = new HashMap<String,Object>();
614N/A _stateInfos = new ArrayList<ParsedSynthStyle.StateInfo>();
614N/A _colorTypes = new ArrayList<ColorType>();
614N/A _inputMapBindings = new ArrayList<String>();
614N/A _stylePainters = new ArrayList<ParsedSynthStyle.PainterInfo>();
614N/A _statePainters = new ArrayList<ParsedSynthStyle.PainterInfo>();
0N/A }
0N/A
0N/A /**
0N/A * Parses a set of styles from <code>inputStream</code>, adding the
0N/A * resulting styles to the passed in DefaultSynthStyleFactory.
0N/A * Resources are resolved either from a URL or from a Class. When calling
0N/A * this method, one of the URL or the Class must be null but not both at
0N/A * the same time.
0N/A *
0N/A * @param inputStream XML document containing the styles to read
0N/A * @param factory DefaultSynthStyleFactory that new styles are added to
0N/A * @param urlResourceBase the URL used to resolve any resources, such as Images
0N/A * @param classResourceBase the Class used to resolve any resources, such as Images
0N/A * @param defaultsMap Map that UIDefaults properties are placed in
0N/A */
0N/A public void parse(InputStream inputStream,
0N/A DefaultSynthStyleFactory factory,
0N/A URL urlResourceBase, Class<?> classResourceBase,
614N/A Map<String, Object> defaultsMap)
0N/A throws ParseException, IllegalArgumentException {
0N/A if (inputStream == null || factory == null ||
0N/A (urlResourceBase == null && classResourceBase == null)) {
0N/A throw new IllegalArgumentException(
0N/A "You must supply an InputStream, StyleFactory and Class or URL");
0N/A }
0N/A
0N/A assert(!(urlResourceBase != null && classResourceBase != null));
0N/A
0N/A _factory = factory;
0N/A _classResourceBase = classResourceBase;
0N/A _urlResourceBase = urlResourceBase;
0N/A _defaultsMap = defaultsMap;
0N/A try {
0N/A try {
0N/A SAXParser saxParser = SAXParserFactory.newInstance().
0N/A newSAXParser();
0N/A saxParser.parse(new BufferedInputStream(inputStream), this);
0N/A } catch (ParserConfigurationException e) {
0N/A throw new ParseException("Error parsing: " + e, 0);
0N/A }
0N/A catch (SAXException se) {
0N/A throw new ParseException("Error parsing: " + se + " " +
0N/A se.getException(), 0);
0N/A }
0N/A catch (IOException ioe) {
0N/A throw new ParseException("Error parsing: " + ioe, 0);
0N/A }
0N/A } finally {
0N/A reset();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the path to a resource.
0N/A */
0N/A private URL getResource(String path) {
0N/A if (_classResourceBase != null) {
0N/A return _classResourceBase.getResource(path);
0N/A } else {
0N/A try {
0N/A return new URL(_urlResourceBase, path);
0N/A } catch (MalformedURLException mue) {
0N/A return null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Clears our internal state.
0N/A */
0N/A private void reset() {
0N/A _handler = null;
0N/A _depth = 0;
0N/A _mapping.clear();
0N/A _stateInfos.clear();
0N/A _colorTypes.clear();
0N/A _statePainters.clear();
0N/A _stylePainters.clear();
0N/A }
0N/A
0N/A /**
0N/A * Returns true if we are forwarding to persistance.
0N/A */
0N/A private boolean isForwarding() {
0N/A return (_depth > 0);
0N/A }
0N/A
0N/A /**
0N/A * Handles beans persistance.
0N/A */
827N/A private DocumentHandler getHandler() {
0N/A if (_handler == null) {
827N/A _handler = new DocumentHandler();
0N/A if (_urlResourceBase != null) {
0N/A // getHandler() is never called before parse() so it is safe
0N/A // to create a URLClassLoader with _resourceBase.
0N/A //
0N/A // getResource(".") is called to ensure we have the directory
0N/A // containing the resources in the case the resource base is a
0N/A // .class file.
0N/A URL[] urls = new URL[] { getResource(".") };
0N/A ClassLoader parent = Thread.currentThread().getContextClassLoader();
0N/A ClassLoader urlLoader = new URLClassLoader(urls, parent);
827N/A _handler.setClassLoader(urlLoader);
0N/A } else {
827N/A _handler.setClassLoader(_classResourceBase.getClassLoader());
0N/A }
0N/A
0N/A for (String key : _mapping.keySet()) {
827N/A _handler.setVariable(key, _mapping.get(key));
0N/A }
0N/A }
0N/A return _handler;
0N/A }
0N/A
0N/A /**
0N/A * If <code>value</code> is an instance of <code>type</code> it is
0N/A * returned, otherwise a SAXException is thrown.
0N/A */
0N/A private Object checkCast(Object value, Class type) throws SAXException {
0N/A if (!type.isInstance(value)) {
0N/A throw new SAXException("Expected type " + type + " got " +
0N/A value.getClass());
0N/A }
0N/A return value;
0N/A }
0N/A
0N/A /**
0N/A * Returns an object created with id=key. If the object is not of
0N/A * type type, this will throw an exception.
0N/A */
0N/A private Object lookup(String key, Class type) throws SAXException {
614N/A Object value;
0N/A if (_handler != null) {
827N/A if (_handler.hasVariable(key)) {
827N/A return checkCast(_handler.getVariable(key), type);
0N/A }
0N/A }
0N/A value = _mapping.get(key);
0N/A if (value == null) {
0N/A throw new SAXException("ID " + key + " has not been defined");
0N/A }
0N/A return checkCast(value, type);
0N/A }
0N/A
0N/A /**
0N/A * Registers an object by name. This will throw an exception if an
0N/A * object has already been registered under the given name.
0N/A */
0N/A private void register(String key, Object value) throws SAXException {
0N/A if (key != null) {
0N/A if (_mapping.get(key) != null ||
827N/A (_handler != null && _handler.hasVariable(key))) {
0N/A throw new SAXException("ID " + key + " is already defined");
0N/A }
0N/A if (_handler != null) {
827N/A _handler.setVariable(key, value);
0N/A }
0N/A else {
0N/A _mapping.put(key, value);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Convenience method to return the next int, or throw if there are no
0N/A * more valid ints.
0N/A */
0N/A private int nextInt(StringTokenizer tok, String errorMsg) throws
0N/A SAXException {
0N/A if (!tok.hasMoreTokens()) {
0N/A throw new SAXException(errorMsg);
0N/A }
0N/A try {
0N/A return Integer.parseInt(tok.nextToken());
0N/A } catch (NumberFormatException nfe) {
0N/A throw new SAXException(errorMsg);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Convenience method to return an Insets object.
0N/A */
0N/A private Insets parseInsets(String insets, String errorMsg) throws
0N/A SAXException {
0N/A StringTokenizer tokenizer = new StringTokenizer(insets);
0N/A return new Insets(nextInt(tokenizer, errorMsg),
0N/A nextInt(tokenizer, errorMsg),
0N/A nextInt(tokenizer, errorMsg),
0N/A nextInt(tokenizer, errorMsg));
0N/A }
0N/A
0N/A
0N/A
0N/A //
0N/A // The following methods are invoked from startElement/stopElement
0N/A //
0N/A
827N/A private void startStyle(Attributes attributes) throws SAXException {
0N/A String id = null;
0N/A
0N/A _style = null;
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A if (key.equals(ATTRIBUTE_CLONE)) {
0N/A _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup(
0N/A attributes.getValue(i), ParsedSynthStyle.class)).
0N/A clone();
0N/A }
0N/A else if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A }
0N/A if (_style == null) {
0N/A _style = new ParsedSynthStyle();
0N/A }
0N/A register(id, _style);
0N/A }
0N/A
827N/A private void endStyle() {
0N/A int size = _stylePainters.size();
0N/A if (size > 0) {
614N/A _style.setPainters(_stylePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
0N/A _stylePainters.clear();
0N/A }
0N/A size = _stateInfos.size();
0N/A if (size > 0) {
614N/A _style.setStateInfo(_stateInfos.toArray(new ParsedSynthStyle.StateInfo[size]));
0N/A _stateInfos.clear();
0N/A }
0N/A _style = null;
0N/A }
0N/A
827N/A private void startState(Attributes attributes) throws SAXException {
0N/A ParsedSynthStyle.StateInfo stateInfo = null;
0N/A int state = 0;
0N/A String id = null;
0N/A
0N/A _stateInfo = null;
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_IDREF)) {
0N/A _stateInfo = (ParsedSynthStyle.StateInfo)lookup(
0N/A attributes.getValue(i), ParsedSynthStyle.StateInfo.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_CLONE)) {
0N/A _stateInfo = (ParsedSynthStyle.StateInfo)((ParsedSynthStyle.
0N/A StateInfo)lookup(attributes.getValue(i),
0N/A ParsedSynthStyle.StateInfo.class)).clone();
0N/A }
0N/A else if (key.equals(ATTRIBUTE_VALUE)) {
0N/A StringTokenizer tokenizer = new StringTokenizer(
0N/A attributes.getValue(i));
0N/A while (tokenizer.hasMoreTokens()) {
0N/A String stateString = tokenizer.nextToken().toUpperCase().
0N/A intern();
0N/A if (stateString == "ENABLED") {
0N/A state |= SynthConstants.ENABLED;
0N/A }
0N/A else if (stateString == "MOUSE_OVER") {
0N/A state |= SynthConstants.MOUSE_OVER;
0N/A }
0N/A else if (stateString == "PRESSED") {
0N/A state |= SynthConstants.PRESSED;
0N/A }
0N/A else if (stateString == "DISABLED") {
0N/A state |= SynthConstants.DISABLED;
0N/A }
0N/A else if (stateString == "FOCUSED") {
0N/A state |= SynthConstants.FOCUSED;
0N/A }
0N/A else if (stateString == "SELECTED") {
0N/A state |= SynthConstants.SELECTED;
0N/A }
0N/A else if (stateString == "DEFAULT") {
0N/A state |= SynthConstants.DEFAULT;
0N/A }
0N/A else if (stateString != "AND") {
0N/A throw new SAXException("Unknown state: " + state);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (_stateInfo == null) {
0N/A _stateInfo = new ParsedSynthStyle.StateInfo();
0N/A }
0N/A _stateInfo.setComponentState(state);
0N/A register(id, _stateInfo);
0N/A _stateInfos.add(_stateInfo);
0N/A }
0N/A
827N/A private void endState() {
0N/A int size = _statePainters.size();
0N/A if (size > 0) {
614N/A _stateInfo.setPainters(_statePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
0N/A _statePainters.clear();
0N/A }
0N/A _stateInfo = null;
0N/A }
0N/A
827N/A private void startFont(Attributes attributes) throws SAXException {
0N/A Font font = null;
0N/A int style = Font.PLAIN;
0N/A int size = 0;
0N/A String id = null;
0N/A String name = null;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_IDREF)) {
0N/A font = (Font)lookup(attributes.getValue(i), Font.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_NAME)) {
0N/A name = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_SIZE)) {
0N/A try {
0N/A size = Integer.parseInt(attributes.getValue(i));
0N/A } catch (NumberFormatException nfe) {
0N/A throw new SAXException("Invalid font size: " +
0N/A attributes.getValue(i));
0N/A }
0N/A }
0N/A else if (key.equals(ATTRIBUTE_STYLE)) {
0N/A StringTokenizer tok = new StringTokenizer(
0N/A attributes.getValue(i));
0N/A while (tok.hasMoreTokens()) {
0N/A String token = tok.nextToken().intern();
0N/A if (token == "BOLD") {
0N/A style = ((style | Font.PLAIN) ^ Font.PLAIN) |
0N/A Font.BOLD;
0N/A }
0N/A else if (token == "ITALIC") {
0N/A style |= Font.ITALIC;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (font == null) {
0N/A if (name == null) {
0N/A throw new SAXException("You must define a name for the font");
0N/A }
0N/A if (size == 0) {
0N/A throw new SAXException("You must define a size for the font");
0N/A }
0N/A font = new FontUIResource(name, style, size);
0N/A }
0N/A else if (name != null || size != 0 || style != Font.PLAIN) {
0N/A throw new SAXException("Name, size and style are not for use " +
0N/A "with idref");
0N/A }
0N/A register(id, font);
0N/A if (_stateInfo != null) {
0N/A _stateInfo.setFont(font);
0N/A }
0N/A else if (_style != null) {
0N/A _style.setFont(font);
0N/A }
0N/A }
0N/A
827N/A private void startColor(Attributes attributes) throws SAXException {
0N/A Color color = null;
0N/A String id = null;
0N/A
0N/A _colorTypes.clear();
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_IDREF)) {
0N/A color = (Color)lookup(attributes.getValue(i), Color.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_NAME)) {
0N/A }
0N/A else if (key.equals(ATTRIBUTE_VALUE)) {
0N/A String value = attributes.getValue(i);
0N/A
0N/A if (value.startsWith("#")) {
0N/A try {
0N/A int argb;
0N/A boolean hasAlpha;
0N/A
0N/A int length = value.length();
0N/A if (length < 8) {
0N/A // Just RGB, or some portion of it.
0N/A argb = Integer.decode(value);
0N/A hasAlpha = false;
0N/A } else if (length == 8) {
0N/A // Single character alpha: #ARRGGBB.
0N/A argb = Integer.decode(value);
0N/A hasAlpha = true;
0N/A } else if (length == 9) {
0N/A // Color has alpha and is of the form
0N/A // #AARRGGBB.
0N/A // The following split decoding is mandatory due to
0N/A // Integer.decode() behavior which won't decode
0N/A // hexadecimal values higher than #7FFFFFFF.
0N/A // Thus, when an alpha channel is detected, it is
0N/A // decoded separately from the RGB channels.
0N/A int rgb = Integer.decode('#' +
0N/A value.substring(3, 9));
0N/A int a = Integer.decode(value.substring(0, 3));
0N/A argb = (a << 24) | rgb;
0N/A hasAlpha = true;
0N/A } else {
0N/A throw new SAXException("Invalid Color value: "
0N/A + value);
0N/A }
0N/A
0N/A color = new ColorUIResource(new Color(argb, hasAlpha));
0N/A } catch (NumberFormatException nfe) {
0N/A throw new SAXException("Invalid Color value: " +value);
0N/A }
0N/A }
0N/A else {
0N/A try {
0N/A color = new ColorUIResource((Color)Color.class.
0N/A getField(value.toUpperCase()).get(Color.class));
0N/A } catch (NoSuchFieldException nsfe) {
0N/A throw new SAXException("Invalid color name: " + value);
0N/A } catch (IllegalAccessException iae) {
0N/A throw new SAXException("Invalid color name: " + value);
0N/A }
0N/A }
0N/A }
0N/A else if (key.equals(ATTRIBUTE_TYPE)) {
0N/A StringTokenizer tokenizer = new StringTokenizer(
0N/A attributes.getValue(i));
0N/A while (tokenizer.hasMoreTokens()) {
0N/A String typeName = tokenizer.nextToken();
0N/A int classIndex = typeName.lastIndexOf('.');
0N/A Class typeClass;
0N/A
0N/A if (classIndex == -1) {
0N/A typeClass = ColorType.class;
0N/A classIndex = 0;
0N/A }
0N/A else {
0N/A try {
0N/A typeClass = Class.forName(typeName.substring(
0N/A 0, classIndex));
0N/A } catch (ClassNotFoundException cnfe) {
0N/A throw new SAXException("Unknown class: " +
0N/A typeName.substring(0, classIndex));
0N/A }
0N/A classIndex++;
0N/A }
0N/A try {
0N/A _colorTypes.add((ColorType)checkCast(typeClass.
2455N/A getField(typeName.substring(classIndex)).
0N/A get(typeClass), ColorType.class));
0N/A } catch (NoSuchFieldException nsfe) {
0N/A throw new SAXException("Unable to find color type: " +
0N/A typeName);
0N/A } catch (IllegalAccessException iae) {
0N/A throw new SAXException("Unable to find color type: " +
0N/A typeName);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (color == null) {
0N/A throw new SAXException("color: you must specificy a value");
0N/A }
0N/A register(id, color);
0N/A if (_stateInfo != null && _colorTypes.size() > 0) {
0N/A Color[] colors = _stateInfo.getColors();
0N/A int max = 0;
0N/A for (int counter = _colorTypes.size() - 1; counter >= 0;
0N/A counter--) {
614N/A max = Math.max(max, _colorTypes.get(counter).getID());
0N/A }
0N/A if (colors == null || colors.length <= max) {
0N/A Color[] newColors = new Color[max + 1];
0N/A if (colors != null) {
0N/A System.arraycopy(colors, 0, newColors, 0, colors.length);
0N/A }
0N/A colors = newColors;
0N/A }
0N/A for (int counter = _colorTypes.size() - 1; counter >= 0;
0N/A counter--) {
614N/A colors[_colorTypes.get(counter).getID()] = color;
0N/A }
0N/A _stateInfo.setColors(colors);
0N/A }
0N/A }
0N/A
827N/A private void startProperty(Attributes attributes,
0N/A Object property) throws SAXException {
0N/A Object value = null;
614N/A String key = null;
0N/A // Type of the value: 0=idref, 1=boolean, 2=dimension, 3=insets,
0N/A // 4=integer,5=string
0N/A int iType = 0;
0N/A String aValue = null;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String aName = attributes.getQName(i);
0N/A if (aName.equals(ATTRIBUTE_TYPE)) {
0N/A String type = attributes.getValue(i).toUpperCase();
0N/A if (type.equals("IDREF")) {
0N/A iType = 0;
0N/A }
0N/A else if (type.equals("BOOLEAN")) {
0N/A iType = 1;
0N/A }
0N/A else if (type.equals("DIMENSION")) {
0N/A iType = 2;
0N/A }
0N/A else if (type.equals("INSETS")) {
0N/A iType = 3;
0N/A }
0N/A else if (type.equals("INTEGER")) {
0N/A iType = 4;
0N/A }
0N/A else if (type.equals("STRING")) {
0N/A iType = 5;
0N/A }
0N/A else {
0N/A throw new SAXException(property + " unknown type, use" +
0N/A "idref, boolean, dimension, insets or integer");
0N/A }
0N/A }
0N/A else if (aName.equals(ATTRIBUTE_VALUE)) {
0N/A aValue = attributes.getValue(i);
0N/A }
0N/A else if (aName.equals(ATTRIBUTE_KEY)) {
0N/A key = attributes.getValue(i);
0N/A }
0N/A }
0N/A if (aValue != null) {
0N/A switch (iType) {
0N/A case 0: // idref
0N/A value = lookup(aValue, Object.class);
0N/A break;
0N/A case 1: // boolean
0N/A if (aValue.toUpperCase().equals("TRUE")) {
0N/A value = Boolean.TRUE;
0N/A }
0N/A else {
0N/A value = Boolean.FALSE;
0N/A }
0N/A break;
0N/A case 2: // dimension
0N/A StringTokenizer tok = new StringTokenizer(aValue);
0N/A value = new DimensionUIResource(
0N/A nextInt(tok, "Invalid dimension"),
0N/A nextInt(tok, "Invalid dimension"));
0N/A break;
0N/A case 3: // insets
0N/A value = parseInsets(aValue, property + " invalid insets");
0N/A break;
0N/A case 4: // integer
0N/A try {
0N/A value = new Integer(Integer.parseInt(aValue));
0N/A } catch (NumberFormatException nfe) {
0N/A throw new SAXException(property + " invalid value");
0N/A }
0N/A break;
0N/A case 5: //string
0N/A value = aValue;
0N/A break;
0N/A }
0N/A }
0N/A if (value == null || key == null) {
0N/A throw new SAXException(property + ": you must supply a " +
0N/A "key and value");
0N/A }
0N/A if (property == ELEMENT_DEFAULTS_PROPERTY) {
0N/A _defaultsMap.put(key, value);
0N/A }
0N/A else if (_stateInfo != null) {
0N/A if (_stateInfo.getData() == null) {
0N/A _stateInfo.setData(new HashMap());
0N/A }
0N/A _stateInfo.getData().put(key, value);
0N/A }
0N/A else if (_style != null) {
0N/A if (_style.getData() == null) {
0N/A _style.setData(new HashMap());
0N/A }
0N/A _style.getData().put(key, value);
0N/A }
0N/A }
0N/A
827N/A private void startGraphics(Attributes attributes) throws SAXException {
0N/A SynthGraphicsUtils graphics = null;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A if (key.equals(ATTRIBUTE_IDREF)) {
0N/A graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i),
0N/A SynthGraphicsUtils.class);
0N/A }
0N/A }
0N/A if (graphics == null) {
0N/A throw new SAXException("graphicsUtils: you must supply an idref");
0N/A }
0N/A if (_style != null) {
0N/A _style.setGraphicsUtils(graphics);
0N/A }
0N/A }
0N/A
827N/A private void startInsets(Attributes attributes) throws SAXException {
0N/A int top = 0;
0N/A int bottom = 0;
0N/A int left = 0;
0N/A int right = 0;
0N/A Insets insets = null;
0N/A String id = null;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A
0N/A try {
0N/A if (key.equals(ATTRIBUTE_IDREF)) {
0N/A insets = (Insets)lookup(attributes.getValue(i),
0N/A Insets.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_TOP)) {
0N/A top = Integer.parseInt(attributes.getValue(i));
0N/A }
0N/A else if (key.equals(ATTRIBUTE_LEFT)) {
0N/A left = Integer.parseInt(attributes.getValue(i));
0N/A }
0N/A else if (key.equals(ATTRIBUTE_BOTTOM)) {
0N/A bottom = Integer.parseInt(attributes.getValue(i));
0N/A }
0N/A else if (key.equals(ATTRIBUTE_RIGHT)) {
0N/A right = Integer.parseInt(attributes.getValue(i));
0N/A }
0N/A } catch (NumberFormatException nfe) {
0N/A throw new SAXException("insets: bad integer value for " +
0N/A attributes.getValue(i));
0N/A }
0N/A }
0N/A if (insets == null) {
0N/A insets = new InsetsUIResource(top, left, bottom, right);
0N/A }
0N/A register(id, insets);
0N/A if (_style != null) {
0N/A _style.setInsets(insets);
0N/A }
0N/A }
0N/A
827N/A private void startBind(Attributes attributes) throws SAXException {
0N/A ParsedSynthStyle style = null;
0N/A String path = null;
0N/A int type = -1;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A
0N/A if (key.equals(ATTRIBUTE_STYLE)) {
0N/A style = (ParsedSynthStyle)lookup(attributes.getValue(i),
0N/A ParsedSynthStyle.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_TYPE)) {
0N/A String typeS = attributes.getValue(i).toUpperCase();
0N/A
0N/A if (typeS.equals("NAME")) {
0N/A type = DefaultSynthStyleFactory.NAME;
0N/A }
0N/A else if (typeS.equals("REGION")) {
0N/A type = DefaultSynthStyleFactory.REGION;
0N/A }
0N/A else {
0N/A throw new SAXException("bind: unknown type " + typeS);
0N/A }
0N/A }
0N/A else if (key.equals(ATTRIBUTE_KEY)) {
0N/A path = attributes.getValue(i);
0N/A }
0N/A }
0N/A if (style == null || path == null || type == -1) {
0N/A throw new SAXException("bind: you must specify a style, type " +
0N/A "and key");
0N/A }
0N/A try {
0N/A _factory.addStyle(style, path, type);
0N/A } catch (PatternSyntaxException pse) {
0N/A throw new SAXException("bind: " + path + " is not a valid " +
0N/A "regular expression");
0N/A }
0N/A }
0N/A
827N/A private void startPainter(Attributes attributes, String type) throws SAXException {
0N/A Insets sourceInsets = null;
0N/A Insets destInsets = null;
0N/A String path = null;
0N/A boolean paintCenter = true;
0N/A boolean stretch = true;
0N/A SynthPainter painter = null;
0N/A String method = null;
0N/A String id = null;
0N/A int direction = -1;
0N/A boolean center = false;
0N/A
0N/A boolean stretchSpecified = false;
0N/A boolean paintCenterSpecified = false;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A String value = attributes.getValue(i);
0N/A
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A id = value;
0N/A }
0N/A else if (key.equals(ATTRIBUTE_METHOD)) {
0N/A method = value.toLowerCase(Locale.ENGLISH);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_IDREF)) {
0N/A painter = (SynthPainter)lookup(value, SynthPainter.class);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_PATH)) {
0N/A path = value;
0N/A }
0N/A else if (key.equals(ATTRIBUTE_SOURCE_INSETS)) {
0N/A sourceInsets = parseInsets(value, type +
0N/A ": sourceInsets must be top left bottom right");
0N/A }
0N/A else if (key.equals(ATTRIBUTE_DEST_INSETS)) {
0N/A destInsets = parseInsets(value, type +
0N/A ": destinationInsets must be top left bottom right");
0N/A }
0N/A else if (key.equals(ATTRIBUTE_PAINT_CENTER)) {
0N/A paintCenter = value.toLowerCase().equals("true");
0N/A paintCenterSpecified = true;
0N/A }
0N/A else if (key.equals(ATTRIBUTE_STRETCH)) {
0N/A stretch = value.toLowerCase().equals("true");
0N/A stretchSpecified = true;
0N/A }
0N/A else if (key.equals(ATTRIBUTE_DIRECTION)) {
0N/A value = value.toUpperCase().intern();
0N/A if (value == "EAST") {
0N/A direction = SwingConstants.EAST;
0N/A }
0N/A else if (value == "NORTH") {
0N/A direction = SwingConstants.NORTH;
0N/A }
0N/A else if (value == "SOUTH") {
0N/A direction = SwingConstants.SOUTH;
0N/A }
0N/A else if (value == "WEST") {
0N/A direction = SwingConstants.WEST;
0N/A }
0N/A else if (value == "TOP") {
0N/A direction = SwingConstants.TOP;
0N/A }
0N/A else if (value == "LEFT") {
0N/A direction = SwingConstants.LEFT;
0N/A }
0N/A else if (value == "BOTTOM") {
0N/A direction = SwingConstants.BOTTOM;
0N/A }
0N/A else if (value == "RIGHT") {
0N/A direction = SwingConstants.RIGHT;
0N/A }
0N/A else if (value == "HORIZONTAL") {
0N/A direction = SwingConstants.HORIZONTAL;
0N/A }
0N/A else if (value == "VERTICAL") {
0N/A direction = SwingConstants.VERTICAL;
0N/A }
0N/A else if (value == "HORIZONTAL_SPLIT") {
0N/A direction = JSplitPane.HORIZONTAL_SPLIT;
0N/A }
0N/A else if (value == "VERTICAL_SPLIT") {
0N/A direction = JSplitPane.VERTICAL_SPLIT;
0N/A }
0N/A else {
0N/A throw new SAXException(type + ": unknown direction");
0N/A }
0N/A }
0N/A else if (key.equals(ATTRIBUTE_CENTER)) {
0N/A center = value.toLowerCase().equals("true");
0N/A }
0N/A }
0N/A if (painter == null) {
0N/A if (type == ELEMENT_PAINTER) {
0N/A throw new SAXException(type +
0N/A ": you must specify an idref");
0N/A }
0N/A if (sourceInsets == null && !center) {
0N/A throw new SAXException(
0N/A "property: you must specify sourceInsets");
0N/A }
0N/A if (path == null) {
0N/A throw new SAXException("property: you must specify a path");
0N/A }
0N/A if (center && (sourceInsets != null || destInsets != null ||
0N/A paintCenterSpecified || stretchSpecified)) {
0N/A throw new SAXException("The attributes: sourceInsets, " +
0N/A "destinationInsets, paintCenter and stretch " +
0N/A " are not legal when center is true");
0N/A }
0N/A painter = new ImagePainter(!stretch, paintCenter,
0N/A sourceInsets, destInsets, getResource(path), center);
0N/A }
0N/A register(id, painter);
0N/A if (_stateInfo != null) {
0N/A addPainterOrMerge(_statePainters, method, painter, direction);
0N/A }
0N/A else if (_style != null) {
0N/A addPainterOrMerge(_stylePainters, method, painter, direction);
0N/A }
0N/A }
0N/A
614N/A private void addPainterOrMerge(List<ParsedSynthStyle.PainterInfo> painters, String method,
0N/A SynthPainter painter, int direction) {
0N/A ParsedSynthStyle.PainterInfo painterInfo;
0N/A painterInfo = new ParsedSynthStyle.PainterInfo(method,
0N/A painter,
0N/A direction);
0N/A
0N/A for (Object infoObject: painters) {
0N/A ParsedSynthStyle.PainterInfo info;
0N/A info = (ParsedSynthStyle.PainterInfo) infoObject;
0N/A
0N/A if (painterInfo.equalsPainter(info)) {
0N/A info.addPainter(painter);
0N/A return;
0N/A }
0N/A }
0N/A
0N/A painters.add(painterInfo);
0N/A }
0N/A
827N/A private void startImageIcon(Attributes attributes) throws SAXException {
0N/A String path = null;
0N/A String id = null;
0N/A
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A id = attributes.getValue(i);
0N/A }
0N/A else if (key.equals(ATTRIBUTE_PATH)) {
0N/A path = attributes.getValue(i);
0N/A }
0N/A }
0N/A if (path == null) {
0N/A throw new SAXException("imageIcon: you must specify a path");
0N/A }
0N/A register(id, new LazyImageIcon(getResource(path)));
0N/A }
0N/A
827N/A private void startOpaque(Attributes attributes) {
0N/A if (_style != null) {
0N/A _style.setOpaque(true);
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A
0N/A if (key.equals(ATTRIBUTE_VALUE)) {
0N/A _style.setOpaque("true".equals(attributes.getValue(i).
0N/A toLowerCase()));
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
827N/A private void startInputMap(Attributes attributes) throws SAXException {
0N/A _inputMapBindings.clear();
0N/A _inputMapID = null;
0N/A if (_style != null) {
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String key = attributes.getQName(i);
0N/A
0N/A if (key.equals(ATTRIBUTE_ID)) {
0N/A _inputMapID = attributes.getValue(i);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A private void endInputMap() throws SAXException {
0N/A if (_inputMapID != null) {
0N/A register(_inputMapID, new UIDefaults.LazyInputMap(
0N/A _inputMapBindings.toArray(new Object[_inputMapBindings.
0N/A size()])));
0N/A }
0N/A _inputMapBindings.clear();
0N/A _inputMapID = null;
0N/A }
0N/A
827N/A private void startBindKey(Attributes attributes) throws SAXException {
0N/A if (_inputMapID == null) {
0N/A // Not in an inputmap, bail.
0N/A return;
0N/A }
0N/A if (_style != null) {
0N/A String key = null;
0N/A String value = null;
0N/A for(int i = attributes.getLength() - 1; i >= 0; i--) {
827N/A String aKey = attributes.getQName(i);
0N/A
0N/A if (aKey.equals(ATTRIBUTE_KEY)) {
0N/A key = attributes.getValue(i);
0N/A }
0N/A else if (aKey.equals(ATTRIBUTE_ACTION)) {
0N/A value = attributes.getValue(i);
0N/A }
0N/A }
0N/A if (key == null || value == null) {
0N/A throw new SAXException(
0N/A "bindKey: you must supply a key and action");
0N/A }
0N/A _inputMapBindings.add(key);
0N/A _inputMapBindings.add(value);
0N/A }
0N/A }
0N/A
0N/A //
827N/A // SAX methods, these forward to the DocumentHandler if we don't know
0N/A // the element name.
0N/A //
0N/A
0N/A public InputSource resolveEntity(String publicId, String systemId)
827N/A throws IOException, SAXException {
0N/A if (isForwarding()) {
0N/A return getHandler().resolveEntity(publicId, systemId);
0N/A }
0N/A return null;
0N/A }
0N/A
827N/A public void notationDecl(String name, String publicId, String systemId) throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().notationDecl(name, publicId, systemId);
0N/A }
0N/A }
0N/A
0N/A public void unparsedEntityDecl(String name, String publicId,
827N/A String systemId, String notationName) throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().unparsedEntityDecl(name, publicId, systemId,
0N/A notationName);
0N/A }
0N/A }
0N/A
0N/A public void setDocumentLocator(Locator locator) {
0N/A if (isForwarding()) {
0N/A getHandler().setDocumentLocator(locator);
0N/A }
0N/A }
0N/A
0N/A public void startDocument() throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().startDocument();
0N/A }
0N/A }
0N/A
0N/A public void endDocument() throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().endDocument();
0N/A }
0N/A }
0N/A
827N/A public void startElement(String uri, String local, String name, Attributes attributes)
0N/A throws SAXException {
0N/A name = name.intern();
0N/A if (name == ELEMENT_STYLE) {
0N/A startStyle(attributes);
0N/A }
0N/A else if (name == ELEMENT_STATE) {
0N/A startState(attributes);
0N/A }
0N/A else if (name == ELEMENT_FONT) {
0N/A startFont(attributes);
0N/A }
0N/A else if (name == ELEMENT_COLOR) {
0N/A startColor(attributes);
0N/A }
0N/A else if (name == ELEMENT_PAINTER) {
0N/A startPainter(attributes, name);
0N/A }
0N/A else if (name == ELEMENT_IMAGE_PAINTER) {
0N/A startPainter(attributes, name);
0N/A }
0N/A else if (name == ELEMENT_PROPERTY) {
0N/A startProperty(attributes, ELEMENT_PROPERTY);
0N/A }
0N/A else if (name == ELEMENT_DEFAULTS_PROPERTY) {
0N/A startProperty(attributes, ELEMENT_DEFAULTS_PROPERTY);
0N/A }
0N/A else if (name == ELEMENT_SYNTH_GRAPHICS) {
0N/A startGraphics(attributes);
0N/A }
0N/A else if (name == ELEMENT_INSETS) {
0N/A startInsets(attributes);
0N/A }
0N/A else if (name == ELEMENT_BIND) {
0N/A startBind(attributes);
0N/A }
0N/A else if (name == ELEMENT_BIND_KEY) {
0N/A startBindKey(attributes);
0N/A }
0N/A else if (name == ELEMENT_IMAGE_ICON) {
0N/A startImageIcon(attributes);
0N/A }
0N/A else if (name == ELEMENT_OPAQUE) {
0N/A startOpaque(attributes);
0N/A }
0N/A else if (name == ELEMENT_INPUT_MAP) {
0N/A startInputMap(attributes);
0N/A }
0N/A else if (name != ELEMENT_SYNTH) {
0N/A if (_depth++ == 0) {
827N/A getHandler().startDocument();
0N/A }
827N/A getHandler().startElement(uri, local, name, attributes);
0N/A }
0N/A }
0N/A
827N/A public void endElement(String uri, String local, String name) throws SAXException {
0N/A if (isForwarding()) {
827N/A getHandler().endElement(uri, local, name);
0N/A _depth--;
0N/A if (!isForwarding()) {
827N/A getHandler().startDocument();
0N/A }
0N/A }
0N/A else {
0N/A name = name.intern();
0N/A if (name == ELEMENT_STYLE) {
0N/A endStyle();
0N/A }
0N/A else if (name == ELEMENT_STATE) {
0N/A endState();
0N/A }
0N/A else if (name == ELEMENT_INPUT_MAP) {
0N/A endInputMap();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void characters(char ch[], int start, int length)
0N/A throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().characters(ch, start, length);
0N/A }
0N/A }
0N/A
0N/A public void ignorableWhitespace (char ch[], int start, int length)
0N/A throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().ignorableWhitespace(ch, start, length);
0N/A }
0N/A }
0N/A
0N/A public void processingInstruction(String target, String data)
0N/A throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().processingInstruction(target, data);
0N/A }
0N/A }
0N/A
0N/A public void warning(SAXParseException e) throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().warning(e);
0N/A }
0N/A }
0N/A
0N/A public void error(SAXParseException e) throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().error(e);
0N/A }
0N/A }
0N/A
0N/A
0N/A public void fatalError(SAXParseException e) throws SAXException {
0N/A if (isForwarding()) {
0N/A getHandler().fatalError(e);
0N/A }
0N/A throw e;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * ImageIcon that lazily loads the image until needed.
0N/A */
0N/A private static class LazyImageIcon extends ImageIcon implements UIResource {
0N/A private URL location;
0N/A
0N/A public LazyImageIcon(URL location) {
0N/A super();
0N/A this.location = location;
0N/A }
0N/A
0N/A public void paintIcon(Component c, Graphics g, int x, int y) {
0N/A if (getImage() != null) {
0N/A super.paintIcon(c, g, x, y);
0N/A }
0N/A }
0N/A
0N/A public int getIconWidth() {
0N/A if (getImage() != null) {
0N/A return super.getIconWidth();
0N/A }
0N/A return 0;
0N/A }
0N/A
0N/A public int getIconHeight() {
0N/A if (getImage() != null) {
0N/A return super.getIconHeight();
0N/A }
0N/A return 0;
0N/A }
0N/A
0N/A public Image getImage() {
0N/A if (location != null) {
0N/A setImage(Toolkit.getDefaultToolkit().getImage(location));
0N/A location = null;
0N/A }
0N/A return super.getImage();
0N/A }
0N/A }
0N/A}