KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > synth > SynthParser


1 /*
2  * @(#)SynthParser.java 1.15 04/04/16
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.plaf.synth;
8
9 import org.xml.sax.*;
10 import java.awt.*;
11 import java.io.*;
12 import java.lang.reflect.*;
13 import java.net.*;
14 import java.text.*;
15 import java.util.*;
16 import java.util.regex.*;
17 import javax.swing.*;
18 import javax.swing.plaf.*;
19 import javax.xml.parsers.*;
20 import com.sun.beans.ObjectHandler;
21 import sun.swing.plaf.synth.*;
22
23 /**
24  * @version 1.15, 04/16/04
25  */

26 class SynthParser extends HandlerBase {
27     //
28
// Known element names
29
//
30
private static final String JavaDoc ELEMENT_SYNTH = "synth";
31     private static final String JavaDoc ELEMENT_STYLE = "style";
32     private static final String JavaDoc ELEMENT_STATE = "state";
33     private static final String JavaDoc ELEMENT_FONT = "font";
34     private static final String JavaDoc ELEMENT_COLOR = "color";
35     private static final String JavaDoc ELEMENT_IMAGE_PAINTER = "imagePainter";
36     private static final String JavaDoc ELEMENT_PAINTER = "painter";
37     private static final String JavaDoc ELEMENT_PROPERTY = "property";
38     private static final String JavaDoc ELEMENT_SYNTH_GRAPHICS = "graphicsUtils";
39     private static final String JavaDoc ELEMENT_IMAGE_ICON = "imageIcon";
40     private static final String JavaDoc ELEMENT_BIND = "bind";
41     private static final String JavaDoc ELEMENT_BIND_KEY = "bindKey";
42     private static final String JavaDoc ELEMENT_INSETS = "insets";
43     private static final String JavaDoc ELEMENT_OPAQUE = "opaque";
44     private static final String JavaDoc ELEMENT_DEFAULTS_PROPERTY =
45                                         "defaultsProperty";
46     private static final String JavaDoc ELEMENT_INPUT_MAP = "inputMap";
47     private static final String JavaDoc ELEMENT_BACKGROUND_IMAGE = "backgroundImage";
48
49     //
50
// Known attribute names
51
//
52
private static final String JavaDoc ATTRIBUTE_ACTION = "action";
53     private static final String JavaDoc ATTRIBUTE_ID = "id";
54     private static final String JavaDoc ATTRIBUTE_IDREF = "idref";
55     private static final String JavaDoc ATTRIBUTE_CLONE = "clone";
56     private static final String JavaDoc ATTRIBUTE_VALUE = "value";
57     private static final String JavaDoc ATTRIBUTE_NAME = "name";
58     private static final String JavaDoc ATTRIBUTE_STYLE = "style";
59     private static final String JavaDoc ATTRIBUTE_SIZE = "size";
60     private static final String JavaDoc ATTRIBUTE_TYPE = "type";
61     private static final String JavaDoc ATTRIBUTE_TOP = "top";
62     private static final String JavaDoc ATTRIBUTE_LEFT = "left";
63     private static final String JavaDoc ATTRIBUTE_BOTTOM = "bottom";
64     private static final String JavaDoc ATTRIBUTE_RIGHT = "right";
65     private static final String JavaDoc ATTRIBUTE_KEY = "key";
66     private static final String JavaDoc ATTRIBUTE_SOURCE_INSETS = "sourceInsets";
67     private static final String JavaDoc ATTRIBUTE_DEST_INSETS = "destinationInsets";
68     private static final String JavaDoc ATTRIBUTE_PATH = "path";
69     private static final String JavaDoc ATTRIBUTE_STRETCH = "stretch";
70     private static final String JavaDoc ATTRIBUTE_PAINT_CENTER = "paintCenter";
71     private static final String JavaDoc ATTRIBUTE_METHOD = "method";
72     private static final String JavaDoc ATTRIBUTE_DIRECTION = "direction";
73
74     /**
75      * Lazily created, used for anything we don't understand.
76      */

77     private ObjectHandler _handler;
78
79     /**
80      * Indicates the depth of how many elements we've encountered but don't
81      * understand. This is used when forwarding to beans persistance to know
82      * when we hsould stop forwarding.
83      */

84     private int _depth;
85
86     /**
87      * Factory that new styles are added to.
88      */

89     private DefaultSynthStyleFactory JavaDoc _factory;
90
91     /**
92      * Array of state infos for the current style. These are pushed to the
93      * style when </style> is received.
94      */

95     private java.util.List JavaDoc _stateInfos;
96
97     /**
98      * Current style.
99      */

100     private ParsedSynthStyle JavaDoc _style;
101
102     /**
103      * Current state info.
104      */

105     private ParsedSynthStyle.StateInfo JavaDoc _stateInfo;
106
107     /**
108      * Bindings for the current InputMap
109      */

110     private java.util.List JavaDoc _inputMapBindings;
111
112     /**
113      * ID for the input map. This is cached as
114      * the InputMap is created AFTER the inputMapProperty has ended.
115      */

116     private String JavaDoc _inputMapID;
117
118     /**
119      * Object references outside the scope of persistance.
120      */

121     private Map _mapping;
122
123     /**
124      * Based used to resolve paths.
125      */

126     private Class JavaDoc _resourceBase;
127
128     /**
129      * List of ColorTypes. This is populated in startColorType.
130      */

131     private java.util.List JavaDoc _colorTypes;
132
133     /**
134      * defaultsPropertys are placed here.
135      */

136     private Map _defaultsMap;
137
138     /**
139      * List of SynthStyle.Painters that will be applied to the current style.
140      */

141     private java.util.List JavaDoc _stylePainters;
142
143     /**
144      * List of SynthStyle.Painters that will be applied to the current state.
145      */

146     private java.util.List JavaDoc _statePainters;
147
148     SynthParser() {
149         _mapping = new HashMap();
150         _stateInfos = new ArrayList();
151         _colorTypes = new ArrayList();
152         _inputMapBindings = new ArrayList();
153         _stylePainters = new ArrayList();
154         _statePainters = new ArrayList();
155     }
156
157     /**
158      * Parses a set of styles from <code>inputStream</code>, adding the
159      * resulting styles to the passed in DefaultSynthStyleFactory.
160      *
161      * @param inputStream XML document containing the styles to read
162      * @param factory DefaultSynthStyleFactory that new styles are added to
163      * @param resourceBase Class used to resolve any resources, such as Images
164      * @param defaultsMap Map that UIDefaults properties are placed in
165      */

166     public void parse(InputStream inputStream,
167                       DefaultSynthStyleFactory JavaDoc factory,
168                       Class JavaDoc resourceBase, Map defaultsMap)
169                       throws ParseException, IllegalArgumentException JavaDoc {
170         if (inputStream == null || factory == null || resourceBase == null) {
171             throw new IllegalArgumentException JavaDoc(
172                 "You must supply an InputStream;, Class and StyleFactory");
173         }
174         _factory = factory;
175         _resourceBase = resourceBase;
176         _defaultsMap = defaultsMap;
177         try {
178             try {
179                 SAXParser saxParser = SAXParserFactory.newInstance().
180                                                    newSAXParser();
181                 saxParser.parse(new BufferedInputStream(inputStream), this);
182             } catch (ParserConfigurationException e) {
183                 throw new ParseException("Error parsing: " + e, 0);
184             }
185             catch (SAXException se) {
186                 throw new ParseException("Error parsing: " + se + " " +
187                                          se.getException(), 0);
188             }
189             catch (IOException ioe) {
190                 throw new ParseException("Error parsing: " + ioe, 0);
191             }
192         } finally {
193             reset();
194         }
195     }
196
197     /**
198      * Returns the path to a resource.
199      */

200     private URL getResource(String JavaDoc path) {
201         return _resourceBase.getResource(path);
202     }
203
204     /**
205      * Clears our internal state.
206      */

207     private void reset() {
208         _handler = null;
209         _depth = 0;
210         _mapping.clear();
211         _stateInfos.clear();
212         _colorTypes.clear();
213         _statePainters.clear();
214         _stylePainters.clear();
215     }
216
217     /**
218      * Returns true if we are forwarding to persistance.
219      */

220     private boolean isForwarding() {
221         return (_depth > 0);
222     }
223
224     /**
225      * Handles beans persistance.
226      */

227     private ObjectHandler getHandler() {
228         if (_handler == null) {
229             _handler = new ObjectHandler();
230         }
231         return _handler;
232     }
233
234     /**
235      * If <code>value</code> is an instance of <code>type</code> it is
236      * returned, otherwise a SAXException is thrown.
237      */

238     private Object JavaDoc checkCast(Object JavaDoc value, Class JavaDoc type) throws SAXException {
239         if (!type.isInstance(value)) {
240             throw new SAXException("Expected type " + type + " got " +
241                                    value.getClass());
242         }
243         return value;
244     }
245
246     /**
247      * Returns an object created with id=key. If the object is not of
248      * type type, this will throw an exception.
249      */

250     private Object JavaDoc lookup(String JavaDoc key, Class JavaDoc type) throws SAXException {
251         Object JavaDoc value = null;
252         if (_handler != null) {
253             if ((value = _handler.lookup(key)) != null) {
254                 return checkCast(value, type);
255             }
256         }
257         value = _mapping.get(key);
258         if (value == null) {
259             throw new SAXException("ID " + key + " has not been defined");
260         }
261         return checkCast(value, type);
262     }
263
264     /**
265      * Registers an object by name. This will throw an exception if an
266      * object has already been registered under the given name.
267      */

268     private void register(String JavaDoc key, Object JavaDoc value) throws SAXException {
269         if (key != null) {
270             if (_mapping.get(key) != null ||
271                      (_handler != null && _handler.lookup(key) != null)) {
272                 throw new SAXException("ID " + key + " is already defined");
273             }
274             _mapping.put(key, value);
275         }
276     }
277
278     /**
279      * Convenience method to return the next int, or throw if there are no
280      * more valid ints.
281      */

282     private int nextInt(StringTokenizer tok, String JavaDoc errorMsg) throws
283                    SAXException {
284         if (!tok.hasMoreTokens()) {
285             throw new SAXException(errorMsg);
286         }
287         try {
288             return Integer.parseInt(tok.nextToken());
289         } catch (NumberFormatException JavaDoc nfe) {
290             throw new SAXException(errorMsg);
291         }
292     }
293
294     /**
295      * Convenience method to return an Insets object.
296      */

297     private Insets parseInsets(String JavaDoc insets, String JavaDoc errorMsg) throws
298                         SAXException {
299         StringTokenizer tokenizer = new StringTokenizer(insets);
300         return new Insets(nextInt(tokenizer, errorMsg),
301                           nextInt(tokenizer, errorMsg),
302                           nextInt(tokenizer, errorMsg),
303                           nextInt(tokenizer, errorMsg));
304     }
305
306
307
308     //
309
// The following methods are invoked from startElement/stopElement
310
//
311

312     private void startStyle(AttributeList attributes) throws SAXException {
313         String JavaDoc id = null;
314
315         _style = null;
316         for(int i = attributes.getLength() - 1; i >= 0; i--) {
317             String JavaDoc key = attributes.getName(i);
318             if (key.equals(ATTRIBUTE_CLONE)) {
319                 _style = (ParsedSynthStyle JavaDoc)((ParsedSynthStyle JavaDoc)lookup(
320                          attributes.getValue(i), ParsedSynthStyle JavaDoc.class)).
321                          clone();
322             }
323             else if (key.equals(ATTRIBUTE_ID)) {
324                 id = attributes.getValue(i);
325             }
326         }
327         if (_style == null) {
328             _style = new ParsedSynthStyle JavaDoc();
329         }
330         register(id, _style);
331     }
332
333     private void endStyle() throws SAXException {
334         int size = _stylePainters.size();
335         if (size > 0) {
336             _style.setPainters((ParsedSynthStyle.PainterInfo JavaDoc[])
337                   _stylePainters.toArray(new ParsedSynthStyle.
338
JavaDoc                  PainterInfo[size]));
339             _stylePainters.clear();
340         }
341         size = _stateInfos.size();
342         if (size > 0) {
343             _style.setStateInfo((ParsedSynthStyle.StateInfo JavaDoc[])_stateInfos.
344                  toArray(new ParsedSynthStyle.StateInfo JavaDoc[size]));
345             _stateInfos.clear();
346         }
347         _style = null;
348     }
349
350     private void startState(AttributeList attributes) throws SAXException {
351         ParsedSynthStyle.StateInfo JavaDoc stateInfo = null;
352         int state = 0;
353         String JavaDoc id = null;
354
355         _stateInfo = null;
356         for(int i = attributes.getLength() - 1; i >= 0; i--) {
357             String JavaDoc key = attributes.getName(i);
358             if (key.equals(ATTRIBUTE_ID)) {
359                 id = attributes.getValue(i);
360             }
361             else if (key.equals(ATTRIBUTE_IDREF)) {
362                 _stateInfo = (ParsedSynthStyle.StateInfo JavaDoc)lookup(
363                    attributes.getValue(i), ParsedSynthStyle.StateInfo JavaDoc.class);
364             }
365             else if (key.equals(ATTRIBUTE_CLONE)) {
366                 _stateInfo = (ParsedSynthStyle.StateInfo JavaDoc)((ParsedSynthStyle.
367
JavaDoc                             StateInfo)lookup(attributes.getValue(i),
368                              ParsedSynthStyle.StateInfo JavaDoc.class)).clone();
369             }
370             else if (key.equals(ATTRIBUTE_VALUE)) {
371                 StringTokenizer tokenizer = new StringTokenizer(
372                                    attributes.getValue(i));
373                 while (tokenizer.hasMoreTokens()) {
374                     String JavaDoc stateString = tokenizer.nextToken().toUpperCase().
375                                                    intern();
376                     if (stateString == "ENABLED") {
377                         state |= SynthConstants.ENABLED;
378                     }
379                     else if (stateString == "MOUSE_OVER") {
380                         state |= SynthConstants.MOUSE_OVER;
381                     }
382                     else if (stateString == "PRESSED") {
383                         state |= SynthConstants.PRESSED;
384                     }
385                     else if (stateString == "DISABLED") {
386                         state |= SynthConstants.DISABLED;
387                     }
388                     else if (stateString == "FOCUSED") {
389                         state |= SynthConstants.FOCUSED;
390                     }
391                     else if (stateString == "SELECTED") {
392                         state |= SynthConstants.SELECTED;
393                     }
394                     else if (stateString == "DEFAULT") {
395                         state |= SynthConstants.DEFAULT;
396                     }
397                     else if (stateString != "AND") {
398                         throw new SAXException("Unknown state: " + state);
399                     }
400                 }
401             }
402         }
403         if (_stateInfo == null) {
404             _stateInfo = new ParsedSynthStyle.StateInfo JavaDoc();
405         }
406         _stateInfo.setComponentState(state);
407         register(id, _stateInfo);
408         _stateInfos.add(_stateInfo);
409     }
410
411     private void endState() throws SAXException {
412         int size = _statePainters.size();
413         if (size > 0) {
414             _stateInfo.setPainters((ParsedSynthStyle.PainterInfo JavaDoc[])
415                   _statePainters.toArray(new ParsedSynthStyle.
416
JavaDoc                  PainterInfo[size]));
417             _statePainters.clear();
418         }
419         _stateInfo = null;
420     }
421
422     private void startFont(AttributeList attributes) throws SAXException {
423         Font font = null;
424         int style = Font.PLAIN;
425         int size = 0;
426         String JavaDoc id = null;
427         String JavaDoc name = null;
428
429         for(int i = attributes.getLength() - 1; i >= 0; i--) {
430             String JavaDoc key = attributes.getName(i);
431             if (key.equals(ATTRIBUTE_ID)) {
432                 id = attributes.getValue(i);
433             }
434             else if (key.equals(ATTRIBUTE_IDREF)) {
435                 font = (Font)lookup(attributes.getValue(i), Font.class);
436             }
437             else if (key.equals(ATTRIBUTE_NAME)) {
438                 name = attributes.getValue(i);
439             }
440             else if (key.equals(ATTRIBUTE_SIZE)) {
441                 try {
442                     size = Integer.parseInt(attributes.getValue(i));
443                 } catch (NumberFormatException JavaDoc nfe) {
444                     throw new SAXException("Invalid font size: " +
445                                            attributes.getValue(i));
446                 }
447             }
448             else if (key.equals(ATTRIBUTE_STYLE)) {
449                 StringTokenizer tok = new StringTokenizer(
450                                                 attributes.getValue(i));
451                 while (tok.hasMoreTokens()) {
452                     String JavaDoc token = tok.nextToken().intern();
453                     if (token == "BOLD") {
454                         style = ((style | Font.PLAIN) ^ Font.PLAIN) |
455                                 Font.BOLD;
456                     }
457                     else if (token == "ITALIC") {
458                         style |= Font.ITALIC;
459                     }
460                 }
461             }
462         }
463         if (font == null) {
464             if (name == null) {
465                 throw new SAXException("You must define a name for the font");
466             }
467             if (size == 0) {
468                 throw new SAXException("You must define a size for the font");
469             }
470             font = new FontUIResource(name, style, size);
471         }
472         else if (name != null || size != 0 || style != Font.PLAIN) {
473             throw new SAXException("Name, size and style are not for use " +
474                                    "with idref");
475         }
476         register(id, font);
477         if (_stateInfo != null) {
478             _stateInfo.setFont(font);
479         }
480         else if (_style != null) {
481             _style.setFont(font);
482         }
483     }
484
485     private void startColor(AttributeList attributes) throws SAXException {
486         Color color = null;
487         String JavaDoc id = null;
488
489         _colorTypes.clear();
490         for(int i = attributes.getLength() - 1; i >= 0; i--) {
491             String JavaDoc key = attributes.getName(i);
492             if (key.equals(ATTRIBUTE_ID)) {
493                 id = attributes.getValue(i);
494             }
495             else if (key.equals(ATTRIBUTE_IDREF)) {
496                 color = (Color)lookup(attributes.getValue(i), Color.class);
497             }
498             else if (key.equals(ATTRIBUTE_NAME)) {
499             }
500             else if (key.equals(ATTRIBUTE_VALUE)) {
501                 String JavaDoc value = attributes.getValue(i);
502
503                 if (value.startsWith("#")) {
504                     try {
505                         int rgba = Integer.decode(value).intValue();
506                         color = new ColorUIResource(new Color(
507                                               rgba, value.length() > 7));
508                     } catch (NumberFormatException JavaDoc nfe) {
509                         throw new SAXException("Invalid Color value: " +value);
510                     }
511                 }
512                 else {
513                     try {
514                         color = new ColorUIResource((Color)Color.class.
515                               getField(value.toUpperCase()).get(Color.class));
516                     } catch (NoSuchFieldException JavaDoc nsfe) {
517                         throw new SAXException("Invalid color name: " + value);
518                     } catch (IllegalAccessException JavaDoc iae) {
519                         throw new SAXException("Invalid color name: " + value);
520                     }
521                 }
522             }
523             else if (key.equals(ATTRIBUTE_TYPE)) {
524                 StringTokenizer tokenizer = new StringTokenizer(
525                                    attributes.getValue(i));
526                 while (tokenizer.hasMoreTokens()) {
527                     String JavaDoc typeName = tokenizer.nextToken();
528                     int classIndex = typeName.lastIndexOf('.');
529                     Class JavaDoc typeClass;
530
531                     if (classIndex == -1) {
532                         typeClass = ColorType JavaDoc.class;
533                         classIndex = 0;
534                     }
535                     else {
536                         try {
537                             typeClass = Class.forName(typeName.substring(
538                                                       0, classIndex));
539                         } catch (ClassNotFoundException JavaDoc cnfe) {
540                             throw new SAXException("Unknown class: " +
541                                       typeName.substring(0, classIndex));
542                         }
543                         classIndex++;
544                     }
545                     try {
546                         _colorTypes.add((ColorType JavaDoc)checkCast(typeClass.
547                               getField(typeName.substring(classIndex,
548                               typeName.length() - classIndex)).
549                               get(typeClass), ColorType JavaDoc.class));
550                     } catch (NoSuchFieldException JavaDoc nsfe) {
551                         throw new SAXException("Unable to find color type: " +
552                                                typeName);
553                     } catch (IllegalAccessException JavaDoc iae) {
554                         throw new SAXException("Unable to find color type: " +
555                                                typeName);
556                     }
557                 }
558             }
559         }
560         if (color == null) {
561             throw new SAXException("color: you must specificy a value");
562         }
563         register(id, color);
564         if (_stateInfo != null && _colorTypes.size() > 0) {
565             Color[] colors = _stateInfo.getColors();
566             int max = 0;
567             for (int counter = _colorTypes.size() - 1; counter >= 0;
568                      counter--) {
569                 max = Math.max(max, ((ColorType JavaDoc)_colorTypes.get(counter)).
570                                getID());
571             }
572             if (colors == null || colors.length <= max) {
573                 Color[] newColors = new Color[max + 1];
574                 if (colors != null) {
575                     System.arraycopy(colors, 0, newColors, 0, colors.length);
576                 }
577                 colors = newColors;
578             }
579             for (int counter = _colorTypes.size() - 1; counter >= 0;
580                      counter--) {
581                 colors[((ColorType JavaDoc)_colorTypes.get(counter)).getID()] = color;
582             }
583             _stateInfo.setColors(colors);
584         }
585     }
586
587     private void startProperty(AttributeList attributes,
588                                Object JavaDoc property) throws SAXException {
589         Object JavaDoc value = null;
590         Object JavaDoc key = null;
591         // Type of the value: 0=idref, 1=boolean, 2=dimension, 3=insets,
592
// 4=integer
593
int iType = 0;
594         String JavaDoc aValue = null;
595
596         for(int i = attributes.getLength() - 1; i >= 0; i--) {
597             String JavaDoc aName = attributes.getName(i);
598             if (aName.equals(ATTRIBUTE_TYPE)) {
599                 String JavaDoc type = attributes.getValue(i).toUpperCase();
600                 if (type.equals("IDREF")) {
601                     iType = 0;
602                 }
603                 else if (type.equals("BOOLEAN")) {
604                     iType = 1;
605                 }
606                 else if (type.equals("DIMENSION")) {
607                     iType = 2;
608                 }
609                 else if (type.equals("INSETS")) {
610                     iType = 3;
611                 }
612                 else if (type.equals("INTEGER")) {
613                     iType = 4;
614                 }
615                 else {
616                     throw new SAXException(property + " unknown type, use" +
617                         "idref, boolean, dimension, insets or integer");
618                 }
619             }
620             else if (aName.equals(ATTRIBUTE_VALUE)) {
621                 aValue = attributes.getValue(i);
622             }
623             else if (aName.equals(ATTRIBUTE_KEY)) {
624                 key = attributes.getValue(i);
625             }
626         }
627         if (aValue != null) {
628             switch (iType) {
629             case 0: // idref
630
value = lookup(aValue, Object JavaDoc.class);
631                 break;
632             case 1: // boolean
633
if (aValue.toUpperCase().equals("TRUE")) {
634                     value = Boolean.TRUE;
635                 }
636                 else {
637                     value = Boolean.FALSE;
638                 }
639                 break;
640             case 2: // dimension
641
StringTokenizer tok = new StringTokenizer(aValue);
642                 value = new DimensionUIResource(
643                     nextInt(tok, "Invalid dimension"),
644                     nextInt(tok, "Invalid dimension"));
645                 break;
646             case 3: // insets
647
value = parseInsets(aValue, property + " invalid insets");
648                 break;
649             case 4: // integer
650
try {
651                     value = new Integer JavaDoc(Integer.parseInt(aValue));
652                 } catch (NumberFormatException JavaDoc nfe) {
653                     throw new SAXException(property + " invalid value");
654                 }
655                 break;
656             }
657         }
658         if (value == null || key == null) {
659             throw new SAXException(property + ": you must supply a " +
660                                    "key and value");
661         }
662         if (property == ELEMENT_DEFAULTS_PROPERTY) {
663             _defaultsMap.put(key, value);
664         }
665         else if (_stateInfo != null) {
666             if (_stateInfo.getData() == null) {
667                 _stateInfo.setData(new HashMap());
668             }
669             _stateInfo.getData().put(key, value);
670         }
671         else if (_style != null) {
672             if (_style.getData() == null) {
673                 _style.setData(new HashMap());
674             }
675             _style.getData().put(key, value);
676         }
677     }
678
679     private void startGraphics(AttributeList attributes) throws SAXException {
680         SynthGraphicsUtils JavaDoc graphics = null;
681
682         for(int i = attributes.getLength() - 1; i >= 0; i--) {
683             String JavaDoc key = attributes.getName(i);
684             if (key.equals(ATTRIBUTE_IDREF)) {
685                 graphics = (SynthGraphicsUtils JavaDoc)lookup(attributes.getValue(i),
686                                                  SynthGraphicsUtils JavaDoc.class);
687             }
688         }
689         if (graphics == null) {
690             throw new SAXException("graphicsUtils: you must supply an idref");
691         }
692         if (_style != null) {
693             _style.setGraphicsUtils(graphics);
694         }
695     }
696
697     private void startInsets(AttributeList attributes) throws SAXException {
698         int top = 0;
699         int bottom = 0;
700         int left = 0;
701         int right = 0;
702         Insets insets = null;
703         String JavaDoc id = null;
704
705         for(int i = attributes.getLength() - 1; i >= 0; i--) {
706             String JavaDoc key = attributes.getName(i);
707
708             try {
709                 if (key.equals(ATTRIBUTE_IDREF)) {
710                     insets = (Insets)lookup(attributes.getValue(i),
711                                                    Insets.class);
712                 }
713                 else if (key.equals(ATTRIBUTE_ID)) {
714                     id = attributes.getValue(i);
715                 }
716                 else if (key.equals(ATTRIBUTE_TOP)) {
717                     top = Integer.parseInt(attributes.getValue(i));
718                 }
719                 else if (key.equals(ATTRIBUTE_LEFT)) {
720                     left = Integer.parseInt(attributes.getValue(i));
721                 }
722                 else if (key.equals(ATTRIBUTE_BOTTOM)) {
723                     bottom = Integer.parseInt(attributes.getValue(i));
724                 }
725                 else if (key.equals(ATTRIBUTE_RIGHT)) {
726                     right = Integer.parseInt(attributes.getValue(i));
727                 }
728             } catch (NumberFormatException JavaDoc nfe) {
729                 throw new SAXException("insets: bad integer value for " +
730                                        attributes.getValue(i));
731             }
732         }
733         if (insets == null) {
734             insets = new InsetsUIResource(top, left, bottom, right);
735         }
736         register(id, insets);
737         if (_style != null) {
738             _style.setInsets(insets);
739         }
740     }
741
742     private void startBind(AttributeList attributes) throws SAXException {
743         ParsedSynthStyle JavaDoc style = null;
744         String JavaDoc path = null;
745         int type = -1;
746
747         for(int i = attributes.getLength() - 1; i >= 0; i--) {
748             String JavaDoc key = attributes.getName(i);
749
750             if (key.equals(ATTRIBUTE_STYLE)) {
751                 style = (ParsedSynthStyle JavaDoc)lookup(attributes.getValue(i),
752                                                   ParsedSynthStyle JavaDoc.class);
753             }
754             else if (key.equals(ATTRIBUTE_TYPE)) {
755                 String JavaDoc typeS = attributes.getValue(i).toUpperCase();
756
757                 if (typeS.equals("NAME")) {
758                     type = DefaultSynthStyleFactory.NAME;
759                 }
760                 else if (typeS.equals("REGION")) {
761                     type = DefaultSynthStyleFactory.REGION;
762                 }
763                 else {
764                     throw new SAXException("bind: unknown type " + typeS);
765                 }
766             }
767             else if (key.equals(ATTRIBUTE_KEY)) {
768                 path = attributes.getValue(i);
769             }
770         }
771         if (style == null || path == null || type == -1) {
772             throw new SAXException("bind: you must specify a style, type " +
773                                    "and key");
774         }
775         try {
776             _factory.addStyle(style, path, type);
777         } catch (PatternSyntaxException pse) {
778             throw new SAXException("bind: " + path + " is not a valid " +
779                                    "regular expression");
780         }
781     }
782
783     private void startPainter(AttributeList attributes, String JavaDoc type) throws SAXException {
784         Insets sourceInsets = null;
785         Insets destInsets = null;
786         String JavaDoc path = null;
787         boolean paintCenter = true;
788         boolean stretch = true;
789         SynthPainter JavaDoc painter = null;
790         String JavaDoc method = null;
791         String JavaDoc id = null;
792         int direction = -1;
793
794         for(int i = attributes.getLength() - 1; i >= 0; i--) {
795             String JavaDoc key = attributes.getName(i);
796             String JavaDoc value = attributes.getValue(i);
797
798             if (key.equals(ATTRIBUTE_ID)) {
799                 id = value;
800             }
801             else if (key.equals(ATTRIBUTE_METHOD)) {
802                 method = value;
803             }
804             else if (key.equals(ATTRIBUTE_IDREF)) {
805                 painter = (SynthPainter JavaDoc)lookup(value, SynthPainter JavaDoc.class);
806             }
807             else if (key.equals(ATTRIBUTE_PATH)) {
808                 path = value;
809             }
810             else if (key.equals(ATTRIBUTE_SOURCE_INSETS)) {
811                 sourceInsets = parseInsets(value, type +
812                    ": sourceInsets must be top left bottom right");
813             }
814             else if (key.equals(ATTRIBUTE_DEST_INSETS)) {
815                 destInsets = parseInsets(value, type +
816                   ": destinationInsets must be top left bottom right");
817             }
818             else if (key.equals(ATTRIBUTE_PAINT_CENTER)) {
819                 paintCenter = value.toLowerCase().equals("true");
820             }
821             else if (key.equals(ATTRIBUTE_STRETCH)) {
822                 stretch = value.toLowerCase().equals("true");
823             }
824             else if (key.equals(ATTRIBUTE_DIRECTION)) {
825                 value = value.toUpperCase().intern();
826                 if (value == "EAST") {
827                     direction = SwingConstants.EAST;
828                 }
829                 else if (value == "NORTH") {
830                     direction = SwingConstants.NORTH;
831                 }
832                 else if (value == "SOUTH") {
833                     direction = SwingConstants.SOUTH;
834                 }
835                 else if (value == "WEST") {
836                     direction = SwingConstants.WEST;
837                 }
838                 else if (value == "HORIZONTAL") {
839                     direction = SwingConstants.HORIZONTAL;
840                 }
841                 else if (value == "VERTICAL") {
842                     direction = SwingConstants.VERTICAL;
843                 }
844                 else if (value == "HORIZONTAL_SPLIT") {
845                     direction = JSplitPane.HORIZONTAL_SPLIT;
846                 }
847                 else if (value == "VERTICAL_SPLIT") {
848                     direction = JSplitPane.VERTICAL_SPLIT;
849                 }
850                 else {
851                     throw new SAXException(type + ": unknown direction");
852                 }
853             }
854         }
855         if (painter == null) {
856             if (type == ELEMENT_PAINTER) {
857                 throw new SAXException(type +
858                              ": you must specify an idref");
859             }
860             if (sourceInsets == null) {
861                 throw new SAXException(
862                              "property: you must specify sourceInsets");
863             }
864             if (path == null) {
865                 throw new SAXException("property: you must specify a path");
866             }
867             painter = new ImagePainter JavaDoc(!stretch, paintCenter, null,
868                      sourceInsets, destInsets, getResource(path));
869         }
870         register(id, painter);
871         if (_stateInfo != null) {
872             _statePainters.add(new ParsedSynthStyle.PainterInfo JavaDoc(
873                                    method, painter, direction));
874         }
875         else if (_style != null) {
876             _stylePainters.add(new ParsedSynthStyle.PainterInfo JavaDoc(
877                                    method, painter, direction));
878         }
879     }
880
881     private void startImageIcon(AttributeList attributes) throws SAXException {
882         String JavaDoc path = null;
883         String JavaDoc id = null;
884
885         for(int i = attributes.getLength() - 1; i >= 0; i--) {
886             String JavaDoc key = attributes.getName(i);
887
888             if (key.equals(ATTRIBUTE_ID)) {
889                 id = attributes.getValue(i);
890             }
891             else if (key.equals(ATTRIBUTE_PATH)) {
892                 path = attributes.getValue(i);
893             }
894         }
895         if (path == null) {
896             throw new SAXException("imageIcon: you must specify a path");
897         }
898         register(id, new LazyImageIcon(getResource(path)));
899        }
900
901     private void startOpaque(AttributeList attributes) throws
902                       SAXException {
903         if (_style != null) {
904             _style.setOpaque(true);
905             for(int i = attributes.getLength() - 1; i >= 0; i--) {
906                 String JavaDoc key = attributes.getName(i);
907
908                 if (key.equals(ATTRIBUTE_VALUE)) {
909                     _style.setOpaque("true".equals(attributes.getValue(i).
910                                                    toLowerCase()));
911                 }
912             }
913         }
914     }
915
916     private void startInputMap(AttributeList attributes) throws SAXException {
917         _inputMapBindings.clear();
918         _inputMapID = null;
919         if (_style != null) {
920             for(int i = attributes.getLength() - 1; i >= 0; i--) {
921                 String JavaDoc key = attributes.getName(i);
922
923                 if (key.equals(ATTRIBUTE_ID)) {
924                     _inputMapID = attributes.getValue(i);
925                 }
926             }
927         }
928     }
929
930     private void endInputMap() throws SAXException {
931         if (_inputMapID != null) {
932             register(_inputMapID, new UIDefaults.LazyInputMap(
933                      _inputMapBindings.toArray(new Object JavaDoc[_inputMapBindings.
934                      size()])));
935         }
936         _inputMapBindings.clear();
937         _inputMapID = null;
938     }
939
940     private void startBindKey(AttributeList attributes) throws SAXException {
941         if (_inputMapID == null) {
942             // Not in an inputmap, bail.
943
return;
944         }
945         if (_style != null) {
946             String JavaDoc key = null;
947             String JavaDoc value = null;
948             for(int i = attributes.getLength() - 1; i >= 0; i--) {
949                 String JavaDoc aKey = attributes.getName(i);
950
951                 if (aKey.equals(ATTRIBUTE_KEY)) {
952                     key = attributes.getValue(i);
953                 }
954                 else if (aKey.equals(ATTRIBUTE_ACTION)) {
955                     value = attributes.getValue(i);
956                 }
957             }
958             if (key == null || value == null) {
959                 throw new SAXException(
960                     "bindKey: you must supply a key and action");
961             }
962             _inputMapBindings.add(key);
963             _inputMapBindings.add(value);
964         }
965     }
966
967     //
968
// SAX methods, these forward to the ObjectHandler if we don't know
969
// the element name.
970
//
971

972     public InputSource resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
973                               throws SAXException {
974         if (isForwarding()) {
975             return getHandler().resolveEntity(publicId, systemId);
976         }
977         return null;
978     }
979
980     public void notationDecl(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId) {
981         if (isForwarding()) {
982             getHandler().notationDecl(name, publicId, systemId);
983         }
984     }
985
986     public void unparsedEntityDecl(String JavaDoc name, String JavaDoc publicId,
987                                    String JavaDoc systemId, String JavaDoc notationName) {
988         if (isForwarding()) {
989             getHandler().unparsedEntityDecl(name, publicId, systemId,
990                                             notationName);
991         }
992     }
993
994     public void setDocumentLocator(Locator locator) {
995         if (isForwarding()) {
996             getHandler().setDocumentLocator(locator);
997         }
998     }
999
1000    public void startDocument() throws SAXException {
1001        if (isForwarding()) {
1002            getHandler().startDocument();
1003        }
1004    }
1005
1006    public void endDocument() throws SAXException {
1007        if (isForwarding()) {
1008            getHandler().endDocument();
1009        }
1010    }
1011
1012    public void startElement(String JavaDoc name, AttributeList attributes)
1013                 throws SAXException {
1014        name = name.intern();
1015        if (name == ELEMENT_STYLE) {
1016            startStyle(attributes);
1017        }
1018        else if (name == ELEMENT_STATE) {
1019            startState(attributes);
1020        }
1021        else if (name == ELEMENT_FONT) {
1022            startFont(attributes);
1023        }
1024        else if (name == ELEMENT_COLOR) {
1025            startColor(attributes);
1026        }
1027        else if (name == ELEMENT_PAINTER) {
1028            startPainter(attributes, name);
1029        }
1030        else if (name == ELEMENT_IMAGE_PAINTER) {
1031            startPainter(attributes, name);
1032        }
1033        else if (name == ELEMENT_PROPERTY) {
1034            startProperty(attributes, ELEMENT_PROPERTY);
1035        }
1036        else if (name == ELEMENT_DEFAULTS_PROPERTY) {
1037            startProperty(attributes, ELEMENT_DEFAULTS_PROPERTY);
1038        }
1039        else if (name == ELEMENT_SYNTH_GRAPHICS) {
1040            startGraphics(attributes);
1041        }
1042        else if (name == ELEMENT_INSETS) {
1043            startInsets(attributes);
1044        }
1045        else if (name == ELEMENT_BIND) {
1046            startBind(attributes);
1047        }
1048        else if (name == ELEMENT_BIND_KEY) {
1049            startBindKey(attributes);
1050        }
1051        else if (name == ELEMENT_IMAGE_ICON) {
1052            startImageIcon(attributes);
1053        }
1054        else if (name == ELEMENT_OPAQUE) {
1055            startOpaque(attributes);
1056        }
1057        else if (name == ELEMENT_INPUT_MAP) {
1058            startInputMap(attributes);
1059        }
1060        else if (name != ELEMENT_SYNTH) {
1061            if (_depth++ == 0) {
1062                getHandler().reset();
1063            }
1064            getHandler().startElement(name, attributes);
1065        }
1066    }
1067
1068    public void endElement(String JavaDoc name) throws SAXException {
1069        if (isForwarding()) {
1070            getHandler().endElement(name);
1071            _depth--;
1072            if (!isForwarding()) {
1073                getHandler().reset();
1074            }
1075        }
1076        else {
1077            name = name.intern();
1078            if (name == ELEMENT_STYLE) {
1079                endStyle();
1080            }
1081            else if (name == ELEMENT_STATE) {
1082                endState();
1083            }
1084            else if (name == ELEMENT_INPUT_MAP) {
1085                endInputMap();
1086            }
1087        }
1088    }
1089
1090    public void characters(char ch[], int start, int length)
1091                           throws SAXException {
1092        if (isForwarding()) {
1093            getHandler().characters(ch, start, length);
1094        }
1095    }
1096
1097    public void ignorableWhitespace (char ch[], int start, int length)
1098    throws SAXException {
1099        if (isForwarding()) {
1100            getHandler().ignorableWhitespace(ch, start, length);
1101        }
1102    }
1103
1104    public void processingInstruction(String JavaDoc target, String JavaDoc data)
1105                                     throws SAXException {
1106        if (isForwarding()) {
1107            getHandler().processingInstruction(target, data);
1108        }
1109    }
1110
1111    public void warning(SAXParseException e) throws SAXException {
1112        if (isForwarding()) {
1113            getHandler().warning(e);
1114        }
1115    }
1116
1117    public void error(SAXParseException e) throws SAXException {
1118        if (isForwarding()) {
1119            getHandler().error(e);
1120        }
1121    }
1122    
1123    
1124    public void fatalError(SAXParseException e) throws SAXException {
1125        if (isForwarding()) {
1126            getHandler().fatalError(e);
1127        }
1128    throw e;
1129    }
1130
1131
1132    /**
1133     * ImageIcon that lazily loads the image until needed.
1134     */

1135    private static class LazyImageIcon extends ImageIcon implements UIResource {
1136        private URL location;
1137
1138        public LazyImageIcon(URL location) {
1139            super();
1140            this.location = location;
1141        }
1142
1143        public void paintIcon(Component c, Graphics g, int x, int y) {
1144            if (getImage() != null) {
1145                super.paintIcon(c, g, x, y);
1146            }
1147        }
1148    
1149        public int getIconWidth() {
1150            if (getImage() != null) {
1151                return super.getIconWidth();
1152            }
1153            return 0;
1154        }
1155
1156        public int getIconHeight() {
1157            if (getImage() != null) {
1158                return super.getIconHeight();
1159            }
1160            return 0;
1161        }
1162
1163        public Image getImage() {
1164            if (location != null) {
1165                setImage(Toolkit.getDefaultToolkit().getImage(location));
1166                location = null;
1167            }
1168            return super.getImage();
1169        }
1170    }
1171}
1172
Popular Tags