KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > FormLAF


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.modules.form;
21
22 import java.beans.*;
23 import java.util.*;
24 import javax.swing.*;
25 import javax.swing.plaf.metal.*;
26 import org.jdesktop.layout.LayoutStyle;
27 import org.openide.util.*;
28 import org.openide.ErrorManager;
29
30 /**
31  * Support for execution of tasks in another look and feel.
32  *
33  * @author Jan Stola, Tran Duc Trung
34  */

35 public class FormLAF {
36     /** Determines whether the FormLAF has been initialized (e.g. DelegatingDefaults has been installed). */
37     private static boolean initialized = false;
38     /** Determines whether we already are in LAF block. */
39     private static boolean lafBlockEntered;
40     /** DelegatingDefaults installed in UIManager.FormLAF */
41     private static DelegatingDefaults delDefaults;
42     /** User UIDefaults of the IDE. */
43     private static Map netbeansDefaults = new HashMap();
44     /** User UIDefaults of components */
45     private static Map userDefaults = new HashMap();
46     /** Maps LAF class to its theme. */
47     private static Map lafToTheme = new HashMap();
48     /** Determines whether the IDE LAF is subclass of MetalLookAndFeel. */
49     private static boolean ideLafIsMetal;
50     private static boolean preview;
51     private static Class JavaDoc previewLaf;
52
53     private FormLAF() {
54     }
55     
56     static UIDefaults initPreviewLaf(Class JavaDoc lafClass) {
57         try {
58             boolean previewLafIsMetal = MetalLookAndFeel.class.isAssignableFrom(lafClass);
59             if (!ideLafIsMetal && previewLafIsMetal &&
60                 !MetalLookAndFeel.class.equals(lafClass) && (lafToTheme.get(MetalLookAndFeel.class) == null)) {
61                 lafToTheme.put(MetalLookAndFeel.class, MetalLookAndFeel.getCurrentTheme());
62             }
63             LookAndFeel previewLookAndFeel = (LookAndFeel)lafClass.newInstance();
64             if (previewLafIsMetal) {
65                 MetalTheme theme = (MetalTheme)lafToTheme.get(lafClass);
66                 if (theme == null) {
67                     lafToTheme.put(lafClass, MetalLookAndFeel.getCurrentTheme());
68                 } else {
69                     MetalLookAndFeel.setCurrentTheme(theme);
70                 }
71             }
72             previewLookAndFeel.initialize();
73
74             UIDefaults previewDefaults = previewLookAndFeel.getDefaults();
75
76             if (previewLafIsMetal && ideLafIsMetal) {
77                 LookAndFeel ideLaf = UIManager.getLookAndFeel();
78                 MetalTheme theme = (MetalTheme)lafToTheme.get(ideLaf.getClass());
79                 MetalLookAndFeel.setCurrentTheme(theme);
80             }
81
82             ClassLoader JavaDoc classLoader = lafClass.getClassLoader();
83             if (classLoader != null) previewDefaults.put("ClassLoader", classLoader); // NOI18N
84

85             // Force switch of the LayoutStyle
86
if (previewDefaults.get("LayoutStyle.instance") == null) { // NOI18N
87
previewDefaults.put("LayoutStyle.instance", // NOI18N
88
createLayoutStyle(previewLookAndFeel.getID()));
89             }
90
91             previewDefaults.putAll(delDefaults.getCustomizedUIDefaults());
92
93             return previewDefaults;
94         } catch (Exception JavaDoc ex) {
95             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
96         } catch (LinkageError JavaDoc ex) {
97             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
98         }
99         return null;
100     }
101
102     private static void initialize() throws Exception JavaDoc {
103         initialized = true;
104         UIManager.getDefaults(); // Force initialization
105

106         LookAndFeel laf = UIManager.getLookAndFeel();
107         ideLafIsMetal = laf instanceof MetalLookAndFeel;
108         if (ideLafIsMetal) {
109             lafToTheme.put(laf.getClass(), MetalLookAndFeel.getCurrentTheme());
110         }
111         LookAndFeel original = laf;
112         try {
113             original = laf.getClass().newInstance();
114         } catch (Exception JavaDoc ex) {
115             ex.printStackTrace();
116         }
117
118         java.lang.reflect.Method JavaDoc method = UIManager.class.getDeclaredMethod("getLAFState", new Class JavaDoc[0]); // NOI18N
119
method.setAccessible(true);
120         Object JavaDoc lafState = method.invoke(null, new Object JavaDoc[0]);
121         method = lafState.getClass().getDeclaredMethod("setLookAndFeelDefaults", new Class JavaDoc[] {UIDefaults.class}); // NOI18N
122
method.setAccessible(true);
123
124         UIDefaults ide = UIManager.getLookAndFeelDefaults();
125         assert !(ide instanceof DelegatingDefaults);
126
127         delDefaults = new DelegatingDefaults(null, original.getDefaults(), ide);
128         method.invoke(lafState, new Object JavaDoc[] {delDefaults});
129     }
130
131     static Object JavaDoc executeWithLookAndFeel(final Mutex.ExceptionAction act)
132         throws Exception JavaDoc
133     {
134         try {
135             return Mutex.EVENT.readAccess(new Mutex.ExceptionAction() {
136                 public Object JavaDoc run() throws Exception JavaDoc {
137                     // FIXME(-ttran) needs to hold a lock on UIDefaults to
138
// prevent other threads from creating Swing components
139
// in the mean time
140
synchronized (UIManager.getDefaults()) {
141                         boolean restoreAfter = true;
142                         try {
143                             if (lafBlockEntered)
144                                 restoreAfter = false;
145                             else {
146                                 lafBlockEntered = true;
147                                 useDesignerLookAndFeel();
148                                 restoreAfter = true;
149                             }
150                             return act.run();
151                         }
152                         finally {
153                             if (restoreAfter) {
154                                 useIDELookAndFeel();
155                                 lafBlockEntered = false;
156                             }
157                         }
158                     }
159                 }
160             });
161         }
162         catch (MutexException ex) {
163             throw ex.getException();
164         }
165     }
166
167     static void executeWithLookAndFeel(final Runnable JavaDoc run) {
168         Mutex.EVENT.readAccess(new Mutex.Action() {
169             public Object JavaDoc run() {
170                 // FIXME(-ttran) needs to hold a lock on UIDefaults to
171
// prevent other threads from creating Swing components
172
// in the mean time
173
synchronized (UIManager.getDefaults()) {
174                     boolean restoreAfter = true;
175                     try {
176                         if (lafBlockEntered)
177                             restoreAfter = false;
178                         else {
179                             lafBlockEntered = true;
180                             useDesignerLookAndFeel();
181                             restoreAfter = true;
182                         }
183                         run.run();
184                     }
185                     finally {
186                         if (restoreAfter) {
187                             useIDELookAndFeel();
188                             lafBlockEntered = false;
189                         }
190                     }
191                 }
192                 return null;
193             }
194         });
195     }
196
197     private static void useDesignerLookAndFeel() {
198         if (!initialized) {
199             try {
200                 initialize();
201             } catch (Exception JavaDoc ex) {
202                 ex.printStackTrace();
203             }
204         }
205         UIDefaults defaults = UIManager.getDefaults();
206         netbeansDefaults.clear();
207         netbeansDefaults.putAll(defaults);
208         netbeansDefaults.keySet().removeAll(userDefaults.keySet());
209         defaults.keySet().removeAll(netbeansDefaults.keySet());
210
211         if (!preview) {
212             setUseDesignerDefaults(true);
213         } else if (MetalLookAndFeel.class.isAssignableFrom(previewLaf)) {
214             MetalLookAndFeel.setCurrentTheme((MetalTheme)lafToTheme.get(previewLaf));
215         }
216     }
217
218     private static void useIDELookAndFeel() {
219         userDefaults.clear();
220         userDefaults.putAll(UIManager.getDefaults());
221         UIManager.getDefaults().putAll(netbeansDefaults);
222
223         if (!preview) {
224             setUseDesignerDefaults(false);
225         } else if (ideLafIsMetal) {
226             MetalLookAndFeel.setCurrentTheme((MetalTheme)lafToTheme.get(UIManager.getLookAndFeel().getClass()));
227         }
228     }
229
230     /**
231      * HACK - creates a LayoutStyle that corresponds to the given LAF.
232      * LayoutStyle is created according to UIManager.getLookAndFeel()
233      * which is not affected by our LAF switch => we have to create
234      * the new LayoutStyle manually.
235      */

236     private static LayoutStyle createLayoutStyle(String JavaDoc lafID) {
237         boolean useCoreLayoutStyle = false;
238         try {
239             Class.forName("javax.swing.LayoutStyle"); // NOI18N
240
useCoreLayoutStyle = true;
241         } catch (ClassNotFoundException JavaDoc cnfex) {}
242         String JavaDoc layoutStyleClass;
243         if (useCoreLayoutStyle) {
244             layoutStyleClass = "Swing"; // NOI18N
245
} else if ("Metal" == lafID) { // NOI18N
246
layoutStyleClass = "Metal"; // NOI18N
247
}
248         else if ("Windows" == lafID) { // NOI18N
249
layoutStyleClass = "Windows"; // NOI18N
250
}
251         else if ("GTK" == lafID) { // NOI18N
252
layoutStyleClass = "Gnome"; // NOI18N
253
}
254         else if ("Aqua" == lafID) { // NOI18N
255
layoutStyleClass = "Aqua"; // NOI18N
256
} else {
257             layoutStyleClass = ""; // NOI18N
258
}
259         layoutStyleClass = "org.jdesktop.layout." + layoutStyleClass + "LayoutStyle"; // NOI18N
260
LayoutStyle layoutStyle = null;
261         try {
262             Class JavaDoc clazz = Class.forName(layoutStyleClass);
263             java.lang.reflect.Constructor JavaDoc constr = clazz.getDeclaredConstructor(new Class JavaDoc[0]);
264             constr.setAccessible(true);
265             layoutStyle = (LayoutStyle)constr.newInstance(null);
266         } catch (Exception JavaDoc ex) {
267             ex.printStackTrace();
268         }
269         return layoutStyle;
270     }
271
272     static LayoutStyle getDesignerLayoutStyle() {
273         return LayoutStyle.getSharedInstance();
274     }
275
276     static void setUseDesignerDefaults(boolean designerDefaults) {
277         delDefaults.setDelegating(designerDefaults);
278     }
279
280     static void setUsePreviewDefaults(boolean previewing, Class JavaDoc previewLAF, UIDefaults uiDefaults) {
281         preview = previewing;
282         previewLaf = previewLAF;
283         if (previewing) {
284             delDefaults.setPreviewDefaults(uiDefaults);
285         }
286         delDefaults.setPreviewing(previewing);
287     }
288
289     public static boolean getUsePreviewDefaults() {
290         return preview && !delDefaults.isDelegating();
291     }
292
293     static void setCustomizingUIClasses(boolean customizing) {
294         delDefaults.setCustomizingUIClasses(customizing);
295     }
296
297     /**
298      * Implementation of UIDefaults that delegates requests between two
299      * UIDefaults based on some rule.
300      */

301     static class DelegatingDefaults extends UIDefaults {
302         /** UIDefaults used for preview. */
303         private UIDefaults preview;
304         /** The designer UIDefaults. */
305         private UIDefaults original;
306         /** IDE UIDefaults. */
307         private UIDefaults ide;
308         /** If true, then the designer map is used. */
309         private boolean delegating;
310         /** If true, then the preview map is used. */
311         private boolean previewing;
312         /** If true, then new UI components may install their defaults. */
313         private boolean customizingUI;
314         /** Map of defaults of new UI components. */
315         private Map customizedUIDefaults = new HashMap();
316         
317         DelegatingDefaults(UIDefaults preview, UIDefaults original, UIDefaults ide) {
318             this.preview = preview;
319             this.original = original;
320             this.ide = ide;
321         }
322
323         public void setPreviewDefaults(UIDefaults preview) {
324             this.preview = preview;
325         }
326
327         public void setDelegating(boolean delegating){
328             this.delegating = delegating;
329         }
330
331         public boolean isDelegating() {
332             return delegating;
333         }
334
335         public void setPreviewing(boolean previewing){
336             this.previewing = previewing;
337         }
338
339         public boolean isPreviewing() {
340             return previewing;
341         }
342
343         public void setCustomizingUIClasses(boolean customizing) {
344             customizingUI = customizing;
345         }
346
347         public Map getCustomizedUIDefaults() {
348             return customizedUIDefaults;
349         }
350
351         // Delegated methods
352

353         private UIDefaults getCurrentDefaults() {
354             return delegating ? original : (previewing ? preview : ide);
355         }
356
357         public Object JavaDoc get(Object JavaDoc key) {
358             return delegating ? original.get(key) : (previewing ? preview.get(key) : ide.get(key));
359         }
360
361         public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
362             if (delegating) {
363                 if (customizingUI) {
364                     customizedUIDefaults.put(key, value);
365                 }
366                 return original.put(key, value);
367             } else {
368                 return (previewing ? preview.put(key, value) : ide.put(key, value));
369             }
370         }
371
372         public void putDefaults(Object JavaDoc[] keyValueList) {
373             getCurrentDefaults().putDefaults(keyValueList);
374         }
375
376         public Object JavaDoc get(Object JavaDoc key, Locale l) {
377             return getCurrentDefaults().get(key, l);
378         }
379
380         public synchronized void addResourceBundle(String JavaDoc bundleName) {
381             getCurrentDefaults().addResourceBundle(bundleName);
382         }
383
384         public synchronized void removeResourceBundle(String JavaDoc bundleName) {
385             getCurrentDefaults().removeResourceBundle(bundleName);
386         }
387
388         public void setDefaultLocale(Locale l) {
389             getCurrentDefaults().setDefaultLocale(l);
390         }
391
392         public Locale getDefaultLocale() {
393             return getCurrentDefaults().getDefaultLocale();
394         }
395
396         public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
397             getCurrentDefaults().addPropertyChangeListener(listener);
398         }
399
400         public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
401             getCurrentDefaults().removePropertyChangeListener(listener);
402         }
403
404         public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
405             return getCurrentDefaults().getPropertyChangeListeners();
406         }
407
408         protected void firePropertyChange(String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue) {
409             System.out.println("Warning: FormLAF.firePropertyChange called, but not implemented."); // NOI18N
410
}
411
412     }
413
414 }
415
Popular Tags