001 /* UIManager.java --
002 Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing;
040
041 import gnu.java.lang.CPStringBuilder;
042
043 import java.awt.Color;
044 import java.awt.Dimension;
045 import java.awt.Font;
046 import java.awt.Insets;
047 import java.beans.PropertyChangeListener;
048 import java.beans.PropertyChangeSupport;
049 import java.io.Serializable;
050 import java.util.Enumeration;
051 import java.util.Locale;
052
053 import javax.swing.border.Border;
054 import javax.swing.plaf.ComponentUI;
055 import javax.swing.plaf.metal.MetalLookAndFeel;
056
057 /**
058 * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel}
059 * instances.
060 */
061 public class UIManager implements Serializable
062 {
063 /**
064 * Represents the basic information about a {@link LookAndFeel} (LAF), so
065 * that a list of installed LAFs can be presented without actually loading
066 * the LAF class(es).
067 */
068 public static class LookAndFeelInfo
069 {
070 String name, clazz;
071
072 /**
073 * Creates a new instance.
074 *
075 * @param name the look and feel name.
076 * @param clazz the look and feel class name.
077 */
078 public LookAndFeelInfo(String name,
079 String clazz)
080 {
081 this.name = name;
082 this.clazz = clazz;
083 }
084
085 /**
086 * Returns the name of the look and feel.
087 *
088 * @return The name of the look and feel.
089 */
090 public String getName()
091 {
092 return name;
093 }
094
095 /**
096 * Returns the fully qualified class name for the {@link LookAndFeel}.
097 *
098 * @return The fully qualified class name for the {@link LookAndFeel}.
099 */
100 public String getClassName()
101 {
102 return clazz;
103 }
104
105 /**
106 * Returns a String representation of the LookAndFeelInfo object.
107 *
108 * @return a String representation of the LookAndFeelInfo object
109 */
110 public String toString()
111 {
112 CPStringBuilder s = new CPStringBuilder();
113 s.append(getClass().getName());
114 s.append('[');
115 s.append(getName());
116 s.append(' ');
117 s.append(getClassName());
118 s.append(']');
119 return s.toString();
120 }
121 }
122
123 /**
124 * A UIDefaults subclass that multiplexes between itself and a 'fallback'
125 * UIDefaults instance. This is used to protect the L&F UIDefaults from beeing
126 * overwritten by applications.
127 */
128 private static class MultiplexUIDefaults
129 extends UIDefaults
130 {
131 private class MultiplexEnumeration
132 implements Enumeration
133 {
134 Enumeration[] enums;
135 int i;
136 MultiplexEnumeration(Enumeration e1, Enumeration e2)
137 {
138 enums = new Enumeration[]{ e1, e2 };
139 i = 0;
140 }
141
142 public boolean hasMoreElements()
143 {
144 return enums[i].hasMoreElements() || i < enums.length - 1;
145 }
146
147 public Object nextElement()
148 {
149 Object val = enums[i].nextElement();
150 if (! enums[i].hasMoreElements() && i < enums.length - 1)
151 i++;
152 return val;
153 }
154
155 }
156
157 UIDefaults fallback;
158
159 /**
160 * Creates a new <code>MultiplexUIDefaults</code> instance with
161 * <code>d</code> as the fallback defaults.
162 *
163 * @param d the fallback defaults (<code>null</code> not permitted).
164 */
165 MultiplexUIDefaults(UIDefaults d)
166 {
167 if (d == null)
168 throw new NullPointerException();
169 fallback = d;
170 }
171
172 public Object get(Object key)
173 {
174 Object val = super.get(key);
175 if (val == null)
176 val = fallback.get(key);
177 return val;
178 }
179
180 public Object get(Object key, Locale l)
181 {
182 Object val = super.get(key, l);
183 if (val == null)
184 val = fallback.get(key, l);
185 return val;
186 }
187
188 public Object remove(Object key)
189 {
190 Object val = super.remove(key);
191 if (val == null)
192 val = fallback.remove(key);
193 return val;
194 }
195
196 public int size()
197 {
198 return super.size() + fallback.size();
199 }
200
201 public Enumeration keys()
202 {
203 return new MultiplexEnumeration(super.keys(), fallback.keys());
204 }
205
206 public Enumeration elements()
207 {
208 return new MultiplexEnumeration(super.elements(), fallback.elements());
209 }
210 }
211
212 private static final long serialVersionUID = -5547433830339189365L;
213
214 /** The installed look and feel(s). */
215 static LookAndFeelInfo [] installed = {
216 new LookAndFeelInfo("Metal", "javax.swing.plaf.metal.MetalLookAndFeel"),
217 new LookAndFeelInfo("GNU", "gnu.javax.swing.plaf.gnu.GNULookAndFeel")
218 };
219
220 /** The installed auxiliary look and feels. */
221 static LookAndFeel[] auxLookAndFeels;
222
223 /** The current look and feel. */
224 static LookAndFeel currentLookAndFeel;
225
226 static MultiplexUIDefaults currentUIDefaults;
227
228 static UIDefaults lookAndFeelDefaults;
229
230 /** Property change listener mechanism. */
231 static PropertyChangeSupport listeners
232 = new PropertyChangeSupport(UIManager.class);
233
234 static
235 {
236 String defaultlaf = System.getProperty("swing.defaultlaf");
237 try
238 {
239 if (defaultlaf != null)
240 {
241 setLookAndFeel(defaultlaf);
242 }
243 else
244 {
245 setLookAndFeel(new MetalLookAndFeel());
246 }
247 }
248 catch (Exception ex)
249 {
250 System.err.println("cannot initialize Look and Feel: " + defaultlaf);
251 System.err.println("error: " + ex.toString());
252 ex.printStackTrace();
253 System.err.println("falling back to Metal Look and Feel");
254 try
255 {
256 setLookAndFeel(new MetalLookAndFeel());
257 }
258 catch (Exception ex2)
259 {
260 throw (Error) new AssertionError("There must be no problem installing"
261 + " the MetalLookAndFeel.")
262 .initCause(ex2);
263 }
264 }
265 }
266
267 /**
268 * Creates a new instance of the <code>UIManager</code>. There is no need
269 * to construct an instance of this class, since all methods are static.
270 */
271 public UIManager()
272 {
273 // Do nothing here.
274 }
275
276 /**
277 * Add a <code>PropertyChangeListener</code> to the listener list.
278 *
279 * @param listener the listener to add
280 */
281 public static void addPropertyChangeListener(PropertyChangeListener listener)
282 {
283 listeners.addPropertyChangeListener(listener);
284 }
285
286 /**
287 * Remove a <code>PropertyChangeListener</code> from the listener list.
288 *
289 * @param listener the listener to remove
290 */
291 public static void removePropertyChangeListener(PropertyChangeListener
292 listener)
293 {
294 listeners.removePropertyChangeListener(listener);
295 }
296
297 /**
298 * Returns an array of all added <code>PropertyChangeListener</code> objects.
299 *
300 * @return an array of listeners
301 *
302 * @since 1.4
303 */
304 public static PropertyChangeListener[] getPropertyChangeListeners()
305 {
306 return listeners.getPropertyChangeListeners();
307 }
308
309 /**
310 * Add a {@link LookAndFeel} to the list of auxiliary look and feels.
311 *
312 * @param laf the auxiliary look and feel (<code>null</code> not permitted).
313 *
314 * @throws NullPointerException if <code>laf</code> is <code>null</code>.
315 *
316 * @see #getAuxiliaryLookAndFeels()
317 */
318 public static void addAuxiliaryLookAndFeel(LookAndFeel laf)
319 {
320 if (laf == null)
321 throw new NullPointerException("Null 'laf' argument.");
322 if (auxLookAndFeels == null)
323 {
324 auxLookAndFeels = new LookAndFeel[1];
325 auxLookAndFeels[0] = laf;
326 return;
327 }
328
329 LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length + 1];
330 System.arraycopy(auxLookAndFeels, 0, temp, 0, auxLookAndFeels.length);
331 auxLookAndFeels = temp;
332 auxLookAndFeels[auxLookAndFeels.length - 1] = laf;
333 }
334
335 /**
336 * Removes a {@link LookAndFeel} (LAF) from the list of auxiliary LAFs.
337 *
338 * @param laf the LAF to remove.
339 *
340 * @return <code>true</code> if the LAF was removed, and <code>false</code>
341 * otherwise.
342 */
343 public static boolean removeAuxiliaryLookAndFeel(LookAndFeel laf)
344 {
345 if (auxLookAndFeels == null)
346 return false;
347 int count = auxLookAndFeels.length;
348 if (count == 1 && auxLookAndFeels[0] == laf)
349 {
350 auxLookAndFeels = null;
351 return true;
352 }
353 for (int i = 0; i < count; i++)
354 {
355 if (auxLookAndFeels[i] == laf)
356 {
357 LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length - 1];
358 if (i == 0)
359 {
360 System.arraycopy(auxLookAndFeels, 1, temp, 0, count - 1);
361 }
362 else if (i == count - 1)
363 {
364 System.arraycopy(auxLookAndFeels, 0, temp, 0, count - 1);
365 }
366 else
367 {
368 System.arraycopy(auxLookAndFeels, 0, temp, 0, i);
369 System.arraycopy(auxLookAndFeels, i + 1, temp, i,
370 count - i - 1);
371 }
372 auxLookAndFeels = temp;
373 return true;
374 }
375 }
376 return false;
377 }
378
379 /**
380 * Returns an array (possibly <code>null</code>) containing the auxiliary
381 * {@link LookAndFeel}s that are in use. These are used by the
382 * {@link javax.swing.plaf.multi.MultiLookAndFeel} class.
383 *
384 * @return The auxiliary look and feels (possibly <code>null</code>).
385 *
386 * @see #addAuxiliaryLookAndFeel(LookAndFeel)
387 */
388 public static LookAndFeel[] getAuxiliaryLookAndFeels()
389 {
390 return auxLookAndFeels;
391 }
392
393 /**
394 * Returns an object from the {@link UIDefaults} table for the current
395 * {@link LookAndFeel}.
396 *
397 * @param key the key.
398 *
399 * @return The object.
400 */
401 public static Object get(Object key)
402 {
403 return getDefaults().get(key);
404 }
405
406 /**
407 * Returns an object from the {@link UIDefaults} table for the current
408 * {@link LookAndFeel}.
409 *
410 * @param key the key.
411 *
412 * @return The object.
413 *
414 * @since 1.4
415 */
416 public static Object get(Object key, Locale locale)
417 {
418 return getDefaults().get(key, locale);
419 }
420
421 /**
422 * Returns a boolean value from the defaults table. If there is no value
423 * for the specified key, or the value is not an instance of {@link Boolean},
424 * this method returns <code>false</code>.
425 *
426 * @param key the key (<code>null</code> not permitted).
427 *
428 * @return The boolean value associated with the specified key.
429 *
430 * @throws NullPointerException if <code>key</code> is <code>null</code>.
431 *
432 * @since 1.4
433 */
434 public static boolean getBoolean(Object key)
435 {
436 Object value = get(key);
437 if (value instanceof Boolean)
438 return ((Boolean) value).booleanValue();
439 return false;
440 }
441
442 /**
443 * Returns a boolean value from the defaults table. If there is no value
444 * for the specified key, or the value is not an instance of {@link Boolean},
445 * this method returns <code>false</code>.
446 *
447 * @param key the key (<code>null</code> not permitted).
448 * @param locale the locale.
449 *
450 * @return The boolean value associated with the specified key.
451 *
452 * @throws NullPointerException if <code>key</code> is <code>null</code>.
453 *
454 * @since 1.4
455 */
456 public static boolean getBoolean(Object key, Locale locale)
457 {
458 Object value = get(key, locale);
459 if (value instanceof Boolean)
460 return ((Boolean) value).booleanValue();
461 return false;
462 }
463
464 /**
465 * Returns a border from the defaults table.
466 *
467 * @param key the key (<code>null</code> not permitted).
468 *
469 * @return The border associated with the given key, or <code>null</code>.
470 *
471 * @throws NullPointerException if <code>key</code> is <code>null</code>.
472 */
473 public static Border getBorder(Object key)
474 {
475 Object value = get(key);
476 if (value instanceof Border)
477 return (Border) value;
478 return null;
479 }
480
481 /**
482 * Returns a border from the defaults table.
483 *
484 * @param key the key (<code>null</code> not permitted).
485 * @param locale the locale.
486 *
487 * @return The border associated with the given key, or <code>null</code>.
488 *
489 * @throws NullPointerException if <code>key</code> is <code>null</code>.
490 *
491 * @since 1.4
492 */
493 public static Border getBorder(Object key, Locale locale)
494 {
495 Object value = get(key, locale);
496 if (value instanceof Border)
497 return (Border) value;
498 return null;
499 }
500
501 /**
502 * Returns a drawing color from the defaults table.
503 *
504 * @param key the key (<code>null</code> not permitted).
505 *
506 * @return The color associated with the given key, or <code>null</code>.
507 *
508 * @throws NullPointerException if <code>key</code> is <code>null</code>.
509 */
510 public static Color getColor(Object key)
511 {
512 Object value = get(key);
513 if (value instanceof Color)
514 return (Color) value;
515 return null;
516 }
517
518 /**
519 * Returns a drawing color from the defaults table.
520 *
521 * @param key the key (<code>null</code> not permitted).
522 * @param locale the locale.
523 *
524 * @return The color associated with the given key, or <code>null</code>.
525 *
526 * @throws NullPointerException if <code>key</code> is <code>null</code>.
527 *
528 * @since 1.4
529 */
530 public static Color getColor(Object key, Locale locale)
531 {
532 Object value = get(key, locale);
533 if (value instanceof Color)
534 return (Color) value;
535 return null;
536 }
537
538 /**
539 * The fully qualified class name of the cross platform (Metal) look and feel.
540 * This string can be passed to Class.forName()
541 *
542 * @return <code>"javax.swing.plaf.metal.MetalLookAndFeel"</code>
543 */
544 public static String getCrossPlatformLookAndFeelClassName()
545 {
546 return "javax.swing.plaf.metal.MetalLookAndFeel";
547 }
548
549 /**
550 * Returns the default values for this look and feel.
551 *
552 * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
553 */
554 public static UIDefaults getDefaults()
555 {
556 if (currentUIDefaults == null)
557 currentUIDefaults = new MultiplexUIDefaults(new UIDefaults());
558 return currentUIDefaults;
559 }
560
561 /**
562 * Returns a dimension from the defaults table.
563 *
564 * @param key the key (<code>null</code> not permitted).
565 *
566 * @return The color associated with the given key, or <code>null</code>.
567 *
568 * @throws NullPointerException if <code>key</code> is <code>null</code>.
569 */
570 public static Dimension getDimension(Object key)
571 {
572 Object value = get(key);
573 if (value instanceof Dimension)
574 return (Dimension) value;
575 return null;
576 }
577
578 /**
579 * Returns a dimension from the defaults table.
580 *
581 * @param key the key (<code>null</code> not permitted).
582 * @param locale the locale.
583 *
584 * @return The color associated with the given key, or <code>null</code>.
585 *
586 * @throws NullPointerException if <code>key</code> is <code>null</code>.
587 * @since 1.4
588 */
589 public static Dimension getDimension(Object key, Locale locale)
590 {
591 Object value = get(key, locale);
592 if (value instanceof Dimension)
593 return (Dimension) value;
594 return null;
595 }
596
597 /**
598 * Retrieves a font from the defaults table of the current
599 * LookAndFeel.
600 *
601 * @param key an Object that specifies the font. Typically,
602 * this is a String such as
603 * <code>TitledBorder.font</code>.
604 *
605 * @return The font associated with the given key, or <code>null</code>.
606 *
607 * @throws NullPointerException if <code>key</code> is <code>null</code>.
608 */
609 public static Font getFont(Object key)
610 {
611 Object value = get(key);
612 if (value instanceof Font)
613 return (Font) value;
614 return null;
615 }
616
617 /**
618 * Retrieves a font from the defaults table of the current
619 * LookAndFeel.
620 *
621 * @param key an Object that specifies the font. Typically,
622 * this is a String such as
623 * <code>TitledBorder.font</code>.
624 * @param locale the locale.
625 *
626 * @return The font associated with the given key, or <code>null</code>.
627 *
628 * @throws NullPointerException if <code>key</code> is <code>null</code>.
629 *
630 * @since 1.4
631 */
632 public static Font getFont(Object key, Locale locale)
633 {
634 Object value = get(key, locale);
635 if (value instanceof Font)
636 return (Font) value;
637 return null;
638 }
639
640 /**
641 * Returns an icon from the defaults table.
642 *
643 * @param key the key (<code>null</code> not permitted).
644 *
645 * @return The icon associated with the given key, or <code>null</code>.
646 *
647 * @throws NullPointerException if <code>key</code> is <code>null</code>.
648 */
649 public static Icon getIcon(Object key)
650 {
651 Object value = get(key);
652 if (value instanceof Icon)
653 return (Icon) value;
654 return null;
655 }
656
657 /**
658 * Returns an icon from the defaults table.
659 *
660 * @param key the key (<code>null</code> not permitted).
661 * @param locale the locale.
662 *
663 * @return The icon associated with the given key, or <code>null</code>.
664 *
665 * @throws NullPointerException if <code>key</code> is <code>null</code>.
666 * @since 1.4
667 */
668 public static Icon getIcon(Object key, Locale locale)
669 {
670 Object value = get(key, locale);
671 if (value instanceof Icon)
672 return (Icon) value;
673 return null;
674 }
675
676 /**
677 * Returns an Insets object from the defaults table.
678 *
679 * @param key the key (<code>null</code> not permitted).
680 *
681 * @return The insets associated with the given key, or <code>null</code>.
682 *
683 * @throws NullPointerException if <code>key</code> is <code>null</code>.
684 */
685 public static Insets getInsets(Object key)
686 {
687 Object o = get(key);
688 if (o instanceof Insets)
689 return (Insets) o;
690 else
691 return null;
692 }
693
694 /**
695 * Returns an Insets object from the defaults table.
696 *
697 * @param key the key (<code>null</code> not permitted).
698 * @param locale the locale.
699 *
700 * @return The insets associated with the given key, or <code>null</code>.
701 *
702 * @throws NullPointerException if <code>key</code> is <code>null</code>.
703 * @since 1.4
704 */
705 public static Insets getInsets(Object key, Locale locale)
706 {
707 Object o = get(key, locale);
708 if (o instanceof Insets)
709 return (Insets) o;
710 else
711 return null;
712 }
713
714 /**
715 * Returns an array containing information about the {@link LookAndFeel}s
716 * that are installed.
717 *
718 * @return A list of the look and feels that are available (installed).
719 */
720 public static LookAndFeelInfo[] getInstalledLookAndFeels()
721 {
722 return installed;
723 }
724
725 /**
726 * Returns the integer value of the {@link Integer} associated with the
727 * given key. If there is no value, or the value is not an instance of
728 * {@link Integer}, this method returns 0.
729 *
730 * @param key the key (<code>null</code> not permitted).
731 *
732 * @return The integer value associated with the given key, or 0.
733 */
734 public static int getInt(Object key)
735 {
736 Object x = get(key);
737 if (x instanceof Integer)
738 return ((Integer) x).intValue();
739 return 0;
740 }
741
742 /**
743 * Returns the integer value of the {@link Integer} associated with the
744 * given key. If there is no value, or the value is not an instance of
745 * {@link Integer}, this method returns 0.
746 *
747 * @param key the key (<code>null</code> not permitted).
748 * @param locale the locale.
749 *
750 * @return The integer value associated with the given key, or 0.
751 *
752 * @since 1.4
753 */
754 public static int getInt(Object key, Locale locale)
755 {
756 Object x = get(key, locale);
757 if (x instanceof Integer)
758 return ((Integer) x).intValue();
759 return 0;
760 }
761
762 /**
763 * Returns the current look and feel (which may be <code>null</code>).
764 *
765 * @return The current look and feel.
766 *
767 * @see #setLookAndFeel(LookAndFeel)
768 */
769 public static LookAndFeel getLookAndFeel()
770 {
771 return currentLookAndFeel;
772 }
773
774 /**
775 * Returns the <code>UIDefaults</code> table of the currently active
776 * look and feel.
777 *
778 * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
779 */
780 public static UIDefaults getLookAndFeelDefaults()
781 {
782 return lookAndFeelDefaults;
783 }
784
785 /**
786 * Returns the {@link String} associated with the given key. If the value
787 * is not a {@link String}, this method returns <code>null</code>.
788 *
789 * @param key the key (<code>null</code> not permitted).
790 *
791 * @return The string associated with the given key, or <code>null</code>.
792 */
793 public static String getString(Object key)
794 {
795 Object s = get(key);
796 if (s instanceof String)
797 return (String) s;
798 return null;
799 }
800
801 /**
802 * Returns the {@link String} associated with the given key. If the value
803 * is not a {@link String}, this method returns <code>null</code>.
804 *
805 * @param key the key (<code>null</code> not permitted).
806 * @param locale the locale.
807 *
808 * @return The string associated with the given key, or <code>null</code>.
809 *
810 * @since 1.4
811 */
812 public static String getString(Object key, Locale locale)
813 {
814 Object s = get(key, locale);
815 if (s instanceof String)
816 return (String) s;
817 return null;
818 }
819
820 /**
821 * Returns the name of the {@link LookAndFeel} class that implements the
822 * native systems look and feel if there is one, otherwise the name
823 * of the default cross platform LookAndFeel class.
824 *
825 * @return The fully qualified class name for the system look and feel.
826 *
827 * @see #getCrossPlatformLookAndFeelClassName()
828 */
829 public static String getSystemLookAndFeelClassName()
830 {
831 return getCrossPlatformLookAndFeelClassName();
832 }
833
834 /**
835 * Returns UI delegate from the current {@link LookAndFeel} that renders the
836 * target component.
837 *
838 * @param target the target component.
839 */
840 public static ComponentUI getUI(JComponent target)
841 {
842 return getDefaults().getUI(target);
843 }
844
845 /**
846 * Creates a new look and feel and adds it to the current array.
847 *
848 * @param name the look and feel name.
849 * @param className the fully qualified name of the class that implements the
850 * look and feel.
851 */
852 public static void installLookAndFeel(String name, String className)
853 {
854 installLookAndFeel(new LookAndFeelInfo(name, className));
855 }
856
857 /**
858 * Adds the specified look and feel to the current array and then calls
859 * setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]).
860 */
861 public static void installLookAndFeel(LookAndFeelInfo info)
862 {
863 LookAndFeelInfo[] newInstalled = new LookAndFeelInfo[installed.length + 1];
864 System.arraycopy(installed, 0, newInstalled, 0, installed.length);
865 newInstalled[newInstalled.length - 1] = info;
866 setInstalledLookAndFeels(newInstalled);
867 }
868
869 /**
870 * Stores an object in the defaults table.
871 *
872 * @param key the key.
873 * @param value the value.
874 */
875 public static Object put(Object key, Object value)
876 {
877 return getDefaults().put(key, value);
878 }
879
880 /**
881 * Replaces the current array of installed LookAndFeelInfos.
882 */
883 public static void setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
884 {
885 installed = infos;
886 }
887
888 /**
889 * Sets the current {@link LookAndFeel}.
890 *
891 * @param newLookAndFeel the new look and feel (<code>null</code> permitted).
892 *
893 * @throws UnsupportedLookAndFeelException if the look and feel is not
894 * supported on the current platform.
895 *
896 * @see LookAndFeel#isSupportedLookAndFeel()
897 */
898 public static void setLookAndFeel(LookAndFeel newLookAndFeel)
899 throws UnsupportedLookAndFeelException
900 {
901 if (newLookAndFeel != null && ! newLookAndFeel.isSupportedLookAndFeel())
902 throw new UnsupportedLookAndFeelException(newLookAndFeel.getName()
903 + " not supported on this platform");
904 LookAndFeel oldLookAndFeel = currentLookAndFeel;
905 if (oldLookAndFeel != null)
906 oldLookAndFeel.uninitialize();
907
908 // Set the current default look and feel using a LookAndFeel object.
909 currentLookAndFeel = newLookAndFeel;
910 if (newLookAndFeel != null)
911 {
912 newLookAndFeel.initialize();
913 lookAndFeelDefaults = newLookAndFeel.getDefaults();
914 if (currentUIDefaults == null)
915 currentUIDefaults =
916 new MultiplexUIDefaults(lookAndFeelDefaults);
917 else
918 currentUIDefaults.fallback = lookAndFeelDefaults;
919 }
920 else
921 {
922 currentUIDefaults = null;
923 }
924 listeners.firePropertyChange("lookAndFeel", oldLookAndFeel, newLookAndFeel);
925 //revalidate();
926 //repaint();
927 }
928
929 /**
930 * Set the current default look and feel using a class name.
931 *
932 * @param className the look and feel class name.
933 *
934 * @throws UnsupportedLookAndFeelException if the look and feel is not
935 * supported on the current platform.
936 *
937 * @see LookAndFeel#isSupportedLookAndFeel()
938 */
939 public static void setLookAndFeel(String className)
940 throws ClassNotFoundException, InstantiationException, IllegalAccessException,
941 UnsupportedLookAndFeelException
942 {
943 Class c = Class.forName(className, true,
944 Thread.currentThread().getContextClassLoader());
945 LookAndFeel a = (LookAndFeel) c.newInstance(); // throws class-cast-exception
946 setLookAndFeel(a);
947 }
948 }