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