KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > plaf > Startup


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;
21
22 import java.awt.Toolkit JavaDoc;
23 import org.netbeans.swing.plaf.aqua.AquaLFCustoms;
24 import org.netbeans.swing.plaf.gtk.GtkLFCustoms;
25 import org.netbeans.swing.plaf.metal.MetalLFCustoms;
26 import org.netbeans.swing.plaf.util.NbTheme;
27 import org.netbeans.swing.plaf.util.RelativeColor;
28 import org.netbeans.swing.plaf.util.UIBootstrapValue;
29 import org.netbeans.swing.plaf.util.UIUtils;
30
31 import javax.swing.*;
32 import javax.swing.plaf.metal.MetalLookAndFeel JavaDoc;
33 import java.beans.PropertyChangeEvent JavaDoc;
34 import java.beans.PropertyChangeListener JavaDoc;
35 import java.net.URL JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.HashSet JavaDoc;
38 import java.util.Set JavaDoc;
39 import org.netbeans.swing.plaf.winclassic.WindowsLFCustoms;
40 import org.netbeans.swing.plaf.winvista.VistaLFCustoms;
41 import org.netbeans.swing.plaf.winxp.XPLFCustoms;
42
43 /** Singleton, manages customizers for various LFs. Installs, uninstalls them on LF change.
44  * LF customizers works with Swing UIManager, putting info about various UI elements
45  * in it. Other modules then can query UIManager to get UI elements to get needed
46  * visual design and behaviour.
47  *
48  * @author Dafe Simonek, Tim Boudreau
49  */

50 public final class Startup {
51     //originally LFCustomsManager
52

53     /** For debugging purposes, enable forcing the customizations for, i.e.,
54      * Windows look and feel on a platform that doesn't support it */

55     private static final String JavaDoc FORCED_CUSTOMS = System.getProperty("nb.forceui"); //NOI18N
56

57     /** Provides the ability to disable customizations for applications which, for example, provide their own
58      * subclass of MetalLookAndFeel. See issue XXX
59      */

60     private static final boolean NO_CUSTOMIZATIONS = Boolean.getBoolean("netbeans.plaf.disable.ui.customizations"); //NOI18N
61

62     /** Singleton instance */
63     private static Startup instance = null;
64     
65     /** Currently used LF customizer */
66     private LFCustoms curCustoms = null;
67     private LFCustoms globalCustoms = null;
68
69     private static URL JavaDoc themeURL = null;
70     private static Class JavaDoc uiClass = null;
71
72     private boolean installed = false;
73
74     /** Starts handling of LF customizers. Called only from getInstance. */
75     private Startup() {
76         initialize();
77     }
78
79     /** Initializes defaulf customs for all LFs and fills UIManager with
80      * references to LF customizers for supported LFs.
81      */

82     private void initialize() {
83         LookAndFeel JavaDoc lf = getLookAndFeel();
84         if (lf instanceof MetalLookAndFeel JavaDoc) {
85             //Metal theme must be assigned before using the look and feel
86
installTheme(lf);
87         }
88         // overall defaults for all LFs
89
// defaults for supported LFs
90

91         try {
92             if (lf != UIManager.getLookAndFeel()) {
93                 UIManager.setLookAndFeel (lf);
94             }
95         } catch (Exception JavaDoc e) {
96             System.err.println ("Could not install look and feel " + lf);
97         }
98     }
99
100     private LookAndFeel JavaDoc getLookAndFeel() {
101       if (uiClass == null) {
102           String JavaDoc uiClassName;
103           if (isWindows()) {
104               uiClassName = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; //NOI18N
105
} else if (isMac()){
106               uiClassName = "apple.laf.AquaLookAndFeel";
107           } else if (shouldUseMetal()) {
108               uiClassName = "javax.swing.plaf.metal.MetalLookAndFeel"; //NOI18N
109
} else {
110               //Should get us metal where it doesn't get us GTK
111
uiClassName = UIManager.getSystemLookAndFeelClassName();
112               
113               // Enable GTK L&F only for JDK version 1.6.0 update 1 and later.
114
// GTK L&F quality unacceptable for earlier versions.
115
String JavaDoc javaVersion = System.getProperty("java.version");
116               if ("1.6.0_01".compareTo(javaVersion) > 0) {
117                   // IDE runs on 1.5 or 1.6 - useGtk can enabled Gtk
118
if (uiClassName.indexOf("gtk") >= 0 && !Boolean.getBoolean("useGtk")) {
119                       uiClassName = "javax.swing.plaf.metal.MetalLookAndFeel";
120                   }
121               } else {
122                   // IDE runs on 1.6_01 or higher - useGtk can disabled Gtk
123
if (uiClassName.indexOf("gtk") >= 0 && System.getProperty("useGtk") != null && !Boolean.getBoolean("useGtk")) {
124                       uiClassName = "javax.swing.plaf.metal.MetalLookAndFeel";
125                   }
126               }
127           }
128           try {
129               uiClass = Class.forName(uiClassName);
130           } catch (ClassNotFoundException JavaDoc e) {
131               System.err.println("Custom UI class " + uiClassName + " not on classpath."); // NOI18N
132
} catch (Exception JavaDoc e) {
133               System.err.println("While loading: " + uiClassName); // NOI18N
134
e.printStackTrace();
135           }
136       }
137       LookAndFeel JavaDoc result = null;
138       if (uiClass != null) {
139           try {
140
141               LookAndFeel JavaDoc lf = UIManager.getLookAndFeel();
142               if (uiClass != lf.getClass()) {
143                   result = (LookAndFeel JavaDoc) uiClass.newInstance();
144               } else {
145                   result = UIManager.getLookAndFeel();
146               }
147           } catch (Exception JavaDoc e) {
148               System.err.println("Cannot load custom UI class " + uiClass); //NOI18N
149
e.printStackTrace();
150               result = UIManager.getLookAndFeel();
151           }
152       }
153       return result;
154     }
155
156     private void installTheme(LookAndFeel JavaDoc lf) {
157         //Load the theme
158
if (themeURL != null) {
159           NbTheme nbTheme = new NbTheme(themeURL, lf);
160           MetalLookAndFeel.setCurrentTheme(nbTheme);
161         }
162     }
163
164     /** Enables, installs LF customization. */
165     private void install () {
166         if (installed) {
167             return;
168         }
169         if (globalCustoms == null) {
170             globalCustoms = new AllLFCustoms();
171             installLFCustoms (globalCustoms);
172         }
173         installPerLFDefaults();
174         installTheme(UIManager.getLookAndFeel());
175         attachListener();
176     }
177
178     private void installPerLFDefaults() {
179         boolean isLFChange = curCustoms != null;
180         
181         curCustoms = findCustoms();
182         if (curCustoms != null) {
183             Integer JavaDoc in = (Integer JavaDoc) UIManager.get(LFCustoms.CUSTOM_FONT_SIZE); //NOI18N
184
if (in == null && UIManager.getLookAndFeel().getClass() == MetalLookAndFeel JavaDoc.class) {
185                 in = new Integer JavaDoc (11);
186             }
187
188             if (in != null) {
189                 AllLFCustoms.initCustomFontSize (in.intValue());
190             }
191             installLFCustoms (curCustoms);
192             if (isLFChange) {
193                 //make sure UIBootstrapValue.Lazy instances really get a chance
194
//to replace their values
195
loadAllLazyValues (curCustoms);
196             }
197             curCustoms.disposeValues();
198         }
199     }
200     
201     private void loadAllLazyValues (LFCustoms customs) {
202         if (globalCustoms != null) {
203             loadLazy (globalCustoms.getApplicationSpecificKeysAndValues());
204             loadLazy (globalCustoms.getGuaranteedKeysAndValues());
205             loadLazy (globalCustoms.getLookAndFeelCustomizationKeysAndValues());
206         }
207         loadLazy (customs.getApplicationSpecificKeysAndValues());
208         loadLazy (customs.getGuaranteedKeysAndValues());
209         loadLazy (customs.getLookAndFeelCustomizationKeysAndValues());
210     }
211     
212     private void loadLazy (Object JavaDoc[] o) {
213         if (o.length > 0) {
214             UIDefaults uidefaults = UIManager.getDefaults();
215             for (int i=1; i < o.length; i+=2) {
216                 if (o[i] instanceof UIBootstrapValue.Lazy) {
217                     ((UIBootstrapValue.Lazy) o[i]).createValue(uidefaults);
218                 }
219                 if (o[i] instanceof RelativeColor) {
220                     ((RelativeColor) o[i]).clear();
221                 }
222             }
223         }
224     }
225
226     private void uninstallPerLFDefaults() {
227         assert globalCustoms != null;
228
229         if (curCustoms != null) {
230             Set JavaDoc<Object JavaDoc> keep = new HashSet JavaDoc<Object JavaDoc> (Arrays.asList(globalCustoms.allKeys()));
231             Object JavaDoc[] arr = curCustoms.allKeys();
232
233             for (int i=0; i < arr.length; i++) {
234                 Object JavaDoc key = arr[i];
235                 if (!keep.contains(key)) {
236                     UIManager.put (key, null);
237                 }
238             }
239         }
240     }
241
242     private void attachListener() {
243         assert listener == null;
244         listener = new LFListener();
245         UIManager.addPropertyChangeListener(listener);
246         Toolkit.getDefaultToolkit().addPropertyChangeListener(
247             "win.xpstyle.themeActive", listener); //NOI18N
248
}
249
250     private void installLFCustoms (LFCustoms customs) {
251         UIDefaults defaults = UIManager.getDefaults();
252
253         // to make sure we always use system classloader
254
defaults.put("ClassLoader", new CLValue()); // NOI18N
255

256         //Install values that some look and feels may leave out, which should
257
//be included
258
defaults.putDefaults (customs.getGuaranteedKeysAndValues());
259         //Install entries for custom NetBeans components, such as borders and
260
//colors
261
defaults.putDefaults (customs.getApplicationSpecificKeysAndValues());
262         
263         if (!NO_CUSTOMIZATIONS) {
264             //See issue nnn - Nokia uses a custom metal-based look and feel,
265
//and do not want fonts or other things customized
266
defaults.putDefaults (customs.getLookAndFeelCustomizationKeysAndValues());
267         }
268         
269     }
270
271     /** Gets the value of system class loader and returns it.
272      */

273     private static final class CLValue implements UIDefaults.ActiveValue {
274         public Object JavaDoc createValue (UIDefaults defs) {
275             return Thread.currentThread().getContextClassLoader();
276         }
277     }
278
279     /** Finds and returns instance of LF customizer which is suitable for
280      * current look and feel.
281      */

282     private LFCustoms findCustoms () {
283         if (FORCED_CUSTOMS != null) {
284             System.err.println("Using explicitly set UI customizations: " + //NOI18N
285
FORCED_CUSTOMS);
286             if ("Vista".equals(FORCED_CUSTOMS)) { //NOI18N
287
return new VistaLFCustoms();
288             } else if ("XP".equals(FORCED_CUSTOMS)) { //NOI18N
289
return new XPLFCustoms();
290             } else if ("Aqua".equals(FORCED_CUSTOMS)) { //NOI18N
291
return new AquaLFCustoms();
292             } else if ("Metal".equals(FORCED_CUSTOMS)) { //NOI18N
293
return new MetalLFCustoms();
294             } else if ("Windows".equals(FORCED_CUSTOMS)) { //NOI18N
295
return new WindowsLFCustoms();
296             } else if ("GTK".equals(FORCED_CUSTOMS)) { //NOI18N
297
return new GtkLFCustoms();
298             } else {
299                 try {
300                     return (LFCustoms) Class.forName(FORCED_CUSTOMS).newInstance();
301                 } catch (Exception JavaDoc e) {
302                     System.err.println("UI customizations class not found: " //NOI18N
303
+ FORCED_CUSTOMS); //NOI18N
304
}
305             }
306         }
307         
308         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(40);
309         buf.append("Nb."); //NOI18N
310
buf.append(UIManager.getLookAndFeel().getID());
311         if (UIUtils.isXPLF()) {
312             if (isWindowsVista()) {
313                 buf.append("VistaLFCustoms"); //NOI18N
314
} else {
315                 buf.append("XPLFCustoms"); //NOI18N
316
}
317         } else {
318             buf.append("LFCustoms"); //NOI18N
319
}
320         
321         LFCustoms result = null;
322         try {
323             result = (LFCustoms)UIManager.get(buf.toString());
324         } catch (ClassCastException JavaDoc cce) {
325             //do nothing - the look and feel happens to have something matching
326
//our generated key there
327
}
328         if (result == null) {
329             String JavaDoc[] knownLFs = new String JavaDoc[] {
330                     "Metal", "Windows", "Aqua", "GTK" //NOI18N
331
};
332             switch (Arrays.asList(knownLFs).indexOf(UIManager.getLookAndFeel().getID())) {
333                 case 1 :
334                     if (UIUtils.isXPLF()) {
335                         if (isWindowsVista()) {
336                             result = new VistaLFCustoms();
337                         } else {
338                             result = new XPLFCustoms();
339                         }
340                     } else {
341                         result = new WindowsLFCustoms();
342                     }
343                     break;
344                 case 0 :
345                     result = new MetalLFCustoms();
346                     break;
347                 case 2 :
348                     result = new AquaLFCustoms();
349                     break;
350                 case 3 :
351                     result = new GtkLFCustoms();
352                     break;
353                 default :
354                     // #79401 check if it's XP style LnF, for example jGoodies
355
if (UIUtils.isXPLF()) {
356                         if (isWindowsVista()) {
357                             result = new VistaLFCustoms();
358                         } else {
359                             result = new XPLFCustoms();
360                         }
361                     } else {
362                         result = new WindowsLFCustoms();
363                     }
364             }
365         }
366         return result;
367     }
368     
369     /**
370      * Initialize values in UIDefaults which need to be there for NetBeans' components; apply customizations such
371      * as setting up a custom font size and loading a theme.
372      *
373      * @param uiClass The UI class which should be used for the look and feel
374      * @param uiFontSize A custom fontsize, or 0. This will be retrievable via UIManager.get("customFontSize") after this method has returned
375      * if non 0. If non zero, all of the standard Swing font keys in UIDefaults will be customized to
376      * provide a font with the requested size. Results are undefined for values less than 0 or greater
377      * than any hard limit the platform imposes on font size.
378      * @param themeURL An optional URL for a theme file, or null. Theme file format documentation can be found
379      * <a HREF="ui.netbeans.org/project/ui/docs/ui/themes/themes.html">here</a>.
380      */

381     public static void run (Class JavaDoc uiClass, int uiFontSize, URL JavaDoc themeURL) {
382         if (instance == null) {
383           // Modify default font size to the font size passed as a command-line parameter
384
if(uiFontSize>0) {
385                 Integer JavaDoc customFontSize = new Integer JavaDoc (uiFontSize);
386                 UIManager.put ("customFontSize", customFontSize);
387             }
388             Startup.uiClass = uiClass;
389             Startup.themeURL = themeURL;
390             instance = new Startup();
391             instance.install();
392         }
393     }
394
395     private boolean isWindows() {
396         String JavaDoc osName = System.getProperty ("os.name");
397         return osName.startsWith("Windows");
398     }
399
400     private boolean isWindowsVista() {
401         String JavaDoc osName = System.getProperty ("os.name");
402         return osName.indexOf("Vista") >= 0
403             || (osName.equals( "Windows NT (unknown)" ) && "6.0".equals( System.getProperty("os.version") ));
404     }
405
406     private boolean isMac() {
407         String JavaDoc osName = System.getProperty ("os.name");
408         boolean result = osName.startsWith ("Darwin") || "Mac OS X".equals(osName);
409         return result;
410     }
411
412     /** If it is solaris or linux, we can use GTK where supported by getting
413      * the platform specific look and feel. Also check to make sure under no
414      * circumstances do we use Motif look and feel.
415      *
416      * @return If metal L&F should be used
417      */

418     private boolean shouldUseMetal() {
419         String JavaDoc osName = System.getProperty ("os.name");
420         boolean result = !"Solaris".equals (osName) &&
421             !osName.startsWith ("SunOS") &&
422             !osName.endsWith ("Linux") ||
423             UIManager.getSystemLookAndFeelClassName().indexOf("Motif") > -1;
424         return result;
425     }
426
427     private LFListener listener = null;
428     private class LFListener implements PropertyChangeListener JavaDoc {
429         public void propertyChange (PropertyChangeEvent JavaDoc pcl) {
430             if ("lookAndFeel".equals(pcl.getPropertyName()) || "win.xpstyle.themeActive".equals(pcl.getPropertyName())) { //NOI18N
431
uninstallPerLFDefaults();
432                 installPerLFDefaults();
433             }
434         }
435     }
436     
437 }
438
Popular Tags