Source for javax.swing.UIManager

   1: /* UIManager.java -- 
   2:    Copyright (C) 2002, 2003, 2004, 2005, 2006,  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.awt.Color;
  42: import java.awt.Dimension;
  43: import java.awt.Font;
  44: import java.awt.Insets;
  45: import java.beans.PropertyChangeListener;
  46: import java.beans.PropertyChangeSupport;
  47: import java.io.Serializable;
  48: import java.util.Enumeration;
  49: import java.util.Locale;
  50: 
  51: import javax.swing.border.Border;
  52: import javax.swing.plaf.ComponentUI;
  53: import javax.swing.plaf.metal.MetalLookAndFeel;
  54: 
  55: /**
  56:  * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel}
  57:  * instances.
  58:  */
  59: public class UIManager implements Serializable
  60: {
  61:   /**
  62:    * Represents the basic information about a {@link LookAndFeel} (LAF), so 
  63:    * that a list of installed LAFs can be presented without actually loading 
  64:    * the LAF class(es).
  65:    */
  66:   public static class LookAndFeelInfo
  67:   {
  68:     String name, clazz;
  69:     
  70:     /**
  71:      * Creates a new instance.
  72:      * 
  73:      * @param name  the look and feel name.
  74:      * @param clazz  the look and feel class name.
  75:      */
  76:     public LookAndFeelInfo(String name, 
  77:                String clazz)
  78:     {
  79:       this.name  = name;
  80:       this.clazz = clazz;
  81:     }
  82: 
  83:     /**
  84:      * Returns the name of the look and feel.
  85:      * 
  86:      * @return The name of the look and feel.
  87:      */
  88:     public String getName()
  89:     {
  90:       return name;
  91:     }
  92:     
  93:     /**
  94:      * Returns the fully qualified class name for the {@link LookAndFeel}.
  95:      * 
  96:      * @return The fully qualified class name for the {@link LookAndFeel}.
  97:      */
  98:     public String getClassName()
  99:     {
 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:     MultiplexUIDefaults(UIDefaults d)
 158:     {
 159:       fallback = d;
 160:     }
 161: 
 162:     public Object get(Object key)
 163:     {
 164:       Object val = super.get(key);
 165:       if (val == null)
 166:         val = fallback.get(key);
 167:       return val;
 168:     }
 169: 
 170:     public Object get(Object key, Locale l)
 171:     {
 172:       Object val = super.get(key, l);
 173:       if (val == null)
 174:         val = fallback.get(key, l);
 175:       return val;
 176:     }
 177: 
 178:     public Object remove(Object key)
 179:     {
 180:       Object val = super.remove(key);
 181:       if (val == null)
 182:         val = fallback.remove(key);
 183:       return val;
 184:     }
 185: 
 186:     public int size()
 187:     {
 188:       return super.size() + fallback.size();
 189:     }
 190: 
 191:     public Enumeration keys()
 192:     {
 193:       return new MultiplexEnumeration(super.keys(), fallback.keys());
 194:     }
 195: 
 196:     public Enumeration elements()
 197:     {
 198:       return new MultiplexEnumeration(super.elements(), fallback.elements());
 199:     }
 200:   }
 201: 
 202:   private static final long serialVersionUID = -5547433830339189365L;
 203: 
 204:   /** The installed look and feel(s). */
 205:   static LookAndFeelInfo [] installed = {
 206:     new LookAndFeelInfo("Metal", "javax.swing.plaf.metal.MetalLookAndFeel"),
 207:     new LookAndFeelInfo("GNU", "gnu.javax.swing.plaf.gnu.GNULookAndFeel")
 208:   };
 209: 
 210:   /** The installed auxiliary look and feels. */
 211:   static LookAndFeel[] auxLookAndFeels;
 212:   
 213:   /** The current look and feel. */
 214:   static LookAndFeel currentLookAndFeel;
 215:   
 216:   static MultiplexUIDefaults currentUIDefaults;
 217: 
 218:   static UIDefaults lookAndFeelDefaults;
 219: 
 220:   /** Property change listener mechanism. */
 221:   static PropertyChangeSupport listeners
 222:       = new PropertyChangeSupport(UIManager.class);
 223: 
 224:   static
 225:   {
 226:     String defaultlaf = System.getProperty("swing.defaultlaf");
 227:     try 
 228:       {
 229:         if (defaultlaf != null)
 230:           {
 231:             setLookAndFeel(defaultlaf);
 232:           }
 233:         else
 234:           {
 235:             setLookAndFeel(new MetalLookAndFeel());
 236:           }
 237:       }
 238:     catch (Exception ex)
 239:       {
 240:         System.err.println("cannot initialize Look and Feel: " + defaultlaf);
 241:         System.err.println("error: " + ex.toString());
 242:         ex.printStackTrace();
 243:         System.err.println("falling back to Metal Look and Feel");
 244:         try
 245:           {
 246:             setLookAndFeel(new MetalLookAndFeel());
 247:           }
 248:         catch (Exception ex2)
 249:         {
 250:           throw (Error) new AssertionError("There must be no problem installing"
 251:                                            + " the MetalLookAndFeel.")
 252:                                            .initCause(ex2);
 253:         }
 254:       }
 255:   }
 256: 
 257:   /**
 258:    * Creates a new instance of the <code>UIManager</code>.  There is no need
 259:    * to construct an instance of this class, since all methods are static.
 260:    */
 261:   public UIManager()
 262:   {
 263:     // Do nothing here.
 264:   }
 265: 
 266:   /**
 267:    * Add a <code>PropertyChangeListener</code> to the listener list.
 268:    *
 269:    * @param listener the listener to add
 270:    */
 271:   public static void addPropertyChangeListener(PropertyChangeListener listener)
 272:   {
 273:     listeners.addPropertyChangeListener(listener);
 274:   }
 275: 
 276:   /**
 277:    * Remove a <code>PropertyChangeListener</code> from the listener list.
 278:    *
 279:    * @param listener the listener to remove
 280:    */
 281:   public static void removePropertyChangeListener(PropertyChangeListener 
 282:           listener)
 283:   {
 284:     listeners.removePropertyChangeListener(listener);
 285:   }
 286: 
 287:   /**
 288:    * Returns an array of all added <code>PropertyChangeListener</code> objects.
 289:    *
 290:    * @return an array of listeners
 291:    *
 292:    * @since 1.4
 293:    */
 294:   public static PropertyChangeListener[] getPropertyChangeListeners()
 295:   {
 296:     return listeners.getPropertyChangeListeners();
 297:   }
 298: 
 299:   /**
 300:    * Add a {@link LookAndFeel} to the list of auxiliary look and feels.
 301:    * 
 302:    * @param laf  the auxiliary look and feel (<code>null</code> not permitted).
 303:    * 
 304:    * @throws NullPointerException if <code>laf</code> is <code>null</code>.
 305:    * 
 306:    * @see #getAuxiliaryLookAndFeels()
 307:    */
 308:   public static void addAuxiliaryLookAndFeel(LookAndFeel laf)
 309:   {
 310:     if (laf == null)
 311:       throw new NullPointerException("Null 'laf' argument.");
 312:     if (auxLookAndFeels == null)
 313:       {
 314:         auxLookAndFeels = new LookAndFeel[1];
 315:         auxLookAndFeels[0] = laf;
 316:         return;
 317:       }
 318:     
 319:     LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length + 1];
 320:     System.arraycopy(auxLookAndFeels, 0, temp, 0, auxLookAndFeels.length);             
 321:     auxLookAndFeels = temp;
 322:     auxLookAndFeels[auxLookAndFeels.length - 1] = laf;
 323:   }
 324:     
 325:   /**
 326:    * Removes a {@link LookAndFeel} (LAF) from the list of auxiliary LAFs.
 327:    * 
 328:    * @param laf  the LAF to remove.
 329:    * 
 330:    * @return <code>true</code> if the LAF was removed, and <code>false</code>
 331:    *         otherwise.
 332:    */
 333:   public static boolean removeAuxiliaryLookAndFeel(LookAndFeel laf)
 334:   {
 335:     if (auxLookAndFeels == null)
 336:       return false;
 337:     int count = auxLookAndFeels.length;
 338:     if (count == 1 && auxLookAndFeels[0] == laf)
 339:       {
 340:         auxLookAndFeels = null;
 341:         return true;
 342:       }
 343:     for (int i = 0; i < count; i++)
 344:       {
 345:         if (auxLookAndFeels[i] == laf)
 346:           {
 347:             LookAndFeel[] temp = new LookAndFeel[auxLookAndFeels.length - 1];
 348:             if (i == 0)
 349:               {
 350:                 System.arraycopy(auxLookAndFeels, 1, temp, 0, count - 1);  
 351:               }
 352:             else if (i == count - 1)
 353:               {
 354:                 System.arraycopy(auxLookAndFeels, 0, temp, 0, count - 1);
 355:               }
 356:             else 
 357:               {
 358:                 System.arraycopy(auxLookAndFeels, 0, temp, 0, i);
 359:                 System.arraycopy(auxLookAndFeels, i + 1, temp, i, 
 360:                         count - i - 1);
 361:               }
 362:             auxLookAndFeels = temp;
 363:             return true;
 364:           }        
 365:       }
 366:     return false;
 367:   }
 368: 
 369:   /**
 370:    * Returns an array (possibly <code>null</code>) containing the auxiliary
 371:    * {@link LookAndFeel}s that are in use.  These are used by the 
 372:    * {@link javax.swing.plaf.multi.MultiLookAndFeel} class.
 373:    * 
 374:    * @return The auxiliary look and feels (possibly <code>null</code>).
 375:    * 
 376:    * @see #addAuxiliaryLookAndFeel(LookAndFeel)
 377:    */
 378:   public static LookAndFeel[] getAuxiliaryLookAndFeels()
 379:   {
 380:     return auxLookAndFeels;
 381:   }
 382: 
 383:   /**
 384:    * Returns an object from the {@link UIDefaults} table for the current
 385:    * {@link LookAndFeel}.
 386:    * 
 387:    * @param key  the key.
 388:    * 
 389:    * @return The object.
 390:    */
 391:   public static Object get(Object key)
 392:   {
 393:     return getDefaults().get(key);
 394:   }
 395: 
 396:   /**
 397:    * Returns an object from the {@link UIDefaults} table for the current
 398:    * {@link LookAndFeel}.
 399:    * 
 400:    * @param key  the key.
 401:    * 
 402:    * @return The object.
 403:    */
 404:   public static Object get(Object key, Locale locale)
 405:   {
 406:     return getDefaults().get(key, locale);
 407:   }
 408: 
 409:   /**
 410:    * Returns a boolean value from the defaults table,
 411:    * <code>false</code> if key is not present.
 412:    *
 413:    * @since 1.4
 414:    */
 415:   public static boolean getBoolean(Object key)
 416:   {
 417:     Boolean value = (Boolean) get(key);
 418:     return value != null ? value.booleanValue() : false;
 419:   }
 420:   
 421:   /**
 422:    * Returns a boolean value from the defaults table,
 423:    * <code>false</code> if key is not present.
 424:    *
 425:    * @since 1.4
 426:    */
 427:   public static boolean getBoolean(Object key, Locale locale)
 428:   {
 429:     Boolean value = (Boolean) get(key, locale);
 430:     return value != null ? value.booleanValue() : false;
 431:   }
 432:     
 433:   /**
 434:    * Returns a border from the defaults table. 
 435:    */
 436:   public static Border getBorder(Object key)
 437:   {
 438:     return (Border) get(key);
 439:   }
 440:     
 441:   /**
 442:    * Returns a border from the defaults table.
 443:    *
 444:    * @since 1.4
 445:    */
 446:   public static Border getBorder(Object key, Locale locale)
 447:   {
 448:     return (Border) get(key, locale);
 449:   }
 450:     
 451:   /**
 452:    * Returns a drawing color from the defaults table. 
 453:    */
 454:   public static Color getColor(Object key)
 455:   {
 456:     return (Color) get(key);
 457:   }
 458: 
 459:   /**
 460:    * Returns a drawing color from the defaults table. 
 461:    */
 462:   public static Color getColor(Object key, Locale locale)
 463:   {
 464:     return (Color) get(key);
 465:   }
 466: 
 467:   /**
 468:    * The fully qualified class name of the cross platform (Metal) look and feel.
 469:    * This string can be passed to Class.forName()
 470:    * 
 471:    * @return <code>"javax.swing.plaf.metal.MetalLookAndFeel"</code>
 472:    */
 473:   public static String getCrossPlatformLookAndFeelClassName()
 474:   {    
 475:     return "javax.swing.plaf.metal.MetalLookAndFeel";
 476:   }
 477: 
 478:   /**
 479:    * Returns the default values for this look and feel. 
 480:    * 
 481:    * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
 482:    */
 483:   public static UIDefaults getDefaults()
 484:   {
 485:     if (currentUIDefaults == null)
 486:       currentUIDefaults = new MultiplexUIDefaults(null);
 487:     return currentUIDefaults;
 488:   }
 489: 
 490:   /**
 491:    * Returns a dimension from the defaults table. 
 492:    */
 493:   public static Dimension getDimension(Object key)
 494:   {
 495:     return (Dimension) get(key);
 496:   }
 497: 
 498:   /**
 499:    * Returns a dimension from the defaults table. 
 500:    */
 501:   public static Dimension getDimension(Object key, Locale locale)
 502:   {
 503:     return (Dimension) get(key, locale);
 504:   }
 505: 
 506:   /**
 507:    * Retrieves a font from the defaults table of the current
 508:    * LookAndFeel.
 509:    *
 510:    * @param key an Object that specifies the font. Typically,
 511:    *        this is a String such as
 512:    *        <code>TitledBorder.font</code>.
 513:    */
 514:   public static Font getFont(Object key)
 515:   {
 516:     return (Font) get(key);
 517:   }
 518: 
 519:   /**
 520:    * Retrieves a font from the defaults table of the current
 521:    * LookAndFeel.
 522:    *
 523:    * @param key an Object that specifies the font. Typically,
 524:    *        this is a String such as
 525:    *        <code>TitledBorder.font</code>.
 526:    */
 527:   public static Font getFont(Object key, Locale locale)
 528:   {
 529:     return (Font) get(key, locale);
 530:   }
 531: 
 532:   /**
 533:    * Returns an Icon from the defaults table.
 534:    */
 535:   public static Icon getIcon(Object key)
 536:   {
 537:     return (Icon) get(key);
 538:   }
 539:   
 540:   /**
 541:    * Returns an Icon from the defaults table.
 542:    */
 543:   public static Icon getIcon(Object key, Locale locale)
 544:   {
 545:     return (Icon) get(key, locale);
 546:   }
 547:   
 548:   /**
 549:    * Returns an Insets object from the defaults table.
 550:    */
 551:   public static Insets getInsets(Object key)
 552:   {
 553:     Object o = get(key);
 554:     if (o instanceof Insets)
 555:       return (Insets) o;
 556:     else
 557:       return null;
 558:   }
 559: 
 560:   /**
 561:    * Returns an Insets object from the defaults table.
 562:    */
 563:   public static Insets getInsets(Object key, Locale locale)
 564:   {
 565:     Object o = get(key, locale);
 566:     if (o instanceof Insets)
 567:       return (Insets) o;
 568:     else
 569:       return null;
 570:   }
 571: 
 572:   /**
 573:    * Returns an array containing information about the {@link LookAndFeel}s
 574:    * that are installed.
 575:    * 
 576:    * @return A list of the look and feels that are available (installed).
 577:    */
 578:   public static LookAndFeelInfo[] getInstalledLookAndFeels()
 579:   {
 580:     return installed;
 581:   }
 582: 
 583:   public static int getInt(Object key)
 584:   {
 585:     Integer x = (Integer) get(key);
 586:     if (x == null)
 587:       return 0;
 588:     return x.intValue();
 589:   }
 590: 
 591:   public static int getInt(Object key, Locale locale)
 592:   {
 593:     Integer x = (Integer) get(key, locale);
 594:     if (x == null)
 595:       return 0;
 596:     return x.intValue();
 597:   }
 598: 
 599:   /**
 600:    * Returns the current look and feel (which may be <code>null</code>).
 601:    * 
 602:    * @return The current look and feel.
 603:    * 
 604:    * @see #setLookAndFeel(LookAndFeel)
 605:    */
 606:   public static LookAndFeel getLookAndFeel()
 607:   {
 608:     return currentLookAndFeel;
 609:   }
 610: 
 611:   /**
 612:    * Returns the <code>UIDefaults</code> table of the currently active
 613:    * look and feel.
 614:    * 
 615:    * @return The {@link UIDefaults} for the current {@link LookAndFeel}.
 616:    */
 617:   public static UIDefaults getLookAndFeelDefaults()
 618:   {
 619:     return lookAndFeelDefaults;
 620:   }
 621: 
 622:   /**
 623:    * Returns a string from the defaults table.
 624:    */
 625:   public static String getString(Object key)
 626:   {
 627:     return (String) get(key);
 628:   }
 629:   
 630:   /**
 631:    * Returns a string from the defaults table.
 632:    */
 633:   public static String getString(Object key, Locale locale)
 634:   {
 635:     return (String) get(key, locale);
 636:   }
 637:   
 638:   /**
 639:    * Returns the name of the {@link LookAndFeel} class that implements the
 640:    * native systems look and feel if there is one, otherwise the name
 641:    * of the default cross platform LookAndFeel class.
 642:    * 
 643:    * @return The fully qualified class name for the system look and feel.
 644:    * 
 645:    * @see #getCrossPlatformLookAndFeelClassName()
 646:    */
 647:   public static String getSystemLookAndFeelClassName()
 648:   {
 649:     return getCrossPlatformLookAndFeelClassName();
 650:   }
 651: 
 652:   /**
 653:    * Returns UI delegate from the current {@link LookAndFeel} that renders the 
 654:    * target component.
 655:    * 
 656:    * @param target  the target component.
 657:    */
 658:   public static ComponentUI getUI(JComponent target)
 659:   {
 660:     return getDefaults().getUI(target);
 661:   }
 662: 
 663:   /**
 664:    * Creates a new look and feel and adds it to the current array.
 665:    * 
 666:    * @param name  the look and feel name.
 667:    * @param className  the fully qualified name of the class that implements the
 668:    *                   look and feel.
 669:    */
 670:   public static void installLookAndFeel(String name, String className)
 671:   {
 672:     installLookAndFeel(new LookAndFeelInfo(name, className));
 673:   }
 674: 
 675:   /**
 676:    * Adds the specified look and feel to the current array and then calls
 677:    * setInstalledLookAndFeels(javax.swing.UIManager.LookAndFeelInfo[]).
 678:    */
 679:   public static void installLookAndFeel(LookAndFeelInfo info)
 680:   {
 681:     LookAndFeelInfo[] newInstalled = new LookAndFeelInfo[installed.length + 1];
 682:     System.arraycopy(installed, 0, newInstalled, 0, installed.length);
 683:     newInstalled[newInstalled.length - 1] = info;
 684:     setInstalledLookAndFeels(newInstalled);
 685:   }
 686: 
 687:   /**
 688:    * Stores an object in the defaults table.
 689:    */
 690:   public static Object put(Object key, Object value)
 691:   {
 692:     return getDefaults().put(key, value);
 693:   }
 694: 
 695:   /**
 696:    * Replaces the current array of installed LookAndFeelInfos.
 697:    */
 698:   public static void setInstalledLookAndFeels(UIManager.LookAndFeelInfo[] infos)
 699:   {
 700:     installed = infos;
 701:   }
 702:   
 703:   /**
 704:    * Sets the current {@link LookAndFeel}.
 705:    * 
 706:    * @param newLookAndFeel  the new look and feel (<code>null</code> permitted).
 707:    * 
 708:    * @throws UnsupportedLookAndFeelException if the look and feel is not 
 709:    *         supported on the current platform.
 710:    * 
 711:    * @see LookAndFeel#isSupportedLookAndFeel()
 712:    */
 713:   public static void setLookAndFeel(LookAndFeel newLookAndFeel)
 714:     throws UnsupportedLookAndFeelException
 715:   {
 716:     if (newLookAndFeel != null && ! newLookAndFeel.isSupportedLookAndFeel())
 717:       throw new UnsupportedLookAndFeelException(newLookAndFeel.getName()
 718:                                          + " not supported on this platform");
 719:     LookAndFeel oldLookAndFeel = currentLookAndFeel;
 720:     if (oldLookAndFeel != null)
 721:       oldLookAndFeel.uninitialize();
 722: 
 723:     // Set the current default look and feel using a LookAndFeel object. 
 724:     currentLookAndFeel = newLookAndFeel;
 725:     if (newLookAndFeel != null)
 726:       {
 727:         newLookAndFeel.initialize();
 728:         lookAndFeelDefaults = newLookAndFeel.getDefaults();
 729:         if (currentUIDefaults == null)
 730:           currentUIDefaults =
 731:             new MultiplexUIDefaults(lookAndFeelDefaults);
 732:         else
 733:           currentUIDefaults.fallback = lookAndFeelDefaults;
 734:       }
 735:     else
 736:       {
 737:         currentUIDefaults = null;    
 738:       }
 739:     listeners.firePropertyChange("lookAndFeel", oldLookAndFeel, newLookAndFeel);
 740:     //revalidate();
 741:     //repaint();
 742:   }
 743: 
 744:   /**
 745:    * Set the current default look and feel using a class name.
 746:    * 
 747:    * @param className  the look and feel class name.
 748:    * 
 749:    * @throws UnsupportedLookAndFeelException if the look and feel is not 
 750:    *         supported on the current platform.
 751:    * 
 752:    * @see LookAndFeel#isSupportedLookAndFeel()
 753:    */
 754:   public static void setLookAndFeel(String className)
 755:     throws ClassNotFoundException, InstantiationException, IllegalAccessException,
 756:     UnsupportedLookAndFeelException
 757:   {
 758:     Class c = Class.forName(className, true,
 759:                             Thread.currentThread().getContextClassLoader());
 760:     LookAndFeel a = (LookAndFeel) c.newInstance(); // throws class-cast-exception
 761:     setLookAndFeel(a);
 762:   }
 763: }