Source Code Cross Referenced for UIManager.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package javax.swing;
0026
0027        import java.awt.Component;
0028        import java.awt.Font;
0029        import java.awt.Color;
0030        import java.awt.Insets;
0031        import java.awt.Dimension;
0032        import java.awt.KeyboardFocusManager;
0033        import java.awt.KeyEventPostProcessor;
0034        import java.awt.Toolkit;
0035
0036        import java.awt.event.KeyEvent;
0037
0038        import java.security.AccessController;
0039
0040        import javax.swing.plaf.ComponentUI;
0041        import javax.swing.border.Border;
0042
0043        import javax.swing.event.SwingPropertyChangeSupport;
0044        import java.beans.PropertyChangeListener;
0045
0046        import java.io.Serializable;
0047        import java.io.File;
0048        import java.io.FileInputStream;
0049
0050        import java.util.ArrayList;
0051        import java.util.Properties;
0052        import java.util.StringTokenizer;
0053        import java.util.Vector;
0054        import java.util.Locale;
0055
0056        import sun.awt.SunToolkit;
0057        import sun.awt.OSInfo;
0058        import sun.security.action.GetPropertyAction;
0059        import sun.swing.SwingUtilities2;
0060        import java.lang.reflect.Method;
0061
0062        /**
0063         * {@code UIManager} manages the current look and feel, the set of
0064         * available look and feels, {@code PropertyChangeListeners} that
0065         * are notified when the look and feel changes, look and feel defaults, and
0066         * convenience methods for obtaining various default values.
0067         *
0068         * <h3>Specifying the look and feel</h3>
0069         *
0070         * The look and feel can be specified in two distinct ways: by
0071         * specifying the fully qualified name of the class for the look and
0072         * feel, or by creating an instance of {@code LookAndFeel} and passing
0073         * it to {@code setLookAndFeel}. The following example illustrates
0074         * setting the look and feel to the system look and feel:
0075         * <pre>
0076         *   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
0077         * </pre>
0078         * The following example illustrates setting the look and feel based on
0079         * class name:
0080         * <pre>
0081         *   UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
0082         * </pre>
0083         * Once the look and feel has been changed it is imperative to invoke
0084         * {@code updateUI} on all {@code JComponents}. The method {@link
0085         * SwingUtilities#updateComponentTreeUI} makes it easy to apply {@code
0086         * updateUI} to a containment hierarchy. Refer to it for
0087         * details. The exact behavior of not invoking {@code
0088         * updateUI} after changing the look and feel is
0089         * unspecified. It is very possible to receive unexpected exceptions,
0090         * painting problems, or worse.
0091         *
0092         * <h3>Default look and feel</h3>
0093         *
0094         * The class used for the default look and feel is chosen in the following
0095         * manner:
0096         * <ol>  
0097         *   <li>If the system property <code>swing.defaultlaf</code> is
0098         *       {@code non-null}, use its value as the default look and feel class
0099         *       name.
0100         *   <li>If the {@link java.util.Properties} file <code>swing.properties</code>
0101         *       exists and contains the key <code>swing.defaultlaf</code>,
0102         *       use its value as the default look and feel class name. The location
0103         *       that is checked for <code>swing.properties</code> may vary depending
0104         *       upon the implementation of the Java platform. In Sun's implementation
0105         *       the location is <code>${java.home}/lib/swing.properties</code>.
0106         *       Refer to the release notes of the implementation being used for
0107         *       further details.
0108         *   <li>Otherwise use the cross platform look and feel.
0109         * </ol>
0110         *
0111         * <h3>Defaults</h3>
0112         * 
0113         * {@code UIManager} manages three sets of {@code UIDefaults}. In order, they
0114         * are:
0115         * <ol>
0116         *   <li>Developer defaults. With few exceptions Swing does not
0117         *       alter the developer defaults; these are intended to be modified
0118         *       and used by the developer.
0119         *   <li>Look and feel defaults. The look and feel defaults are
0120         *       supplied by the look and feel at the time it is installed as the
0121         *       current look and feel ({@code setLookAndFeel()} is invoked). The
0122         *       look and feel defaults can be obtained using the {@code
0123         *       getLookAndFeelDefaults()} method.
0124         *   <li>Sytem defaults. The system defaults are provided by Swing.
0125         * </ol>
0126         * Invoking any of the various {@code get} methods
0127         * results in checking each of the defaults, in order, returning
0128         * the first {@code non-null} value. For example, invoking
0129         * {@code UIManager.getString("Table.foreground")} results in first
0130         * checking developer defaults. If the developer defaults contain
0131         * a value for {@code "Table.foreground"} it is returned, otherwise 
0132         * the look and feel defaults are checked, followed by the system defaults.
0133         * <p>
0134         * It's important to note that {@code getDefaults} returns a custom
0135         * instance of {@code UIDefaults} with this resolution logic built into it.
0136         * For example, {@code UIManager.getDefaults().getString("Table.foreground")}
0137         * is equivalent to {@code UIManager.getString("Table.foreground")}. Both
0138         * resolve using the algorithm just described. In many places the
0139         * documentation uses the word defaults to refer to the custom instance
0140         * of {@code UIDefaults} with the resolution logic as previously described.
0141         * <p>
0142         * When the look and feel is changed, {@code UIManager} alters only the
0143         * look and feel defaults; the developer and system defaults are not
0144         * altered by the {@code UIManager} in any way.
0145         * <p>
0146         * The set of defaults a particular look and feel supports is defined
0147         * and documented by that look and feel. In addition, each look and
0148         * feel, or {@code ComponentUI} provided by a look and feel, may
0149         * access the defaults at different times in their life cycle. Some
0150         * look and feels may agressively look up defaults, so that changing a
0151         * default may not have an effect after installing the look and feel.
0152         * Other look and feels may lazily access defaults so that a change to
0153         * the defaults may effect an existing look and feel. Finally, other look
0154         * and feels might not configure themselves from the defaults table in
0155         * any way. None-the-less it is usually the case that a look and feel
0156         * expects certain defaults, so that in general 
0157         * a {@code ComponentUI} provided by one look and feel will not
0158         * work with another look and feel.
0159         * <p>
0160         * <strong>Warning:</strong>
0161         * Serialized objects of this class will not be compatible with
0162         * future Swing releases. The current serialization support is
0163         * appropriate for short term storage or RMI between applications running
0164         * the same version of Swing.  As of 1.4, support for long term storage
0165         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0166         * has been added to the <code>java.beans</code> package.
0167         * Please see {@link java.beans.XMLEncoder}.
0168         *
0169         * @version 1.134 06/07/07
0170         * @author Thomas Ball
0171         * @author Hans Muller
0172         */
0173        public class UIManager implements  Serializable {
0174            /**
0175             * This class defines the state managed by the <code>UIManager</code>.  For 
0176             * Swing applications the fields in this class could just as well
0177             * be static members of <code>UIManager</code> however we give them
0178             * "AppContext"
0179             * scope instead so that applets (and potentially multiple lightweight
0180             * applications running in a single VM) have their own state. For example,
0181             * an applet can alter its look and feel, see <code>setLookAndFeel</code>.
0182             * Doing so has no affect on other applets (or the browser).
0183             */
0184            private static class LAFState {
0185                Properties swingProps;
0186                private UIDefaults[] tables = new UIDefaults[2];
0187
0188                boolean initialized = false;
0189                MultiUIDefaults multiUIDefaults = new MultiUIDefaults(tables);
0190                LookAndFeel lookAndFeel;
0191                LookAndFeel multiLookAndFeel = null;
0192                Vector auxLookAndFeels = null;
0193                SwingPropertyChangeSupport changeSupport;
0194
0195                UIDefaults getLookAndFeelDefaults() {
0196                    return tables[0];
0197                }
0198
0199                void setLookAndFeelDefaults(UIDefaults x) {
0200                    tables[0] = x;
0201                }
0202
0203                UIDefaults getSystemDefaults() {
0204                    return tables[1];
0205                }
0206
0207                void setSystemDefaults(UIDefaults x) {
0208                    tables[1] = x;
0209                }
0210
0211                /**
0212                 * Returns the SwingPropertyChangeSupport for the current
0213                 * AppContext.  If <code>create</code> is a true, a non-null
0214                 * <code>SwingPropertyChangeSupport</code> will be returned, if
0215                 * <code>create</code> is false and this has not been invoked
0216                 * with true, null will be returned.
0217                 */
0218                public synchronized SwingPropertyChangeSupport getPropertyChangeSupport(
0219                        boolean create) {
0220                    if (create && changeSupport == null) {
0221                        changeSupport = new SwingPropertyChangeSupport(
0222                                UIManager.class);
0223                    }
0224                    return changeSupport;
0225                }
0226            }
0227
0228            /* Lock object used in place of class object for synchronization. (4187686)
0229             */
0230            private static final Object classLock = new Object();
0231
0232            /* Cache the last referenced LAFState to improve performance 
0233             * when accessing it.  The cache is based on last thread rather
0234             * than last AppContext because of the cost of looking up the
0235             * AppContext each time.  Since most Swing UI work is on the 
0236             * EventDispatchThread, this hits often enough to justify the
0237             * overhead.  (4193032)
0238             */
0239            private static Thread currentLAFStateThread = null;
0240            private static LAFState currentLAFState = null;
0241
0242            /**
0243             * Return the <code>LAFState</code> object, lazily create one if necessary.
0244             * All access to the <code>LAFState</code> fields is done via this method,
0245             * for example:
0246             * <pre>
0247             *     getLAFState().initialized = true;
0248             * </pre>
0249             */
0250            private static LAFState getLAFState() {
0251                // First check whether we're running on the same thread as
0252                // the last request.
0253                Thread this Thread = Thread.currentThread();
0254                if (this Thread == currentLAFStateThread) {
0255                    return currentLAFState;
0256                }
0257
0258                LAFState rv = (LAFState) SwingUtilities
0259                        .appContextGet(SwingUtilities2.LAF_STATE_KEY);
0260                if (rv == null) {
0261                    synchronized (classLock) {
0262                        rv = (LAFState) SwingUtilities
0263                                .appContextGet(SwingUtilities2.LAF_STATE_KEY);
0264                        if (rv == null) {
0265                            SwingUtilities.appContextPut(
0266                                    SwingUtilities2.LAF_STATE_KEY,
0267                                    (rv = new LAFState()));
0268                        }
0269                    }
0270                }
0271
0272                currentLAFStateThread = this Thread;
0273                currentLAFState = rv;
0274
0275                return rv;
0276            }
0277
0278            /* Keys used for the properties file in <java.home>/lib/swing.properties.
0279             * See loadUserProperties(), initialize().
0280             */
0281
0282            private static final String defaultLAFKey = "swing.defaultlaf";
0283            private static final String auxiliaryLAFsKey = "swing.auxiliarylaf";
0284            private static final String multiplexingLAFKey = "swing.plaf.multiplexinglaf";
0285            private static final String installedLAFsKey = "swing.installedlafs";
0286            private static final String disableMnemonicKey = "swing.disablenavaids";
0287
0288            /**
0289             * Return a swing.properties file key for the attribute of specified 
0290             * look and feel.  The attr is either "name" or "class", a typical
0291             * key would be: "swing.installedlaf.windows.name"
0292             */
0293            private static String makeInstalledLAFKey(String laf, String attr) {
0294                return "swing.installedlaf." + laf + "." + attr;
0295            }
0296
0297            /**
0298             * The filename for swing.properties is a path like this (Unix version):
0299             * <java.home>/lib/swing.properties.  This method returns a bogus
0300             * filename if java.home isn't defined.  
0301             */
0302            private static String makeSwingPropertiesFilename() {
0303                String sep = File.separator;
0304                // No need to wrap this in a doPrivileged as it's called from
0305                // a doPrivileged.
0306                String javaHome = System.getProperty("java.home");
0307                if (javaHome == null) {
0308                    javaHome = "<java.home undefined>";
0309                }
0310                return javaHome + sep + "lib" + sep + "swing.properties";
0311            }
0312
0313            /** 
0314             * Provides a little information about an installed
0315             * <code>LookAndFeel</code> for the sake of configuring a menu or
0316             * for initial application set up.
0317             *
0318             * @see UIManager#getInstalledLookAndFeels
0319             * @see LookAndFeel
0320             */
0321            public static class LookAndFeelInfo {
0322                private String name;
0323                private String className;
0324
0325                /**
0326                 * Constructs a <code>UIManager</code>s 
0327                 * <code>LookAndFeelInfo</code> object.
0328                 *
0329                 * @param name      a <code>String</code> specifying the name of
0330                 *			the look and feel
0331                 * @param className a <code>String</code> specifiying the name of
0332                 *			the class that implements the look and feel
0333                 */
0334                public LookAndFeelInfo(String name, String className) {
0335                    this .name = name;
0336                    this .className = className;
0337                }
0338
0339                /**
0340                 * Returns the name of the look and feel in a form suitable
0341                 * for a menu or other presentation
0342                 * @return a <code>String</code> containing the name
0343                 * @see LookAndFeel#getName
0344                 */
0345                public String getName() {
0346                    return name;
0347                }
0348
0349                /**
0350                 * Returns the name of the class that implements this look and feel.
0351                 * @return the name of the class that implements this 
0352                 *		<code>LookAndFeel</code>
0353                 * @see LookAndFeel
0354                 */
0355                public String getClassName() {
0356                    return className;
0357                }
0358
0359                /**
0360                 * Returns a string that displays and identifies this
0361                 * object's properties.
0362                 *
0363                 * @return a <code>String</code> representation of this object
0364                 */
0365                public String toString() {
0366                    return getClass().getName() + "[" + getName() + " "
0367                            + getClassName() + "]";
0368                }
0369            }
0370
0371            /**
0372             * The default value of <code>installedLAFS</code> is used when no
0373             * swing.properties
0374             * file is available or if the file doesn't contain a "swing.installedlafs"
0375             * property.   
0376             * 
0377             * @see #initializeInstalledLAFs
0378             */
0379            private static LookAndFeelInfo[] installedLAFs;
0380
0381            static {
0382                ArrayList iLAFs = new ArrayList(4);
0383                iLAFs.add(new LookAndFeelInfo("Metal",
0384                        "javax.swing.plaf.metal.MetalLookAndFeel"));
0385                iLAFs.add(new LookAndFeelInfo("CDE/Motif",
0386                        "com.sun.java.swing.plaf.motif.MotifLookAndFeel"));
0387
0388                // Only include windows on Windows boxs.
0389                OSInfo.OSType osType = AccessController.doPrivileged(OSInfo
0390                        .getOSTypeAction());
0391                if (osType == OSInfo.OSType.WINDOWS) {
0392                    iLAFs
0393                            .add(new LookAndFeelInfo("Windows",
0394                                    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"));
0395                    if (Toolkit.getDefaultToolkit().getDesktopProperty(
0396                            "win.xpstyle.themeActive") != null) {
0397                        iLAFs
0398                                .add(new LookAndFeelInfo("Windows Classic",
0399                                        "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"));
0400                    }
0401                } else {
0402                    // GTK is not shipped on Windows.
0403                    iLAFs.add(new LookAndFeelInfo("GTK+",
0404                            "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"));
0405                }
0406                installedLAFs = (LookAndFeelInfo[]) iLAFs
0407                        .toArray(new LookAndFeelInfo[iLAFs.size()]);
0408            }
0409
0410            /** 
0411             * Returns an array of {@code LookAndFeelInfo}s representing the
0412             * {@code LookAndFeel} implementations currently available. The
0413             * <code>LookAndFeelInfo</code> objects can be used by an
0414             * application to construct a menu of look and feel options for
0415             * the user, or to determine which look and feel to set at startup
0416             * time. To avoid the penalty of creating numerous {@code
0417             * LookAndFeel} objects, {@code LookAndFeelInfo} maintains the
0418             * class name of the {@code LookAndFeel} class, not the actual
0419             * {@code LookAndFeel} instance.
0420             * <p>
0421             * The following example illustrates setting the current look and feel
0422             * from an instance of {@code LookAndFeelInfo}:
0423             * <pre>
0424             *   UIManager.setLookAndFeel(info.getClassName());
0425             * </pre>
0426             *
0427             * @return an array of <code>LookAndFeelInfo</code> objects
0428             * @see #setLookAndFeel
0429             */
0430            public static LookAndFeelInfo[] getInstalledLookAndFeels() {
0431                maybeInitialize();
0432                LookAndFeelInfo[] ilafs = installedLAFs;
0433                LookAndFeelInfo[] rv = new LookAndFeelInfo[ilafs.length];
0434                System.arraycopy(ilafs, 0, rv, 0, ilafs.length);
0435                return rv;
0436            }
0437
0438            /**
0439             * Sets the set of available look and feels. While this method does
0440             * not check to ensure all of the {@code LookAndFeelInfos} are
0441             * {@code non-null}, it is strongly recommended that only {@code non-null}
0442             * values are supplied in the {@code infos} array.
0443             *
0444             * @param infos set of <code>LookAndFeelInfo</code> objects specifying
0445             *        the available look and feels
0446             * 
0447             * @see #getInstalledLookAndFeels
0448             * @throws NullPointerException if {@code infos} is {@code null}
0449             */
0450            public static void setInstalledLookAndFeels(LookAndFeelInfo[] infos)
0451                    throws SecurityException {
0452                LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length];
0453                System.arraycopy(infos, 0, newInfos, 0, infos.length);
0454                installedLAFs = newInfos;
0455            }
0456
0457            /**
0458             * Adds the specified look and feel to the set of available look
0459             * and feels. While this method allows a {@code null} {@code info},
0460             * it is strongly recommended that a {@code non-null} value be used.
0461             *
0462             * @param info a <code>LookAndFeelInfo</code> object that names the
0463             *		look and feel and identifies the class that implements it
0464             * @see #setInstalledLookAndFeels
0465             */
0466            public static void installLookAndFeel(LookAndFeelInfo info) {
0467                LookAndFeelInfo[] infos = getInstalledLookAndFeels();
0468                LookAndFeelInfo[] newInfos = new LookAndFeelInfo[infos.length + 1];
0469                System.arraycopy(infos, 0, newInfos, 0, infos.length);
0470                newInfos[infos.length] = info;
0471                setInstalledLookAndFeels(newInfos);
0472            }
0473
0474            /**
0475             * Adds the specified look and feel to the set of available look
0476             * and feels. While this method does not check the
0477             * arguments in any way, it is strongly recommended that {@code
0478             * non-null} values be supplied.
0479             *
0480             * @param name descriptive name of the look and feel
0481             * @param className name of the class that implements the look and feel
0482             * @see #setInstalledLookAndFeels
0483             */
0484            public static void installLookAndFeel(String name, String className) {
0485                installLookAndFeel(new LookAndFeelInfo(name, className));
0486            }
0487
0488            /**
0489             * Returns the current look and feel or <code>null</code>.
0490             *
0491             * @return current look and feel, or <code>null</code>
0492             * @see #setLookAndFeel
0493             */
0494            public static LookAndFeel getLookAndFeel() {
0495                maybeInitialize();
0496                return getLAFState().lookAndFeel;
0497            }
0498
0499            /**
0500             * Sets the current look and feel to {@code newLookAndFeel}. 
0501             * If the current look and feel is {@code non-null} {@code
0502             * uninitialize} is invoked on it. If {@code newLookAndFeel} is
0503             * {@code non-null}, {@code initialize} is invoked on it followed
0504             * by {@code getDefaults}. The defaults returned from {@code
0505             * newLookAndFeel.getDefaults()} replace those of the defaults
0506             * from the previous look and feel. If the {@code newLookAndFeel} is
0507             * {@code null}, the look and feel defaults are set to {@code null}.
0508             * <p>
0509             * A value of {@code null} can be used to set the look and feel
0510             * to {@code null}. As the {@code LookAndFeel} is required for
0511             * most of Swing to function, setting the {@code LookAndFeel} to
0512             * {@code null} is strongly discouraged.
0513             * <p>
0514             * This is a JavaBeans bound property.
0515             *
0516             * @param newLookAndFeel {@code LookAndFeel} to install
0517             * @throws UnsupportedLookAndFeelException if
0518             *          {@code newLookAndFeel} is {@code non-null} and
0519             *          {@code newLookAndFeel.isSupportedLookAndFeel()} returns
0520             *          {@code false}
0521             * @see #getLookAndFeel
0522             */
0523            public static void setLookAndFeel(LookAndFeel newLookAndFeel)
0524                    throws UnsupportedLookAndFeelException {
0525                if ((newLookAndFeel != null)
0526                        && !newLookAndFeel.isSupportedLookAndFeel()) {
0527                    String s = newLookAndFeel.toString()
0528                            + " not supported on this platform";
0529                    throw new UnsupportedLookAndFeelException(s);
0530                }
0531
0532                LAFState lafState = getLAFState();
0533                LookAndFeel oldLookAndFeel = lafState.lookAndFeel;
0534                if (oldLookAndFeel != null) {
0535                    oldLookAndFeel.uninitialize();
0536                }
0537
0538                lafState.lookAndFeel = newLookAndFeel;
0539                if (newLookAndFeel != null) {
0540                    sun.swing.DefaultLookup.setDefaultLookup(null);
0541                    newLookAndFeel.initialize();
0542                    lafState.setLookAndFeelDefaults(newLookAndFeel
0543                            .getDefaults());
0544                } else {
0545                    lafState.setLookAndFeelDefaults(null);
0546                }
0547
0548                SwingPropertyChangeSupport changeSupport = lafState
0549                        .getPropertyChangeSupport(false);
0550                if (changeSupport != null) {
0551                    changeSupport.firePropertyChange("lookAndFeel",
0552                            oldLookAndFeel, newLookAndFeel);
0553                }
0554            }
0555
0556            /**
0557             * Loads the {@code LookAndFeel} specified by the given class
0558             * name, using the current thread's context class loader, and
0559             * passes it to {@code setLookAndFeel(LookAndFeel)}.
0560             *
0561             * @param className  a string specifying the name of the class that implements
0562             *        the look and feel
0563             * @exception ClassNotFoundException if the <code>LookAndFeel</code>
0564             *		 class could not be found
0565             * @exception InstantiationException if a new instance of the class
0566             *		couldn't be created
0567             * @exception IllegalAccessException if the class or initializer isn't accessible
0568             * @exception UnsupportedLookAndFeelException if
0569             *		<code>lnf.isSupportedLookAndFeel()</code> is false
0570             * @throws ClassCastException if {@code className} does not identify
0571             *         a class that extends {@code LookAndFeel}
0572             */
0573            public static void setLookAndFeel(String className)
0574                    throws ClassNotFoundException, InstantiationException,
0575                    IllegalAccessException, UnsupportedLookAndFeelException {
0576                if ("javax.swing.plaf.metal.MetalLookAndFeel".equals(className)) {
0577                    // Avoid reflection for the common case of metal.
0578                    setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
0579                } else {
0580                    Class lnfClass = SwingUtilities.loadSystemClass(className);
0581                    setLookAndFeel((LookAndFeel) (lnfClass.newInstance()));
0582                }
0583            }
0584
0585            /**
0586             * Returns the name of the <code>LookAndFeel</code> class that implements
0587             * the native system look and feel if there is one, otherwise
0588             * the name of the default cross platform <code>LookAndFeel</code>
0589             * class. This value can be overriden by setting the
0590             * <code>swing.systemlaf</code> system property.
0591             * 
0592             * @return the <code>String</code> of the <code>LookAndFeel</code>
0593             *		class
0594             * 
0595             * @see #setLookAndFeel
0596             * @see #getCrossPlatformLookAndFeelClassName
0597             */
0598            public static String getSystemLookAndFeelClassName() {
0599                String systemLAF = AccessController
0600                        .doPrivileged(new GetPropertyAction("swing.systemlaf"));
0601                if (systemLAF != null) {
0602                    return systemLAF;
0603                }
0604                OSInfo.OSType osType = AccessController.doPrivileged(OSInfo
0605                        .getOSTypeAction());
0606                if (osType == OSInfo.OSType.WINDOWS) {
0607                    return "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
0608                } else {
0609                    String desktop = AccessController
0610                            .doPrivileged(new GetPropertyAction("sun.desktop"));
0611                    Toolkit toolkit = Toolkit.getDefaultToolkit();
0612                    if ("gnome".equals(desktop)
0613                            && toolkit instanceof  SunToolkit
0614                            && ((SunToolkit) toolkit).isNativeGTKAvailable()) {
0615                        // May be set on Linux and Solaris boxs.
0616                        return "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
0617                    }
0618                    if (osType == OSInfo.OSType.SOLARIS) {
0619                        return "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
0620                    }
0621                }
0622                return getCrossPlatformLookAndFeelClassName();
0623            }
0624
0625            /**
0626             * Returns the name of the <code>LookAndFeel</code> class that implements
0627             * the default cross platform look and feel -- the Java
0628             * Look and Feel (JLF).  This value can be overriden by setting the
0629             * <code>swing.crossplatformlaf</code> system property.
0630             * 
0631             * @return  a string with the JLF implementation-class
0632             * @see #setLookAndFeel
0633             * @see #getSystemLookAndFeelClassName
0634             */
0635            public static String getCrossPlatformLookAndFeelClassName() {
0636                String laf = (String) AccessController
0637                        .doPrivileged(new GetPropertyAction(
0638                                "swing.crossplatformlaf"));
0639                if (laf != null) {
0640                    return laf;
0641                }
0642                return "javax.swing.plaf.metal.MetalLookAndFeel";
0643            }
0644
0645            /**
0646             * Returns the defaults. The returned defaults resolve using the
0647             * logic specified in the class documentation.
0648             *
0649             * @return a <code>UIDefaults</code> object containing the default values
0650             */
0651            public static UIDefaults getDefaults() {
0652                maybeInitialize();
0653                return getLAFState().multiUIDefaults;
0654            }
0655
0656            /**
0657             * Returns a font from the defaults. If the value for {@code key} is
0658             * not a {@code Font}, {@code null} is returned.
0659             *
0660             * @param key  an <code>Object</code> specifying the font
0661             * @return the <code>Font</code> object
0662             * @throws NullPointerException if {@code key} is {@code null}
0663             */
0664            public static Font getFont(Object key) {
0665                return getDefaults().getFont(key);
0666            }
0667
0668            /**
0669             * Returns a font from the defaults that is appropriate
0670             * for the given locale. If the value for {@code key} is
0671             * not a {@code Font}, {@code null} is returned.
0672             *
0673             * @param key  an <code>Object</code> specifying the font
0674             * @param l the <code>Locale</code> for which the font is desired; refer
0675             *        to {@code UIDefaults} for details on how a {@code null}
0676             *        {@code Locale} is handled
0677             * @return the <code>Font</code> object
0678             * @throws NullPointerException if {@code key} is {@code null}
0679             * @since 1.4
0680             */
0681            public static Font getFont(Object key, Locale l) {
0682                return getDefaults().getFont(key, l);
0683            }
0684
0685            /**
0686             * Returns a color from the defaults. If the value for {@code key} is
0687             * not a {@code Color}, {@code null} is returned.
0688             *
0689             * @param key  an <code>Object</code> specifying the color
0690             * @return the <code>Color</code> object
0691             * @throws NullPointerException if {@code key} is {@code null}
0692             */
0693            public static Color getColor(Object key) {
0694                return getDefaults().getColor(key);
0695            }
0696
0697            /**
0698             * Returns a color from the defaults that is appropriate
0699             * for the given locale. If the value for {@code key} is
0700             * not a {@code Color}, {@code null} is returned.
0701             *
0702             * @param key  an <code>Object</code> specifying the color
0703             * @param l the <code>Locale</code> for which the color is desired; refer
0704             *        to {@code UIDefaults} for details on how a {@code null}
0705             *        {@code Locale} is handled
0706             * @return the <code>Color</code> object
0707             * @throws NullPointerException if {@code key} is {@code null}
0708             * @since 1.4
0709             */
0710            public static Color getColor(Object key, Locale l) {
0711                return getDefaults().getColor(key, l);
0712            }
0713
0714            /**
0715             * Returns an <code>Icon</code> from the defaults. If the value for
0716             * {@code key} is not an {@code Icon}, {@code null} is returned.
0717             *
0718             * @param key  an <code>Object</code> specifying the icon
0719             * @return the <code>Icon</code> object
0720             * @throws NullPointerException if {@code key} is {@code null}
0721             */
0722            public static Icon getIcon(Object key) {
0723                return getDefaults().getIcon(key);
0724            }
0725
0726            /**
0727             * Returns an <code>Icon</code> from the defaults that is appropriate
0728             * for the given locale. If the value for
0729             * {@code key} is not an {@code Icon}, {@code null} is returned.
0730             *
0731             * @param key  an <code>Object</code> specifying the icon
0732             * @param l the <code>Locale</code> for which the icon is desired; refer
0733             *        to {@code UIDefaults} for details on how a {@code null}
0734             *        {@code Locale} is handled
0735             * @return the <code>Icon</code> object
0736             * @throws NullPointerException if {@code key} is {@code null}
0737             * @since 1.4
0738             */
0739            public static Icon getIcon(Object key, Locale l) {
0740                return getDefaults().getIcon(key, l);
0741            }
0742
0743            /**
0744             * Returns a border from the defaults. If the value for
0745             * {@code key} is not a {@code Border}, {@code null} is returned.
0746             *
0747             * @param key  an <code>Object</code> specifying the border
0748             * @return the <code>Border</code> object
0749             * @throws NullPointerException if {@code key} is {@code null}
0750             */
0751            public static Border getBorder(Object key) {
0752                return getDefaults().getBorder(key);
0753            }
0754
0755            /**
0756             * Returns a border from the defaults that is appropriate
0757             * for the given locale.  If the value for
0758             * {@code key} is not a {@code Border}, {@code null} is returned.
0759             *
0760             * @param key  an <code>Object</code> specifying the border
0761             * @param l the <code>Locale</code> for which the border is desired; refer
0762             *        to {@code UIDefaults} for details on how a {@code null}
0763             *        {@code Locale} is handled
0764             * @return the <code>Border</code> object
0765             * @throws NullPointerException if {@code key} is {@code null}
0766             * @since 1.4
0767             */
0768            public static Border getBorder(Object key, Locale l) {
0769                return getDefaults().getBorder(key, l);
0770            }
0771
0772            /**
0773             * Returns a string from the defaults. If the value for
0774             * {@code key} is not a {@code String}, {@code null} is returned.
0775             *
0776             * @param key  an <code>Object</code> specifying the string
0777             * @return the <code>String</code>
0778             * @throws NullPointerException if {@code key} is {@code null}
0779             */
0780            public static String getString(Object key) {
0781                return getDefaults().getString(key);
0782            }
0783
0784            /**
0785             * Returns a string from the defaults that is appropriate for the
0786             * given locale.  If the value for
0787             * {@code key} is not a {@code String}, {@code null} is returned.
0788             *
0789             * @param key  an <code>Object</code> specifying the string
0790             * @param l the <code>Locale</code> for which the string is desired; refer
0791             *        to {@code UIDefaults} for details on how a {@code null}
0792             *        {@code Locale} is handled
0793             * @return the <code>String</code>
0794             * @since 1.4
0795             * @throws NullPointerException if {@code key} is {@code null}
0796             */
0797            public static String getString(Object key, Locale l) {
0798                return getDefaults().getString(key, l);
0799            }
0800
0801            /**
0802             * Returns a string from the defaults that is appropriate for the
0803             * given locale.  If the value for
0804             * {@code key} is not a {@code String}, {@code null} is returned.
0805             *
0806             * @param key  an <code>Object</code> specifying the string
0807             * @param c {@code Component} used to determine the locale;
0808             *          {@code null} implies the default locale as
0809             *          returned by {@code Locale.getDefault()}
0810             * @return the <code>String</code>
0811             * @throws NullPointerException if {@code key} is {@code null}
0812             */
0813            static String getString(Object key, Component c) {
0814                Locale l = (c == null) ? Locale.getDefault() : c.getLocale();
0815                return getString(key, l);
0816            }
0817
0818            /**
0819             * Returns an integer from the defaults. If the value for
0820             * {@code key} is not an {@code Integer}, or does not exist,
0821             * {@code 0} is returned.
0822             *
0823             * @param key  an <code>Object</code> specifying the int
0824             * @return the int
0825             * @throws NullPointerException if {@code key} is {@code null}
0826             */
0827            public static int getInt(Object key) {
0828                return getDefaults().getInt(key);
0829            }
0830
0831            /**
0832             * Returns an integer from the defaults that is appropriate
0833             * for the given locale. If the value for
0834             * {@code key} is not an {@code Integer}, or does not exist,
0835             * {@code 0} is returned.
0836             *
0837             * @param key  an <code>Object</code> specifying the int
0838             * @param l the <code>Locale</code> for which the int is desired; refer
0839             *        to {@code UIDefaults} for details on how a {@code null}
0840             *        {@code Locale} is handled
0841             * @return the int
0842             * @throws NullPointerException if {@code key} is {@code null}
0843             * @since 1.4
0844             */
0845            public static int getInt(Object key, Locale l) {
0846                return getDefaults().getInt(key, l);
0847            }
0848
0849            /**
0850             * Returns a boolean from the defaults which is associated with
0851             * the key value. If the key is not found or the key doesn't represent
0852             * a boolean value then {@code false} is returned.
0853             *
0854             * @param key  an <code>Object</code> specifying the key for the desired boolean value
0855             * @return the boolean value corresponding to the key
0856             * @throws NullPointerException if {@code key} is {@code null}
0857             * @since 1.4
0858             */
0859            public static boolean getBoolean(Object key) {
0860                return getDefaults().getBoolean(key);
0861            }
0862
0863            /**
0864             * Returns a boolean from the defaults which is associated with
0865             * the key value and the given <code>Locale</code>. If the key is not
0866             * found or the key doesn't represent
0867             * a boolean value then {@code false} will be returned.
0868             *
0869             * @param key  an <code>Object</code> specifying the key for the desired 
0870             *             boolean value
0871             * @param l the <code>Locale</code> for which the boolean is desired; refer
0872             *        to {@code UIDefaults} for details on how a {@code null}
0873             *        {@code Locale} is handled
0874             * @return the boolean value corresponding to the key
0875             * @throws NullPointerException if {@code key} is {@code null}
0876             * @since 1.4
0877             */
0878            public static boolean getBoolean(Object key, Locale l) {
0879                return getDefaults().getBoolean(key, l);
0880            }
0881
0882            /**
0883             * Returns an <code>Insets</code> object from the defaults. If the value
0884             * for {@code key} is not an {@code Insets}, {@code null} is returned.
0885             *
0886             * @param key  an <code>Object</code> specifying the <code>Insets</code> object
0887             * @return the <code>Insets</code> object
0888             * @throws NullPointerException if {@code key} is {@code null}
0889             */
0890            public static Insets getInsets(Object key) {
0891                return getDefaults().getInsets(key);
0892            }
0893
0894            /**
0895             * Returns an <code>Insets</code> object from the defaults that is 
0896             * appropriate for the given locale. If the value
0897             * for {@code key} is not an {@code Insets}, {@code null} is returned.
0898             *
0899             * @param key  an <code>Object</code> specifying the <code>Insets</code> object
0900             * @param l the <code>Locale</code> for which the object is desired; refer
0901             *        to {@code UIDefaults} for details on how a {@code null}
0902             *        {@code Locale} is handled
0903             * @return the <code>Insets</code> object
0904             * @throws NullPointerException if {@code key} is {@code null}
0905             * @since 1.4
0906             */
0907            public static Insets getInsets(Object key, Locale l) {
0908                return getDefaults().getInsets(key, l);
0909            }
0910
0911            /**
0912             * Returns a dimension from the defaults. If the value
0913             * for {@code key} is not a {@code Dimension}, {@code null} is returned.
0914             *
0915             * @param key  an <code>Object</code> specifying the dimension object
0916             * @return the <code>Dimension</code> object
0917             * @throws NullPointerException if {@code key} is {@code null}
0918             */
0919            public static Dimension getDimension(Object key) {
0920                return getDefaults().getDimension(key);
0921            }
0922
0923            /**
0924             * Returns a dimension from the defaults that is appropriate
0925             * for the given locale. If the value
0926             * for {@code key} is not a {@code Dimension}, {@code null} is returned.
0927             *
0928             * @param key  an <code>Object</code> specifying the dimension object
0929             * @param l the <code>Locale</code> for which the object is desired; refer
0930             *        to {@code UIDefaults} for details on how a {@code null}
0931             *        {@code Locale} is handled
0932             * @return the <code>Dimension</code> object
0933             * @throws NullPointerException if {@code key} is {@code null}
0934             * @since 1.4
0935             */
0936            public static Dimension getDimension(Object key, Locale l) {
0937                return getDefaults().getDimension(key, l);
0938            }
0939
0940            /**
0941             * Returns an object from the defaults.
0942             *
0943             * @param key  an <code>Object</code> specifying the desired object
0944             * @return the <code>Object</code>
0945             * @throws NullPointerException if {@code key} is {@code null}
0946             */
0947            public static Object get(Object key) {
0948                return getDefaults().get(key);
0949            }
0950
0951            /**
0952             * Returns an object from the defaults that is appropriate for
0953             * the given locale.
0954             *
0955             * @param key  an <code>Object</code> specifying the desired object
0956             * @param l the <code>Locale</code> for which the object is desired; refer
0957             *        to {@code UIDefaults} for details on how a {@code null}
0958             *        {@code Locale} is handled
0959             * @return the <code>Object</code>
0960             * @throws NullPointerException if {@code key} is {@code null}
0961             * @since 1.4
0962             */
0963            public static Object get(Object key, Locale l) {
0964                return getDefaults().get(key, l);
0965            }
0966
0967            /**
0968             * Stores an object in the developer defaults. This is a cover method
0969             * for {@code getDefaults().put(key, value)}. This only effects the
0970             * developer defaults, not the system or look and feel defaults.
0971             *
0972             * @param key    an <code>Object</code> specifying the retrieval key
0973             * @param value  the <code>Object</code> to store; refer to
0974             *               {@code UIDefaults} for details on how {@code null} is
0975             *               handled
0976             * @return the <code>Object</code> returned by {@link UIDefaults#put}
0977             * @throws NullPointerException if {@code key} is {@code null}
0978             * @see UIDefaults#put
0979             */
0980            public static Object put(Object key, Object value) {
0981                return getDefaults().put(key, value);
0982            }
0983
0984            /**
0985             * Returns the appropriate {@code ComponentUI} implementation for 
0986             * {@code target}. Typically, this is a cover for
0987             * {@code getDefaults().getUI(target)}. However, if an auxiliary
0988             * look and feel has been installed, this first invokes
0989             * {@code getUI(target)} on the multiplexing look and feel's
0990             * defaults, and returns that value if it is {@code non-null}.
0991             *
0992             * @param target the <code>JComponent</code> to return the
0993             *        {@code ComponentUI} for
0994             * @return the <code>ComponentUI</code> object for {@code target}
0995             * @throws NullPointerException if {@code target} is {@code null}
0996             * @see UIDefaults#getUI
0997             */
0998            public static ComponentUI getUI(JComponent target) {
0999                maybeInitialize();
1000                ComponentUI ui = null;
1001                LookAndFeel multiLAF = getLAFState().multiLookAndFeel;
1002                if (multiLAF != null) {
1003                    // This can return null if the multiplexing look and feel
1004                    // doesn't support a particular UI.
1005                    ui = multiLAF.getDefaults().getUI(target);
1006                }
1007                if (ui == null) {
1008                    ui = getDefaults().getUI(target);
1009                }
1010                return ui;
1011            }
1012
1013            /**
1014             * Returns the {@code UIDefaults} from the current look and feel,
1015             * that were obtained at the time the look and feel was installed.
1016             * <p>
1017             * In general, developers should use the {@code UIDefaults} returned from
1018             * {@code getDefaults()}. As the current look and feel may expect
1019             * certain values to exist, altering the {@code UIDefaults} returned
1020             * from this method could have unexpected results.
1021             *
1022             * @return <code>UIDefaults</code> from the current look and feel
1023             * @see #getDefaults
1024             * @see #setLookAndFeel(LookAndFeel)
1025             * @see LookAndFeel#getDefaults
1026             */
1027            public static UIDefaults getLookAndFeelDefaults() {
1028                maybeInitialize();
1029                return getLAFState().getLookAndFeelDefaults();
1030            }
1031
1032            /**
1033             * Finds the Multiplexing <code>LookAndFeel</code>.
1034             */
1035            private static LookAndFeel getMultiLookAndFeel() {
1036                LookAndFeel multiLookAndFeel = getLAFState().multiLookAndFeel;
1037                if (multiLookAndFeel == null) {
1038                    String defaultName = "javax.swing.plaf.multi.MultiLookAndFeel";
1039                    String className = getLAFState().swingProps.getProperty(
1040                            multiplexingLAFKey, defaultName);
1041                    try {
1042                        Class lnfClass = SwingUtilities
1043                                .loadSystemClass(className);
1044                        multiLookAndFeel = (LookAndFeel) lnfClass.newInstance();
1045                    } catch (Exception exc) {
1046                        System.err.println("UIManager: failed loading "
1047                                + className);
1048                    }
1049                }
1050                return multiLookAndFeel;
1051            }
1052
1053            /**
1054             * Adds a <code>LookAndFeel</code> to the list of auxiliary look and feels.
1055             * The auxiliary look and feels tell the multiplexing look and feel what
1056             * other <code>LookAndFeel</code> classes for a component instance are to be used 
1057             * in addition to the default <code>LookAndFeel</code> class when creating a 
1058             * multiplexing UI.  The change will only take effect when a new
1059             * UI class is created or when the default look and feel is changed
1060             * on a component instance.
1061             * <p>Note these are not the same as the installed look and feels.
1062             *
1063             * @param laf the <code>LookAndFeel</code> object
1064             * @see #removeAuxiliaryLookAndFeel
1065             * @see #setLookAndFeel
1066             * @see #getAuxiliaryLookAndFeels
1067             * @see #getInstalledLookAndFeels
1068             */
1069            static public void addAuxiliaryLookAndFeel(LookAndFeel laf) {
1070                maybeInitialize();
1071
1072                if (!laf.isSupportedLookAndFeel()) {
1073                    // Ideally we would throw an exception here, but it's too late
1074                    // for that.
1075                    return;
1076                }
1077                Vector v = getLAFState().auxLookAndFeels;
1078                if (v == null) {
1079                    v = new Vector();
1080                }
1081
1082                if (!v.contains(laf)) {
1083                    v.addElement(laf);
1084                    laf.initialize();
1085                    getLAFState().auxLookAndFeels = v;
1086
1087                    if (getLAFState().multiLookAndFeel == null) {
1088                        getLAFState().multiLookAndFeel = getMultiLookAndFeel();
1089                    }
1090                }
1091            }
1092
1093            /**
1094             * Removes a <code>LookAndFeel</code> from the list of auxiliary look and feels.
1095             * The auxiliary look and feels tell the multiplexing look and feel what
1096             * other <code>LookAndFeel</code> classes for a component instance are to be used 
1097             * in addition to the default <code>LookAndFeel</code> class when creating a 
1098             * multiplexing UI.  The change will only take effect when a new
1099             * UI class is created or when the default look and feel is changed
1100             * on a component instance.
1101             * <p>Note these are not the same as the installed look and feels.
1102             * @return true if the <code>LookAndFeel</code> was removed from the list
1103             * @see #removeAuxiliaryLookAndFeel
1104             * @see #getAuxiliaryLookAndFeels
1105             * @see #setLookAndFeel
1106             * @see #getInstalledLookAndFeels
1107             */
1108            static public boolean removeAuxiliaryLookAndFeel(LookAndFeel laf) {
1109                maybeInitialize();
1110
1111                boolean result;
1112
1113                Vector v = getLAFState().auxLookAndFeels;
1114                if ((v == null) || (v.size() == 0)) {
1115                    return false;
1116                }
1117
1118                result = v.removeElement(laf);
1119                if (result) {
1120                    if (v.size() == 0) {
1121                        getLAFState().auxLookAndFeels = null;
1122                        getLAFState().multiLookAndFeel = null;
1123                    } else {
1124                        getLAFState().auxLookAndFeels = v;
1125                    }
1126                }
1127                laf.uninitialize();
1128
1129                return result;
1130            }
1131
1132            /**
1133             * Returns the list of auxiliary look and feels (can be <code>null</code>).
1134             * The auxiliary look and feels tell the multiplexing look and feel what
1135             * other <code>LookAndFeel</code> classes for a component instance are 
1136             * to be used in addition to the default LookAndFeel class when creating a 
1137             * multiplexing UI.  
1138             * <p>Note these are not the same as the installed look and feels.
1139             *
1140             * @return list of auxiliary <code>LookAndFeel</code>s or <code>null</code>
1141             * @see #addAuxiliaryLookAndFeel
1142             * @see #removeAuxiliaryLookAndFeel
1143             * @see #setLookAndFeel
1144             * @see #getInstalledLookAndFeels
1145             */
1146            static public LookAndFeel[] getAuxiliaryLookAndFeels() {
1147                maybeInitialize();
1148
1149                Vector v = getLAFState().auxLookAndFeels;
1150                if ((v == null) || (v.size() == 0)) {
1151                    return null;
1152                } else {
1153                    LookAndFeel[] rv = new LookAndFeel[v.size()];
1154                    for (int i = 0; i < rv.length; i++) {
1155                        rv[i] = (LookAndFeel) v.elementAt(i);
1156                    }
1157                    return rv;
1158                }
1159            }
1160
1161            /**
1162             * Adds a <code>PropertyChangeListener</code> to the listener list.
1163             * The listener is registered for all properties.
1164             *
1165             * @param listener  the <code>PropertyChangeListener</code> to be added
1166             * @see java.beans.PropertyChangeSupport
1167             */
1168            public static void addPropertyChangeListener(
1169                    PropertyChangeListener listener) {
1170                synchronized (classLock) {
1171                    getLAFState().getPropertyChangeSupport(true)
1172                            .addPropertyChangeListener(listener);
1173                }
1174            }
1175
1176            /**
1177             * Removes a <code>PropertyChangeListener</code> from the listener list.
1178             * This removes a <code>PropertyChangeListener</code> that was registered
1179             * for all properties.
1180             *
1181             * @param listener  the <code>PropertyChangeListener</code> to be removed
1182             * @see java.beans.PropertyChangeSupport
1183             */
1184            public static void removePropertyChangeListener(
1185                    PropertyChangeListener listener) {
1186                synchronized (classLock) {
1187                    getLAFState().getPropertyChangeSupport(true)
1188                            .removePropertyChangeListener(listener);
1189                }
1190            }
1191
1192            /**
1193             * Returns an array of all the <code>PropertyChangeListener</code>s added
1194             * to this UIManager with addPropertyChangeListener().
1195             *
1196             * @return all of the <code>PropertyChangeListener</code>s added or an empty
1197             *         array if no listeners have been added
1198             * @since 1.4
1199             */
1200            public static PropertyChangeListener[] getPropertyChangeListeners() {
1201                synchronized (classLock) {
1202                    return getLAFState().getPropertyChangeSupport(true)
1203                            .getPropertyChangeListeners();
1204                }
1205            }
1206
1207            private static Properties loadSwingProperties() {
1208                /* Don't bother checking for Swing properties if untrusted, as
1209                 * there's no way to look them up without triggering SecurityExceptions.
1210                 */
1211                if (UIManager.class.getClassLoader() != null) {
1212                    return new Properties();
1213                } else {
1214                    final Properties props = new Properties();
1215
1216                    java.security.AccessController
1217                            .doPrivileged(new java.security.PrivilegedAction() {
1218                                public Object run() {
1219                                    try {
1220                                        File file = new File(
1221                                                makeSwingPropertiesFilename());
1222
1223                                        if (file.exists()) {
1224                                            // InputStream has been buffered in Properties
1225                                            // class
1226                                            FileInputStream ins = new FileInputStream(
1227                                                    file);
1228                                            props.load(ins);
1229                                            ins.close();
1230                                        }
1231                                    } catch (Exception e) {
1232                                        // No such file, or file is otherwise non-readable.
1233                                    }
1234
1235                                    // Check whether any properties were overridden at the
1236                                    // command line.
1237                                    checkProperty(props, defaultLAFKey);
1238                                    checkProperty(props, auxiliaryLAFsKey);
1239                                    checkProperty(props, multiplexingLAFKey);
1240                                    checkProperty(props, installedLAFsKey);
1241                                    checkProperty(props, disableMnemonicKey);
1242                                    // Don't care about return value.
1243                                    return null;
1244                                }
1245                            });
1246                    return props;
1247                }
1248            }
1249
1250            private static void checkProperty(Properties props, String key) {
1251                // No need to do catch the SecurityException here, this runs
1252                // in a doPrivileged.
1253                String value = System.getProperty(key);
1254                if (value != null) {
1255                    props.put(key, value);
1256                }
1257            }
1258
1259            /**
1260             * If a swing.properties file exist and it has a swing.installedlafs property
1261             * then initialize the <code>installedLAFs</code> field.
1262             * 
1263             * @see #getInstalledLookAndFeels
1264             */
1265            private static void initializeInstalledLAFs(Properties swingProps) {
1266                String ilafsString = swingProps.getProperty(installedLAFsKey);
1267                if (ilafsString == null) {
1268                    return;
1269                }
1270
1271                /* Create a vector that contains the value of the swing.installedlafs
1272                 * property.  For example given "swing.installedlafs=motif,windows"
1273                 * lafs = {"motif", "windows"}.
1274                 */
1275                Vector lafs = new Vector();
1276                StringTokenizer st = new StringTokenizer(ilafsString, ",",
1277                        false);
1278                while (st.hasMoreTokens()) {
1279                    lafs.addElement(st.nextToken());
1280                }
1281
1282                /* Look up the name and class for each name in the "swing.installedlafs"
1283                 * list.  If they both exist then add a LookAndFeelInfo to 
1284                 * the installedLafs array.
1285                 */
1286                Vector ilafs = new Vector(lafs.size());
1287                for (int i = 0; i < lafs.size(); i++) {
1288                    String laf = (String) lafs.elementAt(i);
1289                    String name = swingProps.getProperty(makeInstalledLAFKey(
1290                            laf, "name"), laf);
1291                    String cls = swingProps.getProperty(makeInstalledLAFKey(
1292                            laf, "class"));
1293                    if (cls != null) {
1294                        ilafs.addElement(new LookAndFeelInfo(name, cls));
1295                    }
1296                }
1297
1298                installedLAFs = new LookAndFeelInfo[ilafs.size()];
1299                for (int i = 0; i < ilafs.size(); i++) {
1300                    installedLAFs[i] = (LookAndFeelInfo) (ilafs.elementAt(i));
1301                }
1302            }
1303
1304            /**
1305             * If the user has specified a default look and feel, use that.  
1306             * Otherwise use the look and feel that's native to this platform.
1307             * If this code is called after the application has explicitly
1308             * set it's look and feel, do nothing.
1309             *
1310             * @see #maybeInitialize
1311             */
1312            private static void initializeDefaultLAF(Properties swingProps) {
1313                if (getLAFState().lookAndFeel != null) {
1314                    return;
1315                }
1316
1317                String metalLnf = getCrossPlatformLookAndFeelClassName();
1318                String lnfDefault = metalLnf;
1319
1320                String lnfName = "<undefined>";
1321                try {
1322                    lnfName = swingProps.getProperty(defaultLAFKey, lnfDefault);
1323                    setLookAndFeel(lnfName);
1324                } catch (Exception e) {
1325                    try {
1326                        lnfName = swingProps.getProperty(defaultLAFKey,
1327                                metalLnf);
1328                        setLookAndFeel(lnfName);
1329                    } catch (Exception e2) {
1330                        throw new Error("can't load " + lnfName);
1331                    }
1332                }
1333            }
1334
1335            private static void initializeAuxiliaryLAFs(Properties swingProps) {
1336                String auxLookAndFeelNames = swingProps
1337                        .getProperty(auxiliaryLAFsKey);
1338                if (auxLookAndFeelNames == null) {
1339                    return;
1340                }
1341
1342                Vector auxLookAndFeels = new Vector();
1343
1344                StringTokenizer p = new StringTokenizer(auxLookAndFeelNames,
1345                        ",");
1346                String factoryName;
1347
1348                /* Try to load each LookAndFeel subclass in the list.
1349                 */
1350
1351                while (p.hasMoreTokens()) {
1352                    String className = p.nextToken();
1353                    try {
1354                        Class lnfClass = SwingUtilities
1355                                .loadSystemClass(className);
1356                        LookAndFeel newLAF = (LookAndFeel) lnfClass
1357                                .newInstance();
1358                        newLAF.initialize();
1359                        auxLookAndFeels.addElement(newLAF);
1360                    } catch (Exception e) {
1361                        System.err
1362                                .println("UIManager: failed loading auxiliary look and feel "
1363                                        + className);
1364                    }
1365                }
1366
1367                /* If there were problems and no auxiliary look and feels were 
1368                 * loaded, make sure we reset auxLookAndFeels to null.
1369                 * Otherwise, we are going to use the MultiLookAndFeel to get
1370                 * all component UI's, so we need to load it now.
1371                 */
1372                if (auxLookAndFeels.size() == 0) {
1373                    auxLookAndFeels = null;
1374                } else {
1375                    getLAFState().multiLookAndFeel = getMultiLookAndFeel();
1376                    if (getLAFState().multiLookAndFeel == null) {
1377                        auxLookAndFeels = null;
1378                    }
1379                }
1380
1381                getLAFState().auxLookAndFeels = auxLookAndFeels;
1382            }
1383
1384            private static void initializeSystemDefaults(Properties swingProps) {
1385                getLAFState().swingProps = swingProps;
1386            }
1387
1388            /* 
1389             * This method is called before any code that depends on the 
1390             * <code>AppContext</code> specific LAFState object runs.  When the AppContext
1391             * corresponds to a set of applets it's possible for this method 
1392             * to be re-entered, which is why we grab a lock before calling
1393             * initialize().
1394             */
1395            private static void maybeInitialize() {
1396                synchronized (classLock) {
1397                    if (!getLAFState().initialized) {
1398                        getLAFState().initialized = true;
1399                        initialize();
1400                    }
1401                }
1402            }
1403
1404            /*
1405             * Only called by maybeInitialize().
1406             */
1407            private static void initialize() {
1408                Properties swingProps = loadSwingProperties();
1409                initializeSystemDefaults(swingProps);
1410                initializeDefaultLAF(swingProps);
1411                initializeAuxiliaryLAFs(swingProps);
1412                initializeInstalledLAFs(swingProps);
1413
1414                // Enable the Swing default LayoutManager.
1415                String toolkitName = Toolkit.getDefaultToolkit().getClass()
1416                        .getName();
1417                // don't set default policy if this is XAWT.
1418                if (!"sun.awt.X11.XToolkit".equals(toolkitName)) {
1419                    if (FocusManager.isFocusManagerEnabled()) {
1420                        KeyboardFocusManager.getCurrentKeyboardFocusManager()
1421                                .setDefaultFocusTraversalPolicy(
1422                                        new LayoutFocusTraversalPolicy());
1423                    }
1424                }
1425
1426                // Install Swing's PaintEventDispatcher
1427                if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
1428                    sun.awt.PaintEventDispatcher
1429                            .setPaintEventDispatcher(new SwingPaintEventDispatcher());
1430                }
1431                // Install a hook that will be invoked if no one consumes the
1432                // KeyEvent.  If the source isn't a JComponent this will process
1433                // key bindings, if the source is a JComponent it implies that
1434                // processKeyEvent was already invoked and thus no need to process
1435                // the bindings again, unless the Component is disabled, in which
1436                // case KeyEvents will no longer be dispatched to it so that we
1437                // handle it here.
1438                KeyboardFocusManager.getCurrentKeyboardFocusManager()
1439                        .addKeyEventPostProcessor(new KeyEventPostProcessor() {
1440                            public boolean postProcessKeyEvent(KeyEvent e) {
1441                                Component c = e.getComponent();
1442
1443                                if ((!(c instanceof  JComponent) || (c != null && !((JComponent) c)
1444                                        .isEnabled()))
1445                                        && JComponent.KeyboardState
1446                                                .shouldProcess(e)
1447                                        && SwingUtilities.processKeyBindings(e)) {
1448                                    e.consume();
1449                                    return true;
1450                                }
1451                                return false;
1452                            }
1453                        });
1454                try {
1455                    Method setRequestFocusControllerM = java.security.AccessController
1456                            .doPrivileged(new java.security.PrivilegedExceptionAction<Method>() {
1457                                public Method run() throws Exception {
1458                                    Method method = Component.class
1459                                            .getDeclaredMethod(
1460                                                    "setRequestFocusController",
1461                                                    sun.awt.RequestFocusController.class);
1462                                    method.setAccessible(true);
1463                                    return method;
1464                                }
1465                            });
1466                    setRequestFocusControllerM.invoke(null,
1467                            JComponent.focusController);
1468                } catch (Exception e) {
1469                    // perhaps we should log this
1470                    assert false;
1471                }
1472            }
1473        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.