001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form;
043:
044: import java.beans.*;
045: import java.lang.reflect.Field;
046: import java.util.*;
047: import java.util.logging.Level;
048: import java.util.logging.Logger;
049: import javax.swing.*;
050: import javax.swing.plaf.ComponentUI;
051: import javax.swing.plaf.metal.*;
052: import org.jdesktop.layout.LayoutStyle;
053: import org.netbeans.modules.form.project.ClassPathUtils;
054: import org.openide.util.*;
055: import org.openide.ErrorManager;
056: import org.openide.filesystems.FileObject;
057:
058: /**
059: * Support for execution of tasks in another look and feel.
060: *
061: * @author Jan Stola, Tran Duc Trung
062: */
063: public class FormLAF {
064: private static final String SWING_NOXP = "swing.noxp"; // NOI18N
065: /** Determines whether the FormLAF has been initialized (e.g. DelegatingDefaults has been installed). */
066: private static boolean initialized = false;
067: /** Determines whether we already are in LAF block. */
068: private static boolean lafBlockEntered;
069: /** DelegatingDefaults installed in UIManager.FormLAF */
070: private static DelegatingDefaults delDefaults;
071: /** User UIDefaults of the IDE. */
072: private static Map<Object, Object> netbeansDefaults = new HashMap<Object, Object>();
073: /** User UIDefaults of components */
074: private static Map<Object, Object> userDefaults = new HashMap<Object, Object>();
075: /** Maps LAF class to its theme. */
076: private static Map<Class, MetalTheme> lafToTheme = new HashMap<Class, MetalTheme>();
077: /** Determines whether the IDE LAF is subclass of MetalLookAndFeel. */
078: private static boolean ideLafIsMetal;
079: /** Determines whether the current LAF block corresponds to preview. */
080: private static boolean preview;
081: /** LAF class of preview. */
082: private static Class previewLaf;
083:
084: /**
085: * <code>FormLAF</code> has static methods only => no need for public constructor.
086: */
087: private FormLAF() {
088: }
089:
090: public static PreviewInfo initPreviewLaf(Class lafClass,
091: ClassLoader formClassLoader) {
092: try {
093: boolean previewLafIsMetal = MetalLookAndFeel.class
094: .isAssignableFrom(lafClass);
095: if (!ideLafIsMetal && previewLafIsMetal
096: && !MetalLookAndFeel.class.equals(lafClass)
097: && (lafToTheme.get(MetalLookAndFeel.class) == null)) {
098: lafToTheme.put(MetalLookAndFeel.class, MetalLookAndFeel
099: .getCurrentTheme());
100: }
101: LookAndFeel previewLookAndFeel = (LookAndFeel) lafClass
102: .newInstance();
103: if (previewLafIsMetal) {
104: MetalTheme theme = lafToTheme.get(lafClass);
105: if (theme == null) {
106: lafToTheme.put(lafClass, MetalLookAndFeel
107: .getCurrentTheme());
108: } else {
109: MetalLookAndFeel.setCurrentTheme(theme);
110: }
111: }
112:
113: String noxp = null;
114: boolean classic = isClassicWinLAF(lafClass.getName());
115: if (classic) {
116: noxp = System.getProperty(SWING_NOXP);
117: System.setProperty(SWING_NOXP, "y"); // NOI18N
118: }
119: UIDefaults previewDefaults = null;
120: try {
121: previewLookAndFeel.initialize();
122: previewDefaults = previewLookAndFeel.getDefaults();
123: } finally {
124: if (classic) {
125: if (noxp == null) {
126: System.getProperties().remove(SWING_NOXP);
127: } else {
128: System.setProperty(SWING_NOXP, noxp);
129: }
130: }
131: }
132:
133: PreviewInfo info = new PreviewInfo(previewLookAndFeel,
134: previewDefaults);
135: if (isNimbusLAF(lafClass)
136: && !isNimbusLAF(UIManager.getLookAndFeel()
137: .getClass())) {
138: try {
139: // The update of derived colors must be performed within preview block
140: FormLAF
141: .setUsePreviewDefaults(formClassLoader,
142: info);
143: for (PropertyChangeListener listener : UIManager
144: .getPropertyChangeListeners()) {
145: if (listener.getClass().getName().endsWith(
146: "UIDefaultColorListener")) { // NOI18N
147: // Forces update of derived colors, see NimbusDefaults.UIDefaultColorListener
148: listener
149: .propertyChange(new PropertyChangeEvent(
150: UIManager.class,
151: "lookAndFeel", null, null)); // NOI18N
152: // Remove listener added by NimbusLookAndFeel.initialize()
153: UIManager
154: .removePropertyChangeListener(listener);
155: }
156: }
157: } finally {
158: FormLAF.setUsePreviewDefaults(null, null);
159: }
160: }
161:
162: if (previewLafIsMetal && ideLafIsMetal) {
163: LookAndFeel ideLaf = UIManager.getLookAndFeel();
164: MetalTheme theme = lafToTheme.get(ideLaf.getClass());
165: MetalLookAndFeel.setCurrentTheme(theme);
166: }
167:
168: ClassLoader classLoader = lafClass.getClassLoader();
169: if (classLoader != null)
170: previewDefaults.put("ClassLoader", classLoader); // NOI18N
171:
172: // Force switch of the LayoutStyle
173: if (previewDefaults.get("LayoutStyle.instance") == null) { // NOI18N
174: previewDefaults.put("LayoutStyle.instance", // NOI18N
175: createLayoutStyle(previewLookAndFeel.getID()));
176: }
177:
178: return info;
179: } catch (Exception ex) {
180: ErrorManager.getDefault().notify(
181: ErrorManager.INFORMATIONAL, ex);
182: } catch (LinkageError ex) {
183: ErrorManager.getDefault().notify(
184: ErrorManager.INFORMATIONAL, ex);
185: }
186: return null;
187: }
188:
189: private static boolean isClassicWinLAF(String className) {
190: return "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"
191: .equals(className); // NOI18N
192: }
193:
194: private static boolean isNimbusLAF(Class lafClass) {
195: return lafClass.getName().endsWith("NimbusLookAndFeel"); // NOI18N
196: }
197:
198: private static void invalidateXPStyle() {
199: try {
200: Class xpStyle = Class
201: .forName("com.sun.java.swing.plaf.windows.XPStyle"); // NOI18N
202: java.lang.reflect.Method method = xpStyle
203: .getDeclaredMethod("invalidateStyle",
204: (Class[]) null); // NOI18N
205: method.setAccessible(true);
206: method.invoke(null);
207: } catch (Exception ex) {
208: Logger.getLogger(FormLAF.class.getName()).log(Level.INFO,
209: ex.getMessage(), ex);
210: }
211: }
212:
213: private static void initialize() throws Exception {
214: initialized = true;
215: UIManager.getDefaults(); // Force initialization
216:
217: LookAndFeel laf = UIManager.getLookAndFeel();
218: ideLafIsMetal = laf instanceof MetalLookAndFeel;
219: if (ideLafIsMetal) {
220: lafToTheme.put(laf.getClass(), MetalLookAndFeel
221: .getCurrentTheme());
222: }
223: LookAndFeel original = laf;
224: try {
225: original = laf.getClass().newInstance();
226: } catch (Exception ex) {
227: Logger.getLogger(FormLAF.class.getName()).log(Level.INFO,
228: ex.getMessage(), ex);
229: }
230:
231: java.lang.reflect.Method method = UIManager.class
232: .getDeclaredMethod("getLAFState", new Class[0]); // NOI18N
233: method.setAccessible(true);
234: Object lafState = method.invoke(null, new Object[0]);
235: method = lafState.getClass().getDeclaredMethod(
236: "setLookAndFeelDefaults",
237: new Class[] { UIDefaults.class }); // NOI18N
238: method.setAccessible(true);
239:
240: UIDefaults ide = UIManager.getLookAndFeelDefaults();
241: assert !(ide instanceof DelegatingDefaults);
242:
243: delDefaults = new DelegatingDefaults(null, original
244: .getDefaults(), ide);
245: method.invoke(lafState, new Object[] { delDefaults });
246:
247: // See UIDefaults.getUIClass() method - it stores className-class pairs
248: // in its map. When project classpath is updated new versions
249: // of classes are loaded which results in ClassCastException if
250: // such new classes are casted to the ones obtained from the map.
251: // Hence, we remove such mappings to avoid problems.
252: UIManager.getDefaults().addPropertyChangeListener(
253: new PropertyChangeListener() {
254: public void propertyChange(PropertyChangeEvent evt) {
255: if (delDefaults.isDelegating()
256: || delDefaults.isPreviewing()) {
257: Object newValue = evt.getNewValue();
258: if (newValue instanceof Class) {
259: Class<?> clazz = (Class<?>) newValue;
260: if (ComponentUI.class
261: .isAssignableFrom(clazz)) {
262: UIManager.getDefaults()
263: .put(evt.getPropertyName(),
264: null);
265: }
266: }
267: }
268: }
269: });
270: }
271:
272: static Object executeWithLookAndFeel(final FormModel formModel,
273: final Mutex.ExceptionAction act) throws Exception {
274: try {
275: return Mutex.EVENT
276: .readAccess(new Mutex.ExceptionAction<Object>() {
277: public Object run() throws Exception {
278: // FIXME(-ttran) needs to hold a lock on UIDefaults to
279: // prevent other threads from creating Swing components
280: // in the mean time
281: synchronized (UIManager.getDefaults()) {
282: boolean restoreAfter = true;
283: try {
284: if (lafBlockEntered)
285: restoreAfter = false;
286: else {
287: lafBlockEntered = true;
288: useDesignerLookAndFeel(formModel);
289: restoreAfter = true;
290: }
291: return act.run();
292: } finally {
293: if (restoreAfter) {
294: useIDELookAndFeel();
295: lafBlockEntered = false;
296: }
297: }
298: }
299: }
300: });
301: } catch (MutexException ex) {
302: throw ex.getException();
303: }
304: }
305:
306: static void executeWithLookAndFeel(final FormModel formModel,
307: final Runnable run) {
308: Mutex.EVENT.readAccess(new Mutex.Action<Object>() {
309: public Object run() {
310: // FIXME(-ttran) needs to hold a lock on UIDefaults to
311: // prevent other threads from creating Swing components
312: // in the mean time
313: synchronized (UIManager.getDefaults()) {
314: boolean restoreAfter = true;
315: try {
316: if (lafBlockEntered)
317: restoreAfter = false;
318: else {
319: lafBlockEntered = true;
320: useDesignerLookAndFeel(formModel);
321: restoreAfter = true;
322: }
323: run.run();
324: } finally {
325: if (restoreAfter) {
326: useIDELookAndFeel();
327: lafBlockEntered = false;
328: }
329: }
330: }
331: return null;
332: }
333: });
334: }
335:
336: private static void useDesignerLookAndFeel(FormModel formModel) {
337: if (!initialized) {
338: try {
339: initialize();
340: } catch (Exception ex) {
341: Logger.getLogger(FormLAF.class.getName()).log(
342: Level.INFO, ex.getMessage(), ex);
343: }
344: }
345: UIDefaults defaults = UIManager.getDefaults();
346: netbeansDefaults.clear();
347: netbeansDefaults.putAll(defaults);
348: netbeansDefaults.keySet().removeAll(userDefaults.keySet());
349: defaults.keySet().removeAll(netbeansDefaults.keySet());
350:
351: if (!preview) {
352: setUseDesignerDefaults(formModel);
353: } else if (MetalLookAndFeel.class.isAssignableFrom(previewLaf)) {
354: MetalLookAndFeel
355: .setCurrentTheme(lafToTheme.get(previewLaf));
356: }
357: }
358:
359: private static void useIDELookAndFeel() {
360: userDefaults.clear();
361: userDefaults.putAll(UIManager.getDefaults());
362:
363: if (!preview) {
364: setUseDesignerDefaults(null);
365: } else if (ideLafIsMetal) {
366: MetalLookAndFeel.setCurrentTheme(lafToTheme.get(UIManager
367: .getLookAndFeel().getClass()));
368: }
369:
370: UIManager.getDefaults().putAll(netbeansDefaults);
371: }
372:
373: /**
374: * HACK - creates a LayoutStyle that corresponds to the given LAF.
375: * LayoutStyle is created according to UIManager.getLookAndFeel()
376: * which is not affected by our LAF switch => we have to create
377: * the new LayoutStyle manually.
378: */
379: private static LayoutStyle createLayoutStyle(String lafID) {
380: boolean useCoreLayoutStyle = false;
381: try {
382: Class.forName("javax.swing.LayoutStyle"); // NOI18N
383: useCoreLayoutStyle = true;
384: } catch (ClassNotFoundException cnfex) {
385: }
386: String layoutStyleClass;
387: if (useCoreLayoutStyle) {
388: layoutStyleClass = "Swing"; // NOI18N
389: } else if ("Metal" == lafID) { // NOI18N
390: layoutStyleClass = "Metal"; // NOI18N
391: } else if ("Windows" == lafID) { // NOI18N
392: layoutStyleClass = "Windows"; // NOI18N
393: } else if ("GTK" == lafID) { // NOI18N
394: layoutStyleClass = "Gnome"; // NOI18N
395: } else if ("Aqua" == lafID) { // NOI18N
396: layoutStyleClass = "Aqua"; // NOI18N
397: } else {
398: layoutStyleClass = ""; // NOI18N
399: }
400: layoutStyleClass = "org.jdesktop.layout." + layoutStyleClass
401: + "LayoutStyle"; // NOI18N
402: LayoutStyle layoutStyle = null;
403: try {
404: Class clazz = Class.forName(layoutStyleClass);
405: java.lang.reflect.Constructor constr = clazz
406: .getDeclaredConstructor(new Class[0]);
407: constr.setAccessible(true);
408: layoutStyle = (LayoutStyle) constr
409: .newInstance((Object[]) null);
410: } catch (Exception ex) {
411: Logger.getLogger(FormLAF.class.getName()).log(Level.INFO,
412: ex.getMessage(), ex);
413: }
414: return layoutStyle;
415: }
416:
417: static LayoutStyle getDesignerLayoutStyle() {
418: return LayoutStyle.getSharedInstance();
419: }
420:
421: /**
422: * Maps class loader (project class loader of the form) to set of defaults
423: * added when this class loader was in use.
424: */
425: private static Map<ClassLoader, Map<Object, Object>> classLoaderToDefaults = new WeakHashMap<ClassLoader, Map<Object, Object>>();
426: /** Last content of UIDefaults - to be able to find newly added defaults. */
427: private static UIDefaults lastDefaults = new UIDefaults();
428: /** Defaults that correspond to project class loader in use. */
429: private static Map<Object, Object> classLoaderDefaults;
430:
431: static void setUseDesignerDefaults(FormModel formModel) {
432: ClassLoader classLoader = null;
433: UIDefaults defaults = UIManager.getDefaults();
434: if (formModel == null) {
435: // Determine new user defaults add add them to classLoaderDefaults
436: UIDefaults newDefaults = new UIDefaults();
437: newDefaults.putAll(UIManager.getDefaults());
438: newDefaults.keySet().removeAll(lastDefaults.keySet());
439: classLoaderDefaults.putAll(newDefaults);
440: defaults.putAll(lastDefaults);
441: } else {
442: FileObject formFile = FormEditor.getFormDataObject(
443: formModel).getFormFile();
444: classLoader = ClassPathUtils
445: .getProjectClassLoader(formFile);
446: classLoaderDefaults = classLoaderToDefaults
447: .get(classLoader);
448: if (classLoaderDefaults == null) {
449: classLoaderDefaults = new HashMap<Object, Object>();
450: classLoaderToDefaults.put(classLoader,
451: classLoaderDefaults);
452: }
453: lastDefaults.clear();
454: lastDefaults.putAll(defaults);
455: defaults.putAll(classLoaderDefaults);
456: }
457: delDefaults.setDelegating(classLoader);
458: }
459:
460: static String oldNoXP;
461: static Object origLAF;
462:
463: public static void setUsePreviewDefaults(ClassLoader classLoader,
464: PreviewInfo info) {
465: boolean classic = (info == null) ? ((previewLaf == null) ? false
466: : isClassicWinLAF(previewLaf.getName()))
467: : isClassicWinLAF(info.lafClass.getName());
468: preview = (classLoader != null);
469: previewLaf = (info == null) ? null : info.lafClass;
470: if (preview) {
471: if (classic) {
472: oldNoXP = System.getProperty(SWING_NOXP);
473: System.setProperty(SWING_NOXP, "y"); // NOI18N
474: invalidateXPStyle();
475: }
476: classLoaderDefaults = classLoaderToDefaults
477: .get(classLoader);
478: if (classLoaderDefaults == null) {
479: classLoaderDefaults = new HashMap<Object, Object>();
480: classLoaderToDefaults.put(classLoader,
481: classLoaderDefaults);
482: }
483: Map<Object, Object> added = new HashMap<Object, Object>(
484: classLoaderDefaults);
485: added.keySet().removeAll(info.defaults.keySet());
486: info.defaults.putAll(added);
487: delDefaults.setPreviewDefaults(info.defaults);
488: // AbstractRegionPainter in Nimus L&F uses UIManager.getLookAndFeel()
489: // We cannot use setLookAndFeel() because it would cause update of everything
490: if (isNimbusLAF(previewLaf)) {
491: origLAF = changeLAFStatesLAF(info.laf);
492: }
493: } else {
494: if (classic) {
495: if (oldNoXP == null) {
496: System.getProperties().remove(SWING_NOXP);
497: } else {
498: System.setProperty(SWING_NOXP, oldNoXP);
499: }
500: invalidateXPStyle();
501: }
502: oldNoXP = null;
503: // Restore original (IDEs) UIManager.lookAndFeel
504: if (origLAF != null) {
505: changeLAFStatesLAF(origLAF);
506: origLAF = null;
507: }
508: }
509: delDefaults.setPreviewing(classLoader);
510: }
511:
512: /**
513: * Changes UIManager.lookAndFeel.
514: *
515: * @param laf look and feel to set in UIManager.
516: * @return previous look and feel stored in UIManager.lookAndFeel.
517: */
518: private static Object changeLAFStatesLAF(Object laf) {
519: Object value = null;
520: try {
521: java.lang.reflect.Method method = UIManager.class
522: .getDeclaredMethod("getLAFState", new Class[0]); // NOI18N
523: method.setAccessible(true);
524: Object lafState = method.invoke(null, new Object[0]);
525: Field field = lafState.getClass().getDeclaredField(
526: "lookAndFeel"); // NOI18N
527: field.setAccessible(true);
528: value = field.get(lafState);
529: field.set(lafState, laf);
530: } catch (Exception ex) {
531: Logger.getLogger(FormLAF.class.getName()).log(Level.INFO,
532: ex.getMessage(), ex);
533: }
534: return value;
535: }
536:
537: public static boolean getUsePreviewDefaults() {
538: return preview && !delDefaults.isDelegating();
539: }
540:
541: public static boolean inLAFBlock() {
542: return preview || delDefaults.isDelegating();
543: }
544:
545: /**
546: * Class that encapsulates information needed during preview.
547: */
548: public static class PreviewInfo {
549: PreviewInfo(LookAndFeel laf, UIDefaults defaults) {
550: this .laf = laf;
551: this .lafClass = laf.getClass();
552: this .defaults = defaults;
553: }
554:
555: Class lafClass;
556: UIDefaults defaults;
557: LookAndFeel laf;
558: }
559:
560: /**
561: * Implementation of UIDefaults that delegates requests between two
562: * UIDefaults based on some rule.
563: */
564: static class DelegatingDefaults extends UIDefaults {
565: /** UIDefaults used for preview. */
566: private UIDefaults preview;
567: /** The designer UIDefaults. */
568: private UIDefaults original;
569: /** IDE UIDefaults. */
570: private UIDefaults ide;
571: /** If true, then the designer map is used. */
572: private boolean delegating;
573: /** If true, then the preview map is used. */
574: private boolean previewing;
575:
576: /** If true, then new UI components may install their defaults. */
577:
578: DelegatingDefaults(UIDefaults preview, UIDefaults original,
579: UIDefaults ide) {
580: this .preview = preview;
581: this .original = original;
582: this .ide = ide;
583: }
584:
585: public void setPreviewDefaults(UIDefaults preview) {
586: this .preview = preview;
587: }
588:
589: /**
590: * Maps class loader (project class loader of the form) to set of LAF defaults
591: * added when this class loader was in use.
592: */
593: private Map<ClassLoader, UIDefaults> classLoaderToLAFDefaults = new WeakHashMap<ClassLoader, UIDefaults>();
594: /** LAF defaults that correspond to project class loader in use. */
595: private UIDefaults classLoaderLAFDefaults;
596:
597: public void setDelegating(ClassLoader classLoader) {
598: classLoaderLAFDefaults = classLoaderToLAFDefaults
599: .get(classLoader);
600: if (classLoaderLAFDefaults == null) {
601: classLoaderLAFDefaults = new UIDefaults();
602: classLoaderToLAFDefaults.put(classLoader,
603: classLoaderLAFDefaults);
604: }
605: this .delegating = (classLoader != null);
606: }
607:
608: public boolean isDelegating() {
609: return delegating;
610: }
611:
612: // Preview may not work if project classpath has been changed
613: // while the form was opened: new UIDefaults are created
614: // when the classpath is changed - this allows correct creation
615: // of new components; unfortunately both new and old components
616: // are _cloned_ when preview is done
617: // There are also other use-cases that may fail e.g.
618: // attempt to connect (via some property) old and new
619: // component. But all these use-cases should work after form reload.
620: public void setPreviewing(ClassLoader classLoader) {
621: this .previewing = (classLoader != null);
622: if (previewing) {
623: classLoaderLAFDefaults = classLoaderToLAFDefaults
624: .get(classLoader);
625: if (classLoaderLAFDefaults == null) {
626: classLoaderLAFDefaults = new UIDefaults();
627: classLoaderToLAFDefaults.put(classLoader,
628: classLoaderLAFDefaults);
629: }
630: }
631: }
632:
633: public boolean isPreviewing() {
634: return previewing;
635: }
636:
637: // Delegated methods
638:
639: private UIDefaults getCurrentDefaults() {
640: return delegating ? original : (previewing ? preview : ide);
641: }
642:
643: @Override
644: public Object get(Object key) {
645: Object value;
646: if (delegating) {
647: value = classLoaderLAFDefaults.get(key);
648: if (value == null) {
649: value = original.get(key);
650: }
651: } else if (previewing) {
652: value = classLoaderLAFDefaults.get(key);
653: if (value == null) {
654: value = preview.get(key);
655: }
656: } else {
657: value = ide.get(key);
658: }
659: return value;
660: }
661:
662: @Override
663: public Set<Object> keySet() {
664: Set<Object> set;
665: if (delegating) {
666: set = new HashSet<Object>(classLoaderLAFDefaults
667: .keySet());
668: set.addAll(original.keySet());
669: } else if (previewing) {
670: set = new HashSet<Object>(classLoaderLAFDefaults
671: .keySet());
672: set.addAll(preview.keySet());
673: } else {
674: set = ide.keySet();
675: }
676: return set;
677: }
678:
679: @Override
680: public Object put(Object key, Object value) {
681: Object retVal;
682: if (delegating || previewing) {
683: retVal = classLoaderLAFDefaults.put(key, value);
684: } else {
685: retVal = ide.put(key, value);
686: }
687: return retVal;
688: }
689:
690: @Override
691: public void putDefaults(Object[] keyValueList) {
692: getCurrentDefaults().putDefaults(keyValueList);
693: }
694:
695: @Override
696: public Object get(Object key, Locale l) {
697: return getCurrentDefaults().get(key, l);
698: }
699:
700: @Override
701: public synchronized void addResourceBundle(String bundleName) {
702: getCurrentDefaults().addResourceBundle(bundleName);
703: }
704:
705: @Override
706: public synchronized void removeResourceBundle(String bundleName) {
707: getCurrentDefaults().removeResourceBundle(bundleName);
708: }
709:
710: @Override
711: public void setDefaultLocale(Locale l) {
712: getCurrentDefaults().setDefaultLocale(l);
713: }
714:
715: @Override
716: public Locale getDefaultLocale() {
717: return getCurrentDefaults().getDefaultLocale();
718: }
719:
720: @Override
721: public synchronized void addPropertyChangeListener(
722: PropertyChangeListener listener) {
723: getCurrentDefaults().addPropertyChangeListener(listener);
724: }
725:
726: @Override
727: public synchronized void removePropertyChangeListener(
728: PropertyChangeListener listener) {
729: getCurrentDefaults().removePropertyChangeListener(listener);
730: }
731:
732: @Override
733: public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
734: return getCurrentDefaults().getPropertyChangeListeners();
735: }
736:
737: @Override
738: protected void firePropertyChange(String propertyName,
739: Object oldValue, Object newValue) {
740: Logger
741: .getLogger(getClass().getName())
742: .log(Level.INFO,
743: "FormLAF.firePropertyChange called, but not implemented."); // NOI18N
744: }
745:
746: @Override
747: public synchronized Enumeration<Object> keys() {
748: return getCurrentDefaults().keys();
749: }
750:
751: }
752:
753: }
|