Source Code Cross Referenced for UIDefaults.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
0026        package javax.swing;
0027
0028        import javax.swing.plaf.ComponentUI;
0029        import javax.swing.border.*;
0030        import javax.swing.event.SwingPropertyChangeSupport;
0031
0032        import java.lang.reflect.*;
0033        import java.util.HashMap;
0034        import java.util.Map;
0035        import java.util.Enumeration;
0036        import java.util.Hashtable;
0037        import java.util.ResourceBundle;
0038        import java.util.ResourceBundle.Control;
0039        import java.util.Locale;
0040        import java.util.Vector;
0041        import java.util.MissingResourceException;
0042        import java.awt.Font;
0043        import java.awt.Color;
0044        import java.awt.Insets;
0045        import java.awt.Dimension;
0046        import java.lang.reflect.Method;
0047        import java.beans.PropertyChangeListener;
0048        import java.beans.PropertyChangeEvent;
0049        import java.security.AccessController;
0050        import java.security.AccessControlContext;
0051        import java.security.PrivilegedAction;
0052
0053        import sun.reflect.misc.MethodUtil;
0054        import sun.util.CoreResourceBundleControl;
0055
0056        /**
0057         * A table of defaults for Swing components.  Applications can set/get
0058         * default values via the <code>UIManager</code>.
0059         * <p>
0060         * <strong>Warning:</strong>
0061         * Serialized objects of this class will not be compatible with
0062         * future Swing releases. The current serialization support is
0063         * appropriate for short term storage or RMI between applications running
0064         * the same version of Swing.  As of 1.4, support for long term storage
0065         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0066         * has been added to the <code>java.beans</code> package.
0067         * Please see {@link java.beans.XMLEncoder}.
0068         *
0069         * @see UIManager
0070         * @version 1.70 05/10/07
0071         * @author Hans Muller
0072         */
0073        public class UIDefaults extends Hashtable<Object, Object> {
0074            private static final Object PENDING = new String("Pending");
0075
0076            private SwingPropertyChangeSupport changeSupport;
0077
0078            private Vector resourceBundles;
0079
0080            private Locale defaultLocale = Locale.getDefault();
0081
0082            /**
0083             * Maps from a Locale to a cached Map of the ResourceBundle. This is done
0084             * so as to avoid an exception being thrown when a value is asked for.
0085             * Access to this should be done while holding a lock on the
0086             * UIDefaults, eg synchronized(this).
0087             */
0088            private Map resourceCache;
0089
0090            /**
0091             * Creates an empty defaults table.
0092             */
0093            public UIDefaults() {
0094                this (700, .75f);
0095            }
0096
0097            /**
0098             * Creates an empty defaults table with the specified initial capacity and
0099             * load factor.
0100             *
0101             * @param initialCapacity   the initial capacity of the defaults table
0102             * @param loadFactor        the load factor of the defaults table
0103             * @see java.util.Hashtable
0104             * @since 1.6
0105             */
0106            public UIDefaults(int initialCapacity, float loadFactor) {
0107                super (initialCapacity, loadFactor);
0108                resourceCache = new HashMap();
0109            }
0110
0111            /**
0112             * Creates a defaults table initialized with the specified
0113             * key/value pairs.  For example:
0114             * <pre>
0115                Object[] uiDefaults = {
0116                     "Font", new Font("Dialog", Font.BOLD, 12),
0117                    "Color", Color.red,
0118                     "five", new Integer(5)
0119                }
0120                UIDefaults myDefaults = new UIDefaults(uiDefaults);
0121             * </pre>
0122             * @param keyValueList  an array of objects containing the key/value
0123             *		pairs
0124             */
0125            public UIDefaults(Object[] keyValueList) {
0126                super (keyValueList.length / 2);
0127                for (int i = 0; i < keyValueList.length; i += 2) {
0128                    super .put(keyValueList[i], keyValueList[i + 1]);
0129                }
0130            }
0131
0132            /**
0133             * Returns the value for key.  If the value is a
0134             * <code>UIDefaults.LazyValue</code> then the real
0135             * value is computed with <code>LazyValue.createValue()</code>,
0136             * the table entry is replaced, and the real value is returned.
0137             * If the value is an <code>UIDefaults.ActiveValue</code>
0138             * the table entry is not replaced - the value is computed
0139             * with <code>ActiveValue.createValue()</code> for each
0140             * <code>get()</code> call.
0141             *
0142             * If the key is not found in the table then it is searched for in the list
0143             * of resource bundles maintained by this object.  The resource bundles are
0144             * searched most recently added first using the locale returned by
0145             * <code>getDefaultLocale</code>.  <code>LazyValues</code> and
0146             * <code>ActiveValues</code> are not supported in the resource bundles.
0147
0148             *
0149             * @param key the desired key
0150             * @return the value for <code>key</code>
0151             * @see LazyValue
0152             * @see ActiveValue
0153             * @see java.util.Hashtable#get
0154             * @see #getDefaultLocale
0155             * @see #addResourceBundle
0156             * @since 1.4
0157             */
0158            public Object get(Object key) {
0159                Object value = getFromHashtable(key);
0160                return (value != null) ? value : getFromResourceBundle(key,
0161                        null);
0162            }
0163
0164            /**
0165             * Looks up up the given key in our Hashtable and resolves LazyValues
0166             * or ActiveValues.
0167             */
0168            private Object getFromHashtable(Object key) {
0169                /* Quickly handle the common case, without grabbing
0170                 * a lock.
0171                 */
0172                Object value = super .get(key);
0173                if ((value != PENDING) && !(value instanceof  ActiveValue)
0174                        && !(value instanceof  LazyValue)) {
0175                    return value;
0176                }
0177
0178                /* If the LazyValue for key is being constructed by another
0179                 * thread then wait and then return the new value, otherwise drop
0180                 * the lock and construct the ActiveValue or the LazyValue.
0181                 * We use the special value PENDING to mark LazyValues that
0182                 * are being constructed.
0183                 */
0184                synchronized (this ) {
0185                    value = super .get(key);
0186                    if (value == PENDING) {
0187                        do {
0188                            try {
0189                                this .wait();
0190                            } catch (InterruptedException e) {
0191                            }
0192                            value = super .get(key);
0193                        } while (value == PENDING);
0194                        return value;
0195                    } else if (value instanceof  LazyValue) {
0196                        super .put(key, PENDING);
0197                    } else if (!(value instanceof  ActiveValue)) {
0198                        return value;
0199                    }
0200                }
0201
0202                /* At this point we know that the value of key was
0203                 * a LazyValue or an ActiveValue.
0204                 */
0205                if (value instanceof  LazyValue) {
0206                    try {
0207                        /* If an exception is thrown we'll just put the LazyValue
0208                         * back in the table.
0209                         */
0210                        value = ((LazyValue) value).createValue(this );
0211                    } finally {
0212                        synchronized (this ) {
0213                            if (value == null) {
0214                                super .remove(key);
0215                            } else {
0216                                super .put(key, value);
0217                            }
0218                            this .notifyAll();
0219                        }
0220                    }
0221                } else {
0222                    value = ((ActiveValue) value).createValue(this );
0223                }
0224
0225                return value;
0226            }
0227
0228            /**
0229             * Returns the value for key associated with the given locale.
0230             * If the value is a <code>UIDefaults.LazyValue</code> then the real
0231             * value is computed with <code>LazyValue.createValue()</code>,
0232             * the table entry is replaced, and the real value is returned.
0233             * If the value is an <code>UIDefaults.ActiveValue</code>
0234             * the table entry is not replaced - the value is computed
0235             * with <code>ActiveValue.createValue()</code> for each
0236             * <code>get()</code> call.
0237             *
0238             * If the key is not found in the table then it is searched for in the list
0239             * of resource bundles maintained by this object.  The resource bundles are
0240             * searched most recently added first using the given locale.
0241             * <code>LazyValues</code> and <code>ActiveValues</code> are not supported
0242             * in the resource bundles.
0243             *
0244             * @param key the desired key
0245             * @param l the desired <code>locale</code>
0246             * @return the value for <code>key</code>
0247             * @see LazyValue
0248             * @see ActiveValue
0249             * @see java.util.Hashtable#get
0250             * @see #addResourceBundle
0251             * @since 1.4
0252             */
0253            public Object get(Object key, Locale l) {
0254                Object value = getFromHashtable(key);
0255                return (value != null) ? value : getFromResourceBundle(key, l);
0256            }
0257
0258            /**
0259             * Looks up given key in our resource bundles.
0260             */
0261            private Object getFromResourceBundle(Object key, Locale l) {
0262
0263                if (resourceBundles == null || resourceBundles.isEmpty()
0264                        || !(key instanceof  String)) {
0265                    return null;
0266                }
0267
0268                // A null locale means use the default locale.
0269                if (l == null) {
0270                    if (defaultLocale == null)
0271                        return null;
0272                    else
0273                        l = (Locale) defaultLocale;
0274                }
0275
0276                synchronized (this ) {
0277                    return getResourceCache(l).get((String) key);
0278                }
0279            }
0280
0281            /**
0282             * Returns a Map of the known resources for the given locale.
0283             */
0284            private Map getResourceCache(Locale l) {
0285                Map values = (Map) resourceCache.get(l);
0286
0287                if (values == null) {
0288                    values = new HashMap();
0289                    for (int i = resourceBundles.size() - 1; i >= 0; i--) {
0290                        String bundleName = (String) resourceBundles.get(i);
0291                        try {
0292                            Control c = CoreResourceBundleControl
0293                                    .getRBControlInstance(bundleName);
0294                            ResourceBundle b;
0295                            if (c != null) {
0296                                b = ResourceBundle.getBundle(bundleName, l, c);
0297                            } else {
0298                                b = ResourceBundle.getBundle(bundleName, l);
0299                            }
0300                            Enumeration keys = b.getKeys();
0301
0302                            while (keys.hasMoreElements()) {
0303                                String key = (String) keys.nextElement();
0304
0305                                if (values.get(key) == null) {
0306                                    Object value = b.getObject(key);
0307
0308                                    values.put(key, value);
0309                                }
0310                            }
0311                        } catch (MissingResourceException mre) {
0312                            // Keep looking
0313                        }
0314                    }
0315                    resourceCache.put(l, values);
0316                }
0317                return values;
0318            }
0319
0320            /**
0321             * Sets the value of <code>key</code> to <code>value</code> for all locales.
0322             * If <code>key</code> is a string and the new value isn't
0323             * equal to the old one, fire a <code>PropertyChangeEvent</code>.
0324             * If value is <code>null</code>, the key is removed from the table.
0325             *
0326             * @param key    the unique <code>Object</code> who's value will be used
0327             *          to retrieve the data value associated with it
0328             * @param value  the new <code>Object</code> to store as data under
0329             *		that key
0330             * @return the previous <code>Object</code> value, or <code>null</code>
0331             * @see #putDefaults
0332             * @see java.util.Hashtable#put
0333             */
0334            public Object put(Object key, Object value) {
0335                Object oldValue = (value == null) ? super .remove(key) : super 
0336                        .put(key, value);
0337                if (key instanceof  String) {
0338                    firePropertyChange((String) key, oldValue, value);
0339                }
0340                return oldValue;
0341            }
0342
0343            /**
0344             * Puts all of the key/value pairs in the database and
0345             * unconditionally generates one <code>PropertyChangeEvent</code>.
0346             * The events oldValue and newValue will be <code>null</code> and its
0347             * <code>propertyName</code> will be "UIDefaults".  The key/value pairs are
0348             * added for all locales.
0349             *
0350             * @param keyValueList  an array of key/value pairs
0351             * @see #put
0352             * @see java.util.Hashtable#put
0353             */
0354            public void putDefaults(Object[] keyValueList) {
0355                for (int i = 0, max = keyValueList.length; i < max; i += 2) {
0356                    Object value = keyValueList[i + 1];
0357                    if (value == null) {
0358                        super .remove(keyValueList[i]);
0359                    } else {
0360                        super .put(keyValueList[i], value);
0361                    }
0362                }
0363                firePropertyChange("UIDefaults", null, null);
0364            }
0365
0366            /**
0367             * If the value of <code>key</code> is a <code>Font</code> return it,
0368             * otherwise return <code>null</code>.
0369             * @param key the desired key
0370             * @return if the value for <code>key</code> is a <code>Font</code>,
0371             * 		return the <code>Font</code> object; otherwise return
0372             *		<code>null</code>
0373             */
0374            public Font getFont(Object key) {
0375                Object value = get(key);
0376                return (value instanceof  Font) ? (Font) value : null;
0377            }
0378
0379            /**
0380             * If the value of <code>key</code> for the given <code>Locale</code>
0381             * is a <code>Font</code> return it, otherwise return <code>null</code>.
0382             * @param key the desired key
0383             * @param l the desired locale      
0384             * @return if the value for <code>key</code> and <code>Locale</code>
0385             *          is a <code>Font</code>,
0386             * 		return the <code>Font</code> object; otherwise return
0387             *		<code>null</code>
0388             * @since 1.4
0389             */
0390            public Font getFont(Object key, Locale l) {
0391                Object value = get(key, l);
0392                return (value instanceof  Font) ? (Font) value : null;
0393            }
0394
0395            /**
0396             * If the value of <code>key</code> is a <code>Color</code> return it,
0397             * otherwise return <code>null</code>.
0398             * @param key the desired key
0399             * @return if the value for <code>key</code> is a <code>Color</code>,
0400             *		return the <code>Color</code> object; otherwise return
0401             *		<code>null</code>
0402             */
0403            public Color getColor(Object key) {
0404                Object value = get(key);
0405                return (value instanceof  Color) ? (Color) value : null;
0406            }
0407
0408            /**
0409             * If the value of <code>key</code> for the given <code>Locale</code>
0410             * is a <code>Color</code> return it, otherwise return <code>null</code>.
0411             * @param key the desired key
0412             * @param l the desired locale      
0413             * @return if the value for <code>key</code> and <code>Locale</code>
0414             *          is a <code>Color</code>,
0415             *		return the <code>Color</code> object; otherwise return
0416             *		<code>null</code>
0417             * @since 1.4
0418             */
0419            public Color getColor(Object key, Locale l) {
0420                Object value = get(key, l);
0421                return (value instanceof  Color) ? (Color) value : null;
0422            }
0423
0424            /**
0425             * If the value of <code>key</code> is an <code>Icon</code> return it,
0426             * otherwise return <code>null</code>.
0427             * @param key the desired key
0428             * @return if the value for <code>key</code> is an <code>Icon</code>,
0429             *		return the <code>Icon</code> object; otherwise return
0430             *		<code>null</code>
0431             */
0432            public Icon getIcon(Object key) {
0433                Object value = get(key);
0434                return (value instanceof  Icon) ? (Icon) value : null;
0435            }
0436
0437            /**
0438             * If the value of <code>key</code> for the given <code>Locale</code>
0439             * is an <code>Icon</code> return it, otherwise return <code>null</code>.
0440             * @param key the desired key
0441             * @param l the desired locale      
0442             * @return if the value for <code>key</code> and <code>Locale</code>
0443             *          is an <code>Icon</code>,
0444             *		return the <code>Icon</code> object; otherwise return
0445             *		<code>null</code>
0446             * @since 1.4
0447             */
0448            public Icon getIcon(Object key, Locale l) {
0449                Object value = get(key, l);
0450                return (value instanceof  Icon) ? (Icon) value : null;
0451            }
0452
0453            /**
0454             * If the value of <code>key</code> is a <code>Border</code> return it,
0455             * otherwise return <code>null</code>.
0456             * @param key the desired key
0457             * @return if the value for <code>key</code> is a <code>Border</code>,
0458             *		return the <code>Border</code> object; otherwise return
0459             *		<code>null</code>
0460             */
0461            public Border getBorder(Object key) {
0462                Object value = get(key);
0463                return (value instanceof  Border) ? (Border) value : null;
0464            }
0465
0466            /**
0467             * If the value of <code>key</code> for the given <code>Locale</code>
0468             * is a <code>Border</code> return it, otherwise return <code>null</code>.
0469             * @param key the desired key
0470             * @param l the desired locale      
0471             * @return if the value for <code>key</code> and <code>Locale</code>
0472             *          is a <code>Border</code>,
0473             *		return the <code>Border</code> object; otherwise return
0474             *		<code>null</code>
0475             * @since 1.4
0476             */
0477            public Border getBorder(Object key, Locale l) {
0478                Object value = get(key, l);
0479                return (value instanceof  Border) ? (Border) value : null;
0480            }
0481
0482            /**
0483             * If the value of <code>key</code> is a <code>String</code> return it,
0484             * otherwise return <code>null</code>.
0485             * @param key the desired key
0486             * @return if the value for <code>key</code> is a <code>String</code>,
0487             *		return the <code>String</code> object; otherwise return
0488             *		<code>null</code>
0489             */
0490            public String getString(Object key) {
0491                Object value = get(key);
0492                return (value instanceof  String) ? (String) value : null;
0493            }
0494
0495            /**
0496             * If the value of <code>key</code> for the given <code>Locale</code>
0497             * is a <code>String</code> return it, otherwise return <code>null</code>.
0498             * @param key the desired key
0499             * @param l the desired <code>Locale</code>
0500             * @return if the value for <code>key</code> for the given
0501             *          <code>Locale</code> is a <code>String</code>,
0502             *		return the <code>String</code> object; otherwise return
0503             *		<code>null</code>
0504             * @since 1.4
0505             */
0506            public String getString(Object key, Locale l) {
0507                Object value = get(key, l);
0508                return (value instanceof  String) ? (String) value : null;
0509            }
0510
0511            /**
0512             * If the value of <code>key</code> is an <code>Integer</code> return its
0513             * integer value, otherwise return 0.
0514             * @param key the desired key
0515             * @return if the value for <code>key</code> is an <code>Integer</code>,
0516             *		return its value, otherwise return 0
0517             */
0518            public int getInt(Object key) {
0519                Object value = get(key);
0520                return (value instanceof  Integer) ? ((Integer) value)
0521                        .intValue() : 0;
0522            }
0523
0524            /**
0525             * If the value of <code>key</code> for the given <code>Locale</code>
0526             * is an <code>Integer</code> return its integer value, otherwise return 0.
0527             * @param key the desired key
0528             * @param l the desired locale      
0529             * @return if the value for <code>key</code> and <code>Locale</code>
0530             *          is an <code>Integer</code>,
0531             *		return its value, otherwise return 0
0532             * @since 1.4
0533             */
0534            public int getInt(Object key, Locale l) {
0535                Object value = get(key, l);
0536                return (value instanceof  Integer) ? ((Integer) value)
0537                        .intValue() : 0;
0538            }
0539
0540            /**
0541             * If the value of <code>key</code> is boolean, return the
0542             * boolean value, otherwise return false.
0543             *
0544             * @param key an <code>Object</code> specifying the key for the desired boolean value
0545             * @return if the value of <code>key</code> is boolean, return the
0546             *         boolean value, otherwise return false.
0547             * @since 1.4
0548             */
0549            public boolean getBoolean(Object key) {
0550                Object value = get(key);
0551                return (value instanceof  Boolean) ? ((Boolean) value)
0552                        .booleanValue() : false;
0553            }
0554
0555            /**
0556             * If the value of <code>key</code> for the given <code>Locale</code>
0557             * is boolean, return the boolean value, otherwise return false.
0558             *
0559             * @param key an <code>Object</code> specifying the key for the desired boolean value
0560             * @param l the desired locale      
0561             * @return if the value for <code>key</code> and <code>Locale</code>
0562             *         is boolean, return the
0563             *         boolean value, otherwise return false.
0564             * @since 1.4
0565             */
0566            public boolean getBoolean(Object key, Locale l) {
0567                Object value = get(key, l);
0568                return (value instanceof  Boolean) ? ((Boolean) value)
0569                        .booleanValue() : false;
0570            }
0571
0572            /**
0573             * If the value of <code>key</code> is an <code>Insets</code> return it,
0574             * otherwise return <code>null</code>.
0575             * @param key the desired key
0576             * @return if the value for <code>key</code> is an <code>Insets</code>,
0577             *		return the <code>Insets</code> object; otherwise return
0578             *		<code>null</code>
0579             */
0580            public Insets getInsets(Object key) {
0581                Object value = get(key);
0582                return (value instanceof  Insets) ? (Insets) value : null;
0583            }
0584
0585            /**
0586             * If the value of <code>key</code> for the given <code>Locale</code>
0587             * is an <code>Insets</code> return it, otherwise return <code>null</code>.
0588             * @param key the desired key
0589             * @param l the desired locale      
0590             * @return if the value for <code>key</code> and <code>Locale</code>
0591             *          is an <code>Insets</code>,
0592             *		return the <code>Insets</code> object; otherwise return
0593             *		<code>null</code>
0594             * @since 1.4
0595             */
0596            public Insets getInsets(Object key, Locale l) {
0597                Object value = get(key, l);
0598                return (value instanceof  Insets) ? (Insets) value : null;
0599            }
0600
0601            /**
0602             * If the value of <code>key</code> is a <code>Dimension</code> return it,
0603             * otherwise return <code>null</code>.
0604             * @param key the desired key
0605             * @return if the value for <code>key</code> is a <code>Dimension</code>,
0606             *		return the <code>Dimension</code> object; otherwise return
0607             *		<code>null</code>
0608             */
0609            public Dimension getDimension(Object key) {
0610                Object value = get(key);
0611                return (value instanceof  Dimension) ? (Dimension) value : null;
0612            }
0613
0614            /**
0615             * If the value of <code>key</code> for the given <code>Locale</code>
0616             * is a <code>Dimension</code> return it, otherwise return <code>null</code>.
0617             * @param key the desired key
0618             * @param l the desired locale      
0619             * @return if the value for <code>key</code> and <code>Locale</code>
0620             *          is a <code>Dimension</code>,
0621             *		return the <code>Dimension</code> object; otherwise return
0622             *		<code>null</code>
0623             * @since 1.4
0624             */
0625            public Dimension getDimension(Object key, Locale l) {
0626                Object value = get(key, l);
0627                return (value instanceof  Dimension) ? (Dimension) value : null;
0628            }
0629
0630            /**
0631             * The value of <code>get(uidClassID)</code> must be the
0632             * <code>String</code> name of a
0633             * class that implements the corresponding <code>ComponentUI</code>
0634             * class.  If the class hasn't been loaded before, this method looks 
0635             * up the class with <code>uiClassLoader.loadClass()</code> if a non 
0636             * <code>null</code>
0637             * class loader is provided, <code>classForName()</code> otherwise.
0638             * <p>
0639             * If a mapping for <code>uiClassID</code> exists or if the specified
0640             * class can't be found, return <code>null</code>.
0641             * <p>
0642             * This method is used by <code>getUI</code>, it's usually
0643             * not necessary to call it directly.
0644             *
0645             * @param uiClassID  a string containing the class ID
0646             * @param uiClassLoader the object which will load the class
0647             * @return the value of <code>Class.forName(get(uidClassID))</code>
0648             * @see #getUI
0649             */
0650            public Class<? extends ComponentUI> getUIClass(String uiClassID,
0651                    ClassLoader uiClassLoader) {
0652                try {
0653                    String className = (String) get(uiClassID);
0654                    if (className != null) {
0655                        Class cls = (Class) get(className);
0656                        if (cls == null) {
0657                            if (uiClassLoader == null) {
0658                                cls = SwingUtilities.loadSystemClass(className);
0659                            } else {
0660                                cls = uiClassLoader.loadClass(className);
0661                            }
0662                            if (cls != null) {
0663                                // Save lookup for future use, as forName is slow.
0664                                put(className, cls);
0665                            }
0666                        }
0667                        return cls;
0668                    }
0669                } catch (ClassNotFoundException e) {
0670                    return null;
0671                } catch (ClassCastException e) {
0672                    return null;
0673                }
0674                return null;
0675            }
0676
0677            /**
0678             * Returns the L&F class that renders this component.
0679             *
0680             * @param uiClassID a string containing the class ID
0681             * @return the Class object returned by
0682             *		<code>getUIClass(uiClassID, null)</code>
0683             */
0684            public Class<? extends ComponentUI> getUIClass(String uiClassID) {
0685                return getUIClass(uiClassID, null);
0686            }
0687
0688            /**
0689             * If <code>getUI()</code> fails for any reason,
0690             * it calls this method before returning <code>null</code>.
0691             * Subclasses may choose to do more or less here.
0692             *
0693             * @param msg message string to print
0694             * @see #getUI
0695             */
0696            protected void getUIError(String msg) {
0697                System.err.println("UIDefaults.getUI() failed: " + msg);
0698                try {
0699                    throw new Error();
0700                } catch (Throwable e) {
0701                    e.printStackTrace();
0702                }
0703            }
0704
0705            /**
0706             * Creates an <code>ComponentUI</code> implementation for the
0707             * specified component.  In other words create the look
0708             * and feel specific delegate object for <code>target</code>.
0709             * This is done in two steps:
0710             * <ul>
0711             * <li> Look up the name of the <code>ComponentUI</code> implementation
0712             * class under the value returned by <code>target.getUIClassID()</code>.
0713             * <li> Use the implementation classes static <code>createUI()</code>
0714             * method to construct a look and feel delegate.
0715             * </ul>
0716             * @param target  the <code>JComponent</code> which needs a UI
0717             * @return the <code>ComponentUI</code> object
0718             */
0719            public ComponentUI getUI(JComponent target) {
0720
0721                Object cl = get("ClassLoader");
0722                ClassLoader uiClassLoader = (cl != null) ? (ClassLoader) cl
0723                        : target.getClass().getClassLoader();
0724                Class uiClass = getUIClass(target.getUIClassID(), uiClassLoader);
0725                Object uiObject = null;
0726
0727                if (uiClass == null) {
0728                    getUIError("no ComponentUI class for: " + target);
0729                } else {
0730                    try {
0731                        Method m = (Method) get(uiClass);
0732                        if (m == null) {
0733                            Class acClass = javax.swing.JComponent.class;
0734                            m = uiClass.getMethod("createUI",
0735                                    new Class[] { acClass });
0736                            put(uiClass, m);
0737                        }
0738                        uiObject = MethodUtil.invoke(m, null,
0739                                new Object[] { target });
0740                    } catch (NoSuchMethodException e) {
0741                        getUIError("static createUI() method not found in "
0742                                + uiClass);
0743                    } catch (Exception e) {
0744                        getUIError("createUI() failed for " + target + " " + e);
0745                    }
0746                }
0747
0748                return (ComponentUI) uiObject;
0749            }
0750
0751            /**
0752             * Adds a <code>PropertyChangeListener</code> to the listener list.
0753             * The listener is registered for all properties.
0754             * <p>
0755             * A <code>PropertyChangeEvent</code> will get fired whenever a default
0756             * is changed.
0757             *
0758             * @param listener  the <code>PropertyChangeListener</code> to be added
0759             * @see java.beans.PropertyChangeSupport
0760             */
0761            public synchronized void addPropertyChangeListener(
0762                    PropertyChangeListener listener) {
0763                if (changeSupport == null) {
0764                    changeSupport = new SwingPropertyChangeSupport(this );
0765                }
0766                changeSupport.addPropertyChangeListener(listener);
0767            }
0768
0769            /**
0770             * Removes a <code>PropertyChangeListener</code> from the listener list.
0771             * This removes a <code>PropertyChangeListener</code> that was registered
0772             * for all properties.
0773             *
0774             * @param listener  the <code>PropertyChangeListener</code> to be removed
0775             * @see java.beans.PropertyChangeSupport
0776             */
0777            public synchronized void removePropertyChangeListener(
0778                    PropertyChangeListener listener) {
0779                if (changeSupport != null) {
0780                    changeSupport.removePropertyChangeListener(listener);
0781                }
0782            }
0783
0784            /**
0785             * Returns an array of all the <code>PropertyChangeListener</code>s added
0786             * to this UIDefaults with addPropertyChangeListener().
0787             *
0788             * @return all of the <code>PropertyChangeListener</code>s added or an empty
0789             *         array if no listeners have been added
0790             * @since 1.4
0791             */
0792            public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
0793                if (changeSupport == null) {
0794                    return new PropertyChangeListener[0];
0795                }
0796                return changeSupport.getPropertyChangeListeners();
0797            }
0798
0799            /**
0800             * Support for reporting bound property changes.  If oldValue and
0801             * newValue are not equal and the <code>PropertyChangeEvent</code>x
0802             * listener list isn't empty, then fire a 
0803             * <code>PropertyChange</code> event to each listener.
0804             *
0805             * @param propertyName  the programmatic name of the property
0806             *		that was changed
0807             * @param oldValue  the old value of the property
0808             * @param newValue  the new value of the property
0809             * @see java.beans.PropertyChangeSupport
0810             */
0811            protected void firePropertyChange(String propertyName,
0812                    Object oldValue, Object newValue) {
0813                if (changeSupport != null) {
0814                    changeSupport.firePropertyChange(propertyName, oldValue,
0815                            newValue);
0816                }
0817            }
0818
0819            /**
0820             * Adds a resource bundle to the list of resource bundles that are
0821             * searched for localized values.  Resource bundles are searched in the
0822             * reverse order they were added.  In other words, the most recently added
0823             * bundle is searched first.
0824             *
0825             * @param bundleName  the base name of the resource bundle to be added
0826             * @see java.util.ResourceBundle
0827             * @see #removeResourceBundle
0828             * @since 1.4
0829             */
0830            public synchronized void addResourceBundle(String bundleName) {
0831                if (bundleName == null) {
0832                    return;
0833                }
0834                if (resourceBundles == null) {
0835                    resourceBundles = new Vector(5);
0836                }
0837                if (!resourceBundles.contains(bundleName)) {
0838                    resourceBundles.add(bundleName);
0839                    resourceCache.clear();
0840                }
0841            }
0842
0843            /**
0844             * Removes a resource bundle from the list of resource bundles that are
0845             * searched for localized defaults.
0846             *
0847             * @param bundleName  the base name of the resource bundle to be removed
0848             * @see java.util.ResourceBundle
0849             * @see #addResourceBundle
0850             * @since 1.4
0851             */
0852            public synchronized void removeResourceBundle(String bundleName) {
0853                if (resourceBundles != null) {
0854                    resourceBundles.remove(bundleName);
0855                }
0856                resourceCache.clear();
0857            }
0858
0859            /**
0860             * Sets the default locale.  The default locale is used in retrieving
0861             * localized values via <code>get</code> methods that do not take a
0862             * locale argument.  As of release 1.4, Swing UI objects should retrieve
0863             * localized values using the locale of their component rather than the
0864             * default locale.  The default locale exists to provide compatibility with
0865             * pre 1.4 behaviour.
0866             *
0867             * @param l the new default locale
0868             * @see #getDefaultLocale
0869             * @see #get(Object)
0870             * @see #get(Object,Locale)
0871             * @since 1.4
0872             */
0873            public void setDefaultLocale(Locale l) {
0874                defaultLocale = l;
0875            }
0876
0877            /**
0878             * Returns the default locale.  The default locale is used in retrieving
0879             * localized values via <code>get</code> methods that do not take a
0880             * locale argument.  As of release 1.4, Swing UI objects should retrieve
0881             * localized values using the locale of their component rather than the
0882             * default locale.  The default locale exists to provide compatibility with
0883             * pre 1.4 behaviour.
0884             *
0885             * @return the default locale
0886             * @see #setDefaultLocale
0887             * @see #get(Object)
0888             * @see #get(Object,Locale)
0889             * @since 1.4
0890             */
0891            public Locale getDefaultLocale() {
0892                return defaultLocale;
0893            }
0894
0895            /**
0896             * This class enables one to store an entry in the defaults
0897             * table that isn't constructed until the first time it's
0898             * looked up with one of the <code>getXXX(key)</code> methods.
0899             * Lazy values are useful for defaults that are expensive
0900             * to construct or are seldom retrieved.  The first time
0901             * a <code>LazyValue</code> is retrieved its "real value" is computed
0902             * by calling <code>LazyValue.createValue()</code> and the real
0903             * value is used to replace the <code>LazyValue</code> in the
0904             * <code>UIDefaults</code>
0905             * table.  Subsequent lookups for the same key return
0906             * the real value.  Here's an example of a <code>LazyValue</code>
0907             * that constructs a <code>Border</code>:
0908             * <pre>
0909             *  Object borderLazyValue = new UIDefaults.LazyValue() {
0910             *      public Object createValue(UIDefaults table) {
0911             *          return new BorderFactory.createLoweredBevelBorder();
0912             *      }
0913             *  };
0914             *
0915             *  uiDefaultsTable.put("MyBorder", borderLazyValue);
0916             * </pre>
0917             *
0918             * @see UIDefaults#get
0919             */
0920            public interface LazyValue {
0921                /**
0922                 * Creates the actual value retrieved from the <code>UIDefaults</code>
0923                 * table. When an object that implements this interface is
0924                 * retrieved from the table, this method is used to create
0925                 * the real value, which is then stored in the table and
0926                 * returned to the calling method.
0927                 *
0928                 * @param table  a <code>UIDefaults</code> table
0929                 * @return the created <code>Object</code>
0930                 */
0931                Object createValue(UIDefaults table);
0932            }
0933
0934            /**
0935             * This class enables one to store an entry in the defaults
0936             * table that's constructed each time it's looked up with one of
0937             * the <code>getXXX(key)</code> methods. Here's an example of
0938             * an <code>ActiveValue</code> that constructs a
0939             * <code>DefaultListCellRenderer</code>:
0940             * <pre>
0941             *  Object cellRendererActiveValue = new UIDefaults.ActiveValue() {
0942             *      public Object createValue(UIDefaults table) {
0943             *          return new DefaultListCellRenderer();
0944             *      }
0945             *  };
0946             *
0947             *  uiDefaultsTable.put("MyRenderer", cellRendererActiveValue);
0948             * </pre>
0949             *
0950             * @see UIDefaults#get
0951             */
0952            public interface ActiveValue {
0953                /**
0954                 * Creates the value retrieved from the <code>UIDefaults</code> table.
0955                 * The object is created each time it is accessed.
0956                 *
0957                 * @param table  a <code>UIDefaults</code> table
0958                 * @return the created <code>Object</code> 
0959                 */
0960                Object createValue(UIDefaults table);
0961            }
0962
0963            /**
0964             * This class provides an implementation of <code>LazyValue</code>
0965             * which can be
0966             * used to delay loading of the Class for the instance to be created.
0967             * It also avoids creation of an anonymous inner class for the
0968             * <code>LazyValue</code>
0969             * subclass.  Both of these improve performance at the time that a
0970             * a Look and Feel is loaded, at the cost of a slight performance
0971             * reduction the first time <code>createValue</code> is called
0972             * (since Reflection APIs are used).
0973             * @since 1.3
0974             */
0975            public static class ProxyLazyValue implements  LazyValue {
0976                private AccessControlContext acc;
0977                private String className;
0978                private String methodName;
0979                private Object[] args;
0980
0981                /**
0982                 * Creates a <code>LazyValue</code> which will construct an instance
0983                 * when asked.
0984                 * 
0985                 * @param c    a <code>String</code> specifying the classname 
0986                 *             of the instance to be created on demand
0987                 */
0988                public ProxyLazyValue(String c) {
0989                    this (c, (String) null);
0990                }
0991
0992                /**
0993                 * Creates a <code>LazyValue</code> which will construct an instance
0994                 * when asked.
0995                 * 
0996                 * @param c    a <code>String</code> specifying the classname of
0997                 *		the class
0998                 *             	containing a static method to be called for
0999                 *             	instance creation
1000                 * @param m    a <code>String</code> specifying the static 
1001                 *		method to be called on class c
1002                 */
1003                public ProxyLazyValue(String c, String m) {
1004                    this (c, m, null);
1005                }
1006
1007                /**
1008                 * Creates a <code>LazyValue</code> which will construct an instance
1009                 * when asked.
1010                 * 
1011                 * @param c    a <code>String</code> specifying the classname
1012                 *		of the instance to be created on demand
1013                 * @param o    an array of <code>Objects</code> to be passed as
1014                 *		paramaters to the constructor in class c
1015                 */
1016                public ProxyLazyValue(String c, Object[] o) {
1017                    this (c, null, o);
1018                }
1019
1020                /**
1021                 * Creates a <code>LazyValue</code> which will construct an instance
1022                 * when asked.
1023                 * 
1024                 * @param c    a <code>String</code> specifying the classname
1025                 *		of the class
1026                 *              containing a static method to be called for
1027                 *              instance creation.
1028                 * @param m    a <code>String</code> specifying the static method
1029                 *		to be called on class c
1030                 * @param o    an array of <code>Objects</code> to be passed as
1031                 *		paramaters to the static method in class c
1032                 */
1033                public ProxyLazyValue(String c, String m, Object[] o) {
1034                    acc = AccessController.getContext();
1035                    className = c;
1036                    methodName = m;
1037                    if (o != null) {
1038                        args = (Object[]) o.clone();
1039                    }
1040                }
1041
1042                /**
1043                 * Creates the value retrieved from the <code>UIDefaults</code> table.
1044                 * The object is created each time it is accessed.
1045                 *
1046                 * @param table  a <code>UIDefaults</code> table
1047                 * @return the created <code>Object</code>
1048                 */
1049                public Object createValue(final UIDefaults table) {
1050                    // In order to pick up the security policy in effect at the
1051                    // time of creation we use a doPrivileged with the
1052                    // AccessControlContext that was in place when this was created.
1053                    return AccessController.doPrivileged(
1054                            new PrivilegedAction() {
1055                                public Object run() {
1056                                    try {
1057                                        Class c;
1058                                        Object cl;
1059                                        // See if we should use a separate ClassLoader
1060                                        if (table == null
1061                                                || !((cl = table
1062                                                        .get("ClassLoader")) instanceof  ClassLoader)) {
1063                                            cl = Thread.currentThread()
1064                                                    .getContextClassLoader();
1065                                            if (cl == null) {
1066                                                // Fallback to the system class loader.
1067                                                cl = ClassLoader
1068                                                        .getSystemClassLoader();
1069                                            }
1070                                        }
1071                                        c = Class.forName(className, true,
1072                                                (ClassLoader) cl);
1073                                        if (methodName != null) {
1074                                            Class[] types = getClassArray(args);
1075                                            Method m = c.getMethod(methodName,
1076                                                    types);
1077                                            return MethodUtil
1078                                                    .invoke(m, c, args);
1079                                        } else {
1080                                            Class[] types = getClassArray(args);
1081                                            Constructor constructor = c
1082                                                    .getConstructor(types);
1083                                            return constructor
1084                                                    .newInstance(args);
1085                                        }
1086                                    } catch (Exception e) {
1087                                        // Ideally we would throw an exception, unfortunately
1088                                        // often times there are errors as an initial look and
1089                                        // feel is loaded before one can be switched. Perhaps a
1090                                        // flag should be added for debugging, so that if true
1091                                        // the exception would be thrown.
1092                                    }
1093                                    return null;
1094                                }
1095                            }, acc);
1096                }
1097
1098                /* 
1099                 * Coerce the array of class types provided into one which
1100                 * looks the way the Reflection APIs expect.  This is done
1101                 * by substituting primitive types for their Object counterparts,
1102                 * and superclasses for subclasses used to add the 
1103                 * <code>UIResource</code> tag.
1104                 */
1105                private Class[] getClassArray(Object[] args) {
1106                    Class[] types = null;
1107                    if (args != null) {
1108                        types = new Class[args.length];
1109                        for (int i = 0; i < args.length; i++) {
1110                            /* PENDING(ges): At present only the primitive types 
1111                               used are handled correctly; this should eventually
1112                               handle all primitive types */
1113                            if (args[i] instanceof  java.lang.Integer) {
1114                                types[i] = Integer.TYPE;
1115                            } else if (args[i] instanceof  java.lang.Boolean) {
1116                                types[i] = Boolean.TYPE;
1117                            } else if (args[i] instanceof  javax.swing.plaf.ColorUIResource) {
1118                                /* PENDING(ges) Currently the Reflection APIs do not 
1119                                   search superclasses of parameters supplied for
1120                                   constructor/method lookup.  Since we only have
1121                                   one case where this is needed, we substitute
1122                                   directly instead of adding a massive amount
1123                                   of mechanism for this.  Eventually this will
1124                                   probably need to handle the general case as well.
1125                                 */
1126                                types[i] = java.awt.Color.class;
1127                            } else {
1128                                types[i] = args[i].getClass();
1129                            }
1130                        }
1131                    }
1132                    return types;
1133                }
1134
1135                private String printArgs(Object[] array) {
1136                    String s = "{";
1137                    if (array != null) {
1138                        for (int i = 0; i < array.length - 1; i++) {
1139                            s = s.concat(array[i] + ",");
1140                        }
1141                        s = s.concat(array[array.length - 1] + "}");
1142                    } else {
1143                        s = s.concat("}");
1144                    }
1145                    return s;
1146                }
1147            }
1148
1149            /**
1150             * <code>LazyInputMap</code> will create a <code>InputMap</code>
1151             * in its <code>createValue</code>
1152             * method. The bindings are passed in in the constructor.
1153             * The bindings are an array with
1154             * the even number entries being string <code>KeyStrokes</code>
1155             * (eg "alt SPACE") and
1156             * the odd number entries being the value to use in the
1157             * <code>InputMap</code> (and the key in the <code>ActionMap</code>).
1158             * @since 1.3
1159             */
1160            public static class LazyInputMap implements  LazyValue {
1161                /** Key bindings are registered under. */
1162                private Object[] bindings;
1163
1164                public LazyInputMap(Object[] bindings) {
1165                    this .bindings = bindings;
1166                }
1167
1168                /**
1169                 * Creates an <code>InputMap</code> with the bindings that are
1170                 * passed in.
1171                 *
1172                 * @param table a <code>UIDefaults</code> table
1173                 * @return the <code>InputMap</code>
1174                 */
1175                public Object createValue(UIDefaults table) {
1176                    if (bindings != null) {
1177                        InputMap km = LookAndFeel.makeInputMap(bindings);
1178                        return km;
1179                    }
1180                    return null;
1181                }
1182            }
1183        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.