Frames | No Frames |
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 gnu.java.lang.CPStringBuilder; 42: 43: import java.awt.Color; 44: import java.awt.Dimension; 45: import java.awt.Font; 46: import java.awt.Insets; 47: import java.beans.PropertyChangeListener; 48: import java.beans.PropertyChangeSupport; 49: import java.io.Serializable; 50: import java.util.Enumeration; 51: import java.util.Locale; 52: 53: import javax.swing.border.Border; 54: import javax.swing.plaf.ComponentUI; 55: import javax.swing.plaf.metal.MetalLookAndFeel; 56: 57: /** 58: * Manages the current {@link LookAndFeel} and any auxiliary {@link LookAndFeel} 59: * instances. 60: */ 61: public class UIManager implements Serializable 62: { 63: /** 64: * Represents the basic information about a {@link LookAndFeel} (LAF), so 65: * that a list of installed LAFs can be presented without actually loading 66: * the LAF class(es). 67: */ 68: public static class LookAndFeelInfo 69: { 70: String name, clazz; 71: 72: /** 73: * Creates a new instance. 74: * 75: * @param name the look and feel name. 76: * @param clazz the look and feel class name. 77: */ 78: public LookAndFeelInfo(String name, 79: String clazz) 80: { 81: this.name = name; 82: this.clazz = clazz; 83: } 84: 85: /** 86: * Returns the name of the look and feel. 87: * 88: * @return The name of the look and feel. 89: */ 90: public String getName() 91: { 92: return name; 93: } 94: 95: /** 96: * Returns the fully qualified class name for the {@link LookAndFeel}. 97: * 98: * @return The fully qualified class name for the {@link LookAndFeel}. 99: */ 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: }