001/* UIManager.java -- 002 Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.swing; 040 041import gnu.java.lang.CPStringBuilder; 042 043import java.awt.Color; 044import java.awt.Dimension; 045import java.awt.Font; 046import java.awt.Insets; 047import java.beans.PropertyChangeListener; 048import java.beans.PropertyChangeSupport; 049import java.io.Serializable; 050import java.util.Enumeration; 051import java.util.Locale; 052 053import javax.swing.border.Border; 054import javax.swing.plaf.ComponentUI; 055import javax.swing.plaf.metal.MetalLookAndFeel; 056 057/** 058 * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel} 059 * instances. 060 */ 061public 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}