KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > plaf > util > NbTheme


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.swing.plaf.util;
21
22 import org.xml.sax.InputSource JavaDoc;
23 import org.xml.sax.Locator JavaDoc;
24 import org.xml.sax.Parser JavaDoc;
25 import org.xml.sax.SAXException JavaDoc;
26 import org.xml.sax.helpers.XMLReaderAdapter JavaDoc;
27
28 import javax.swing.*;
29 import javax.swing.border.BevelBorder JavaDoc;
30 import javax.swing.border.EtchedBorder JavaDoc;
31 import javax.swing.plaf.*;
32 import javax.swing.plaf.metal.MetalTheme JavaDoc;
33 import javax.xml.parsers.ParserConfigurationException JavaDoc;
34 import javax.xml.parsers.SAXParserFactory JavaDoc;
35 import java.awt.*;
36 import java.net.URL JavaDoc;
37 import java.util.HashSet JavaDoc;
38 import java.util.StringTokenizer JavaDoc;
39
40 /** An extension of javax.swing.plaf.metal.DefaultMetalTheme which can read a an xml
41  * file named <code>themes.xml</code> and apply the theme defined in XML. NbTheme
42  * stores its data in the <code>UIDefaults</code> instance available from the
43  * look-and-feel manager (<code>UiManager.getLookAndFeel.getDefaults()</code>).
44  * These means that theme files may also override per-component-type settings
45  * stored there, so changes to look and feel deeper than those afforded by the
46  * <code>MetalTheme</code> parent class are possible.
47  * <P>
48  * <code>NbTheme</code> supports seven kinds of data: Colors, Fonts, Integers,
49  * Strings, Borders, Insets and Booleans, which are the major interesting data types typical
50  * stored in <code>UIDefaults</code>. For usage instructions and details,
51  * see <A HREF="http://ui.netbeans.org/docs/ui/themes/themes.html">the themes
52  * documentation</a> on the NetBeans web site.
53  *
54  * @author Jiri Mzourek, Tim Boudreau
55  * @see http://ui.netbeans.org/docs/ui/themes/themes.html
56  */

57 public class NbTheme extends MetalTheme JavaDoc implements org.xml.sax.DocumentHandler JavaDoc {
58     
59     /** The unqualified name for the theme file to use. */
60     public static final String JavaDoc THEMEFILE_NAME = "themes.xml"; // NOI18N
61
// legal xml tags for theme files
62
private static final String JavaDoc THEMESET_TAG = "themeset"; // NOI18N
63
private static final String JavaDoc ACTIVE_ATTR = "active"; // NOI18N
64
private static final String JavaDoc THEME_TAG = "theme"; // NOI18N
65
private static final String JavaDoc BOOL_TAG = "boolean"; // NOI18N
66
private static final String JavaDoc DIM_TAG = "dimension"; // NOI18N
67
private static final String JavaDoc FONT_TAG = "font"; // NOI18N
68
private static final String JavaDoc INSETS_TAG = "insets"; // NOI18N
69
private static final String JavaDoc ETCHEDBORDER_TAG = "etchedborder";
70     private static final String JavaDoc EMPTYBORDER_TAG = "emptyborder";
71     private static final String JavaDoc BEVELBORDER_TAG = "bevelborder";
72     private static final String JavaDoc LINEBORDER_TAG = "lineborder";
73     // attributes recognized in various tags
74
private static final String JavaDoc COLOR_ATTR = "color"; // NOI18N
75
private static final String JavaDoc KEY_ATTR = "key"; // NOI18N
76
private static final String JavaDoc METRIC_TAG = "metric"; // NOI18N
77
private static final String JavaDoc STRING_TAG = "string"; // NOI18N
78
private static final String JavaDoc NAME_ATTR = "name"; // NOI18N
79
private static final String JavaDoc FONTSTYLE_ATTR = "style"; // NOI18N
80
private static final String JavaDoc FONTSIZE_ATTR = "size"; // NOI18N
81
private static final String JavaDoc VALUE_ATTR = "value"; //NOI18N
82
private static final String JavaDoc WIDTH_ATTR = "width"; //NOI18N
83
private static final String JavaDoc HEIGHT_ATTR = "height"; //NOI18N
84
private static final String JavaDoc RED_ATTR = "r"; // NOI18N
85
private static final String JavaDoc GREEN_ATTR = "g"; // NOI18N
86
private static final String JavaDoc BLUE_ATTR = "b"; // NOI18N
87
private static final String JavaDoc LEFT_ATTR = "left"; // NOI18N
88
private static final String JavaDoc TOP_ATTR = "top"; // NOI18N
89
private static final String JavaDoc RIGHT_ATTR = "right"; // NOI18N
90
private static final String JavaDoc BOTTOM_ATTR = "bottom"; // NOI18N
91
private static final String JavaDoc TYPE_ATTR = "type"; // NOI18N
92
private static final String JavaDoc REFERENCE_ATTR = "reference"; // NOI18N
93
// font styles
94
private static final String JavaDoc FONTSTYLE_BOLD = "bold"; // NOI18N
95
private static final String JavaDoc FONTSTYLE_ITALIC = "italic"; // NOI18N
96
//border types
97
private static final String JavaDoc TYPE_LOWERED = "lowered"; // NOI18N
98

99     // keys used to store theme values in UIDefaults
100
private static final String JavaDoc CONTROLFONT = "controlFont"; // NOI18N
101
private static final String JavaDoc SYSTEMFONT = "systemFont"; // NOI18N
102
private static final String JavaDoc USERFONT = "userFont"; // NOI18N
103
private static final String JavaDoc MENUFONT = "menuFont"; // NOI18N
104
private static final String JavaDoc WINDOWTITLEFONT = "windowTitleFont"; // NOI18N
105
private static final String JavaDoc SUBFONT = "subFont"; // NOI18N
106

107     //Keys below here are MetalTheme-specific and have no meaning on
108
//non-Metal look and feels
109
private static final String JavaDoc PRIMARY1 = "primary1"; // NOI18N
110
private static final String JavaDoc PRIMARY2 = "primary2"; // NOI18N
111
private static final String JavaDoc PRIMARY3 = "primary3"; // NOI18N
112
private static final String JavaDoc SECONDARY1 = "secondary1"; // NOI18N
113
private static final String JavaDoc SECONDARY2 = "secondary2"; // NOI18N
114
private static final String JavaDoc SECONDARY3 = "secondary3"; // NOI18N
115
private static final String JavaDoc WHITE = "white"; // NOI18N
116
private static final String JavaDoc BLACK = "black"; // NOI18N
117

118     private HashSet JavaDoc<String JavaDoc> activeThemes=null;
119     private boolean inActiveTheme=false;
120     private URL JavaDoc themeURL = null;
121     
122     private UIDefaults defaults;
123     public String JavaDoc getName(){ return "NetBeans XML Theme"; } // NOI18N
124
/** Create a new instance of NBTheme */
125     public NbTheme(URL JavaDoc themeURL, LookAndFeel lf) {
126         this.themeURL = themeURL;
127         defaults = lf.getDefaults();
128         initThemeDefaults();
129         parseTheme();
130         UIManager.getDefaults().putAll (defaults);
131     }
132     
133     /** Add any custom UIDefault values for Metal L&F here */
134     void initThemeDefaults () {
135         defaults.put(PRIMARY1, new ColorUIResource(102, 102, 153));
136         defaults.put(PRIMARY2, new ColorUIResource(153, 153, 204));
137         defaults.put(PRIMARY3, new ColorUIResource(204, 204, 255));
138
139         defaults.put(SECONDARY1, new ColorUIResource(102, 102, 102));
140         defaults.put(SECONDARY2, new ColorUIResource(153, 153, 153));
141         defaults.put(SECONDARY3, new ColorUIResource(204, 204, 204));
142         
143         defaults.put(WHITE, new ColorUIResource(255,255,255));
144         defaults.put(BLACK, new ColorUIResource(0,0,0));
145     }
146     
147     private void parseTheme(){
148         try{
149             SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
150             factory.setValidating(false);
151             factory.setNamespaceAware(false);
152
153             Parser JavaDoc p = new XMLReaderAdapter JavaDoc(factory.newSAXParser().getXMLReader());
154             p.setDocumentHandler(this);
155             String JavaDoc externalForm = themeURL.toExternalForm();
156             InputSource JavaDoc is = new InputSource JavaDoc(externalForm);
157             p.parse(is);
158             activeThemes=null; //dispose of now useless hashtable
159
locator = null;
160         }
161         catch(java.io.IOException JavaDoc ie){
162             System.err.println ("IO exception reading theme file"); //NOI18N
163
} catch(org.xml.sax.SAXException JavaDoc se){
164             System.err.println ("Error parsing theme file " + (locator != null ? "line " + locator.getLineNumber() : "")); //NOI18N
165
} catch (ParserConfigurationException JavaDoc e) {
166             System.err.println ("Couldn't create XML parser for theme file"); //NOI18N
167
}
168     }
169     
170     public void endDocument() throws org.xml.sax.SAXException JavaDoc {
171     }
172     
173     public void startDocument() throws org.xml.sax.SAXException JavaDoc {
174     }
175     
176     public void startElement(java.lang.String JavaDoc p1,org.xml.sax.AttributeList JavaDoc atts) throws org.xml.sax.SAXException JavaDoc {
177          //found the themeset?
178
if (p1.equals(THEMESET_TAG)) {
179             //break out the comma delimited list of active themes
180
//and stores them in activeThemes hashset
181
String JavaDoc themes = atts.getValue (ACTIVE_ATTR);
182             if (themes != null) {
183                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc (themes, ","); //NOI18N
184
activeThemes = new HashSet JavaDoc<String JavaDoc> (tok.countTokens() + 1);
185                 while (tok.hasMoreTokens()) {
186                     activeThemes.add(tok.nextToken().trim());
187                 }
188             }
189         }
190         else{
191             if (p1.equals(THEME_TAG) && (activeThemes != null)) {
192                 //see if the current theme is one of the active ones
193
String JavaDoc themeName = atts.getValue (NAME_ATTR);
194                 inActiveTheme = activeThemes.contains(themeName);
195             } else {
196                 if (inActiveTheme) {
197                     if (handleReference(atts)) {
198                         return;
199                     }
200                     if (p1.equals (COLOR_ATTR)) {
201                         handleColor (atts);
202                         return;
203                     }
204                     if (p1.equals (FONT_TAG)) {
205                         handleFont (atts);
206                         return;
207                     }
208                     if (p1.equals (EMPTYBORDER_TAG)) {
209                         handleEmptyBorder (atts);
210                         return;
211                     }
212                     if (p1.equals (METRIC_TAG)) {
213                         handleMetric (atts);
214                         return;
215                     }
216                     if (p1.equals (STRING_TAG)) {
217                         handleString (atts);
218                         return;
219                     }
220                     if (p1.equals (INSETS_TAG)) {
221                         handleInsets (atts);
222                         return;
223                     }
224                     if (p1.equals (BOOL_TAG)) {
225                         handleBool (atts);
226                         return;
227                     }
228                     if (p1.equals (DIM_TAG)) {
229                         handleDim (atts);
230                         return;
231                     }
232                     if (p1.equals (ETCHEDBORDER_TAG)) {
233                         handleEtchedBorder (atts);
234                         return;
235                     }
236                     if (p1.equals (LINEBORDER_TAG)) {
237                         handleLineBorder (atts);
238                         return;
239                     }
240                     if (p1.equals (BEVELBORDER_TAG)) {
241                         handleBevelBorder (atts);
242                         return;
243                     }
244                     System.err.println("UNRECOGNIZED " +
245                             "THEME ENTRY " + p1 + "\" " + atts.toString()); //NOI18N
246
}
247             }
248         }
249     }
250     
251     private boolean handleReference(org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
252         String JavaDoc key = atts.getValue (KEY_ATTR);
253         String JavaDoc reference = atts.getValue(REFERENCE_ATTR);
254         if (reference != null) {
255             Object JavaDoc res = defaults.get(reference);
256             if (res != null) {
257                 defaults.put(key, res);
258                 return true;
259             }
260         }
261         return false;
262     }
263     
264     private final void handleFont (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
265         String JavaDoc key = atts.getValue (KEY_ATTR);
266         String JavaDoc fontname = atts.getValue (NAME_ATTR);
267         String JavaDoc fontstylename = atts.getValue (FONTSTYLE_ATTR);
268         int fontsize = intFromAttr (atts, FONTSIZE_ATTR);
269         int fontstyle = Font.PLAIN;
270         if(fontstylename.equals(FONTSTYLE_BOLD)) {
271             fontstyle = Font.BOLD;
272         } else {
273             if(fontstylename.equals(FONTSTYLE_ITALIC)) fontstyle = Font.ITALIC;
274         }
275         
276         FontUIResource resource = new FontUIResource (fontname, fontstyle, fontsize);
277         defaults.put (key, resource);
278     }
279         
280     private final void handleColor (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
281         int r = intFromAttr (atts, RED_ATTR);
282         int g = intFromAttr (atts, GREEN_ATTR);
283         int b = intFromAttr (atts, BLUE_ATTR);
284         String JavaDoc key = atts.getValue(KEY_ATTR);
285         ColorUIResource resource = new ColorUIResource (r,g,b);
286         defaults.put (key, resource);
287     }
288
289     private final void handleMetric (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
290         String JavaDoc key = atts.getValue(KEY_ATTR);
291         Integer JavaDoc resource = Integer.valueOf (atts.getValue(VALUE_ATTR));
292         defaults.put (key, resource);
293     }
294     
295     private final void handleString (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
296         String JavaDoc key = atts.getValue (KEY_ATTR);
297         String JavaDoc resource = atts.getValue (VALUE_ATTR);
298         defaults.put (key, resource);
299     }
300
301     private final void handleBool (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
302         String JavaDoc key = atts.getValue (KEY_ATTR);
303         Boolean JavaDoc resource = Boolean.valueOf (key);
304         defaults.put (key, resource);
305     }
306     
307     private final void handleDim (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
308         String JavaDoc key = atts.getValue (KEY_ATTR);
309         int width = intFromAttr (atts, WIDTH_ATTR);
310         int height = intFromAttr (atts, HEIGHT_ATTR);
311         DimensionUIResource resource = new DimensionUIResource (width, height);
312         defaults.put (key, resource);
313     }
314     
315     private final void handleInsets (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
316         String JavaDoc key = atts.getValue (KEY_ATTR);
317         int top = intFromAttr (atts, TOP_ATTR);
318         int left = intFromAttr (atts, LEFT_ATTR);
319         int bottom = intFromAttr (atts, BOTTOM_ATTR);
320         int right = intFromAttr (atts, RIGHT_ATTR);
321         InsetsUIResource resource = new InsetsUIResource (top, left, bottom,
322           right);
323         defaults.put (key, resource);
324     }
325
326     private final void handleEtchedBorder (org.xml.sax.AttributeList JavaDoc atts) {
327         String JavaDoc key = atts.getValue (KEY_ATTR);
328         int i = EtchedBorder.LOWERED;
329         String JavaDoc type = atts.getValue (TYPE_ATTR);
330         if (type != null)
331             i = type.equals (TYPE_LOWERED) ? EtchedBorder.LOWERED : EtchedBorder.RAISED;
332         BorderUIResource.EtchedBorderUIResource resource = new BorderUIResource.EtchedBorderUIResource (i);
333         defaults.put (key, resource);
334     }
335     
336     private final void handleBevelBorder (org.xml.sax.AttributeList JavaDoc atts) {
337         String JavaDoc key = atts.getValue (KEY_ATTR);
338         int i = BevelBorder.LOWERED;
339         String JavaDoc type = atts.getValue (TYPE_ATTR);
340         if (type != null)
341             i = type.equals (TYPE_LOWERED) ? BevelBorder.LOWERED : BevelBorder.RAISED;
342         BorderUIResource.BevelBorderUIResource resource = new BorderUIResource.BevelBorderUIResource (i);
343         defaults.put (key, resource);
344     }
345     
346     private final void handleEmptyBorder (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
347         String JavaDoc key = atts.getValue (KEY_ATTR);
348         int top = intFromAttr (atts, TOP_ATTR);
349         int left = intFromAttr (atts, LEFT_ATTR);
350         int bottom = intFromAttr (atts, BOTTOM_ATTR);
351         int right = intFromAttr (atts, RIGHT_ATTR);
352         BorderUIResource.EmptyBorderUIResource resource = new BorderUIResource.EmptyBorderUIResource (top, left, bottom, right);
353         defaults.put (key, resource);
354     }
355     
356     private final void handleLineBorder (org.xml.sax.AttributeList JavaDoc atts) throws SAXException JavaDoc {
357         String JavaDoc key = atts.getValue (KEY_ATTR);
358         int r = intFromAttr (atts, RED_ATTR);
359         int g = intFromAttr (atts, GREEN_ATTR);
360         int b = intFromAttr (atts, BLUE_ATTR);
361         int width = 1;
362         if (atts.getValue(WIDTH_ATTR) != null) {
363             width = intFromAttr (atts, WIDTH_ATTR);
364         }
365         Color c = new Color (r,g,b);
366         BorderUIResource.LineBorderUIResource resource = new BorderUIResource.LineBorderUIResource (c);
367         defaults.put (key, resource);
368     }
369     
370     private final int intFromAttr (final org.xml.sax.AttributeList JavaDoc atts, final String JavaDoc key) throws SAXException JavaDoc {
371         try {
372             return Integer.valueOf (atts.getValue (key)).intValue();
373         } catch (NumberFormatException JavaDoc nfe) {
374             throw new SAXException JavaDoc (atts.getValue(key) + " is not an integer");
375         }
376     }
377     
378     public void characters(char[] p1,int p2,int p3) throws org.xml.sax.SAXException JavaDoc {
379     }
380
381     Locator JavaDoc locator = null;
382     public void setDocumentLocator(org.xml.sax.Locator JavaDoc locator) {
383         this.locator = locator;
384     }
385     
386     public void endElement(java.lang.String JavaDoc p1) throws org.xml.sax.SAXException JavaDoc {
387         if(p1.equals(THEME_TAG)){
388             inActiveTheme=false;
389         }
390     }
391     
392     public void ignorableWhitespace(char[] p1,int p2,int p3) throws org.xml.sax.SAXException JavaDoc {
393     }
394     
395     public void processingInstruction(java.lang.String JavaDoc p1,java.lang.String JavaDoc p2) throws org.xml.sax.SAXException JavaDoc {
396     }
397
398     private final ColorUIResource getColor(String JavaDoc key) {
399         return (ColorUIResource) defaults.get (key);
400     }
401     
402     private final FontUIResource getFont(String JavaDoc key) {
403         return (FontUIResource) defaults.get (key);
404     }
405     
406     public FontUIResource getControlTextFont() { return getFont (CONTROLFONT); }
407     public FontUIResource getSystemTextFont() { return getFont (SYSTEMFONT); }
408     public FontUIResource getUserTextFont() { return getFont (USERFONT); }
409     public FontUIResource getMenuTextFont() { return getFont (MENUFONT); }
410     public FontUIResource getWindowTitleFont() { return getFont (WINDOWTITLEFONT); }
411     public FontUIResource getSubTextFont() { return getFont (SUBFONT); }
412     protected ColorUIResource getPrimary1() { return getColor (PRIMARY1); }
413     protected ColorUIResource getPrimary2() { return getColor (PRIMARY2); }
414     protected ColorUIResource getPrimary3() { return getColor (PRIMARY3); }
415     protected ColorUIResource getSecondary1() { return getColor (SECONDARY1); }
416     protected ColorUIResource getSecondary2() { return getColor (SECONDARY2); }
417     protected ColorUIResource getSecondary3() { return getColor (SECONDARY3); }
418     protected ColorUIResource getWhite() { return getColor (WHITE); }
419     protected ColorUIResource getBlack() { return getColor (BLACK); }
420     
421 }
422
Popular Tags