src/share/classes/javax/swing/UIDefaults.java

Print this page




 294     }
 295 
 296     /**
 297      * Returns a Map of the known resources for the given locale.
 298      */
 299     private Map<String, Object> getResourceCache(Locale l) {
 300         Map<String, Object> values = resourceCache.get(l);
 301 
 302         if (values == null) {
 303             values = new TextAndMnemonicHashMap();
 304             for (int i=resourceBundles.size()-1; i >= 0; i--) {
 305                 String bundleName = resourceBundles.get(i);
 306                 try {
 307                     Control c = CoreResourceBundleControl.getRBControlInstance(bundleName);
 308                     ResourceBundle b;
 309                     if (c != null) {
 310                         b = ResourceBundle.getBundle(bundleName, l, c);
 311                     } else {
 312                         b = ResourceBundle.getBundle(bundleName, l);
 313                     }
 314                     Enumeration keys = b.getKeys();
 315 
 316                     while (keys.hasMoreElements()) {
 317                         String key = (String)keys.nextElement();
 318 
 319                         if (values.get(key) == null) {
 320                             Object value = b.getObject(key);
 321 
 322                             values.put(key, value);
 323                         }
 324                     }
 325                 } catch( MissingResourceException mre ) {
 326                     // Keep looking
 327                 }
 328             }
 329             resourceCache.put(l, values);
 330         }
 331         return values;
 332     }
 333 
 334     /**
 335      * Sets the value of <code>key</code> to <code>value</code> for all locales.
 336      * If <code>key</code> is a string and the new value isn't
 337      * equal to the old one, fire a <code>PropertyChangeEvent</code>.


 665      * <p>
 666      * If a mapping for <code>uiClassID</code> exists or if the specified
 667      * class can't be found, return <code>null</code>.
 668      * <p>
 669      * This method is used by <code>getUI</code>, it's usually
 670      * not necessary to call it directly.
 671      *
 672      * @param uiClassID  a string containing the class ID
 673      * @param uiClassLoader the object which will load the class
 674      * @return the value of <code>Class.forName(get(uidClassID))</code>
 675      * @see #getUI
 676      */
 677     public Class<? extends ComponentUI>
 678         getUIClass(String uiClassID, ClassLoader uiClassLoader)
 679     {
 680         try {
 681             String className = (String)get(uiClassID);
 682             if (className != null) {
 683                 ReflectUtil.checkPackageAccess(className);
 684 
 685                 Class cls = (Class)get(className);
 686                 if (cls == null) {
 687                     if (uiClassLoader == null) {
 688                         cls = SwingUtilities.loadSystemClass(className);
 689                     }
 690                     else {
 691                         cls = uiClassLoader.loadClass(className);
 692                     }
 693                     if (cls != null) {
 694                         // Save lookup for future use, as forName is slow.
 695                         put(className, cls);
 696                     }
 697                 }
 698                 return cls;


 699             }
 700         }
 701         catch (ClassNotFoundException e) {
 702             return null;
 703         }
 704         catch (ClassCastException e) {
 705             return null;
 706         }
 707         return null;
 708     }
 709 
 710 
 711     /**
 712      * Returns the L&amp;F class that renders this component.
 713      *
 714      * @param uiClassID a string containing the class ID
 715      * @return the Class object returned by
 716      *          <code>getUIClass(uiClassID, null)</code>
 717      */
 718     public Class<? extends ComponentUI> getUIClass(String uiClassID) {
 719         return getUIClass(uiClassID, null);
 720     }
 721 
 722 
 723     /**
 724      * If <code>getUI()</code> fails for any reason,


 750      * method to construct a look and feel delegate.
 751      * </ul>
 752      * @param target  the <code>JComponent</code> which needs a UI
 753      * @return the <code>ComponentUI</code> object
 754      */
 755     public ComponentUI getUI(JComponent target) {
 756 
 757         Object cl = get("ClassLoader");
 758         ClassLoader uiClassLoader =
 759             (cl != null) ? (ClassLoader)cl : target.getClass().getClassLoader();
 760         Class<? extends ComponentUI> uiClass = getUIClass(target.getUIClassID(), uiClassLoader);
 761         Object uiObject = null;
 762 
 763         if (uiClass == null) {
 764             getUIError("no ComponentUI class for: " + target);
 765         }
 766         else {
 767             try {
 768                 Method m = (Method)get(uiClass);
 769                 if (m == null) {
 770                     m = uiClass.getMethod("createUI", new Class[]{JComponent.class});
 771                     put(uiClass, m);
 772                 }
 773                 uiObject = MethodUtil.invoke(m, null, new Object[]{target});
 774             }
 775             catch (NoSuchMethodException e) {
 776                 getUIError("static createUI() method not found in " + uiClass);
 777             }
 778             catch (Exception e) {
 779                 getUIError("createUI() failed for " + target + " " + e);
 780             }
 781         }
 782 
 783         return (ComponentUI)uiObject;
 784     }
 785 
 786     /**
 787      * Adds a <code>PropertyChangeListener</code> to the listener list.
 788      * The listener is registered for all properties.
 789      * <p>
 790      * A <code>PropertyChangeEvent</code> will get fired whenever a default


1089             }
1090             return AccessController.doPrivileged(new PrivilegedAction<Object>() {
1091                 public Object run() {
1092                     try {
1093                         Class<?> c;
1094                         Object cl;
1095                         // See if we should use a separate ClassLoader
1096                         if (table == null || !((cl = table.get("ClassLoader"))
1097                                                instanceof ClassLoader)) {
1098                             cl = Thread.currentThread().
1099                                         getContextClassLoader();
1100                             if (cl == null) {
1101                                 // Fallback to the system class loader.
1102                                 cl = ClassLoader.getSystemClassLoader();
1103                             }
1104                         }
1105                         ReflectUtil.checkPackageAccess(className);
1106                         c = Class.forName(className, true, (ClassLoader)cl);
1107                         SwingUtilities2.checkAccess(c.getModifiers());
1108                         if (methodName != null) {
1109                             Class[] types = getClassArray(args);
1110                             Method m = c.getMethod(methodName, types);
1111                             return MethodUtil.invoke(m, c, args);
1112                         } else {
1113                             Class[] types = getClassArray(args);
1114                             Constructor constructor = c.getConstructor(types);
1115                             SwingUtilities2.checkAccess(constructor.getModifiers());
1116                             return constructor.newInstance(args);
1117                         }
1118                     } catch(Exception e) {
1119                         // Ideally we would throw an exception, unfortunately
1120                         // often times there are errors as an initial look and
1121                         // feel is loaded before one can be switched. Perhaps a
1122                         // flag should be added for debugging, so that if true
1123                         // the exception would be thrown.
1124                     }
1125                     return null;
1126                 }
1127             }, acc);
1128         }
1129 
1130         /*
1131          * Coerce the array of class types provided into one which
1132          * looks the way the Reflection APIs expect.  This is done
1133          * by substituting primitive types for their Object counterparts,
1134          * and superclasses for subclasses used to add the
1135          * <code>UIResource</code> tag.
1136          */
1137         private Class[] getClassArray(Object[] args) {
1138             Class[] types = null;
1139             if (args!=null) {
1140                 types = new Class[args.length];
1141                 for (int i = 0; i< args.length; i++) {
1142                     /* PENDING(ges): At present only the primitive types
1143                        used are handled correctly; this should eventually
1144                        handle all primitive types */
1145                     if (args[i] instanceof java.lang.Integer) {
1146                         types[i]=Integer.TYPE;
1147                     } else if (args[i] instanceof java.lang.Boolean) {
1148                         types[i]=Boolean.TYPE;
1149                     } else if (args[i] instanceof javax.swing.plaf.ColorUIResource) {
1150                         /* PENDING(ges) Currently the Reflection APIs do not
1151                            search superclasses of parameters supplied for
1152                            constructor/method lookup.  Since we only have
1153                            one case where this is needed, we substitute
1154                            directly instead of adding a massive amount
1155                            of mechanism for this.  Eventually this will
1156                            probably need to handle the general case as well.
1157                            */
1158                         types[i]=java.awt.Color.class;
1159                     } else {
1160                         types[i]=args[i].getClass();




 294     }
 295 
 296     /**
 297      * Returns a Map of the known resources for the given locale.
 298      */
 299     private Map<String, Object> getResourceCache(Locale l) {
 300         Map<String, Object> values = resourceCache.get(l);
 301 
 302         if (values == null) {
 303             values = new TextAndMnemonicHashMap();
 304             for (int i=resourceBundles.size()-1; i >= 0; i--) {
 305                 String bundleName = resourceBundles.get(i);
 306                 try {
 307                     Control c = CoreResourceBundleControl.getRBControlInstance(bundleName);
 308                     ResourceBundle b;
 309                     if (c != null) {
 310                         b = ResourceBundle.getBundle(bundleName, l, c);
 311                     } else {
 312                         b = ResourceBundle.getBundle(bundleName, l);
 313                     }
 314                     Enumeration<String> keys = b.getKeys();
 315 
 316                     while (keys.hasMoreElements()) {
 317                         String key = keys.nextElement();
 318 
 319                         if (values.get(key) == null) {
 320                             Object value = b.getObject(key);
 321 
 322                             values.put(key, value);
 323                         }
 324                     }
 325                 } catch( MissingResourceException mre ) {
 326                     // Keep looking
 327                 }
 328             }
 329             resourceCache.put(l, values);
 330         }
 331         return values;
 332     }
 333 
 334     /**
 335      * Sets the value of <code>key</code> to <code>value</code> for all locales.
 336      * If <code>key</code> is a string and the new value isn't
 337      * equal to the old one, fire a <code>PropertyChangeEvent</code>.


 665      * <p>
 666      * If a mapping for <code>uiClassID</code> exists or if the specified
 667      * class can't be found, return <code>null</code>.
 668      * <p>
 669      * This method is used by <code>getUI</code>, it's usually
 670      * not necessary to call it directly.
 671      *
 672      * @param uiClassID  a string containing the class ID
 673      * @param uiClassLoader the object which will load the class
 674      * @return the value of <code>Class.forName(get(uidClassID))</code>
 675      * @see #getUI
 676      */
 677     public Class<? extends ComponentUI>
 678         getUIClass(String uiClassID, ClassLoader uiClassLoader)
 679     {
 680         try {
 681             String className = (String)get(uiClassID);
 682             if (className != null) {
 683                 ReflectUtil.checkPackageAccess(className);
 684 
 685                 Class<?> cls = (Class)get(className);
 686                 if (cls == null) {
 687                     if (uiClassLoader == null) {
 688                         cls = SwingUtilities.loadSystemClass(className);
 689                     }
 690                     else {
 691                         cls = uiClassLoader.loadClass(className);
 692                     }
 693                     if (cls != null) {
 694                         // Save lookup for future use, as forName is slow.
 695                         put(className, cls);
 696                     }
 697                 }
 698                 @SuppressWarnings("unchecked")
 699                 Class<? extends ComponentUI> tmp = (Class<? extends ComponentUI>)cls;
 700                 return tmp;
 701             }
 702         }
 703         catch (ClassNotFoundException | ClassCastException e) {



 704             return null;
 705         }
 706         return null;
 707     }
 708 
 709 
 710     /**
 711      * Returns the L&amp;F class that renders this component.
 712      *
 713      * @param uiClassID a string containing the class ID
 714      * @return the Class object returned by
 715      *          <code>getUIClass(uiClassID, null)</code>
 716      */
 717     public Class<? extends ComponentUI> getUIClass(String uiClassID) {
 718         return getUIClass(uiClassID, null);
 719     }
 720 
 721 
 722     /**
 723      * If <code>getUI()</code> fails for any reason,


 749      * method to construct a look and feel delegate.
 750      * </ul>
 751      * @param target  the <code>JComponent</code> which needs a UI
 752      * @return the <code>ComponentUI</code> object
 753      */
 754     public ComponentUI getUI(JComponent target) {
 755 
 756         Object cl = get("ClassLoader");
 757         ClassLoader uiClassLoader =
 758             (cl != null) ? (ClassLoader)cl : target.getClass().getClassLoader();
 759         Class<? extends ComponentUI> uiClass = getUIClass(target.getUIClassID(), uiClassLoader);
 760         Object uiObject = null;
 761 
 762         if (uiClass == null) {
 763             getUIError("no ComponentUI class for: " + target);
 764         }
 765         else {
 766             try {
 767                 Method m = (Method)get(uiClass);
 768                 if (m == null) {
 769                     m = uiClass.getMethod("createUI", new Class<?>[]{JComponent.class});
 770                     put(uiClass, m);
 771                 }
 772                 uiObject = MethodUtil.invoke(m, null, new Object[]{target});
 773             }
 774             catch (NoSuchMethodException e) {
 775                 getUIError("static createUI() method not found in " + uiClass);
 776             }
 777             catch (Exception e) {
 778                 getUIError("createUI() failed for " + target + " " + e);
 779             }
 780         }
 781 
 782         return (ComponentUI)uiObject;
 783     }
 784 
 785     /**
 786      * Adds a <code>PropertyChangeListener</code> to the listener list.
 787      * The listener is registered for all properties.
 788      * <p>
 789      * A <code>PropertyChangeEvent</code> will get fired whenever a default


1088             }
1089             return AccessController.doPrivileged(new PrivilegedAction<Object>() {
1090                 public Object run() {
1091                     try {
1092                         Class<?> c;
1093                         Object cl;
1094                         // See if we should use a separate ClassLoader
1095                         if (table == null || !((cl = table.get("ClassLoader"))
1096                                                instanceof ClassLoader)) {
1097                             cl = Thread.currentThread().
1098                                         getContextClassLoader();
1099                             if (cl == null) {
1100                                 // Fallback to the system class loader.
1101                                 cl = ClassLoader.getSystemClassLoader();
1102                             }
1103                         }
1104                         ReflectUtil.checkPackageAccess(className);
1105                         c = Class.forName(className, true, (ClassLoader)cl);
1106                         SwingUtilities2.checkAccess(c.getModifiers());
1107                         if (methodName != null) {
1108                             Class<?>[] types = getClassArray(args);
1109                             Method m = c.getMethod(methodName, types);
1110                             return MethodUtil.invoke(m, c, args);
1111                         } else {
1112                             Class<?>[] types = getClassArray(args);
1113                             Constructor<?> constructor = c.getConstructor(types);
1114                             SwingUtilities2.checkAccess(constructor.getModifiers());
1115                             return constructor.newInstance(args);
1116                         }
1117                     } catch(Exception e) {
1118                         // Ideally we would throw an exception, unfortunately
1119                         // often times there are errors as an initial look and
1120                         // feel is loaded before one can be switched. Perhaps a
1121                         // flag should be added for debugging, so that if true
1122                         // the exception would be thrown.
1123                     }
1124                     return null;
1125                 }
1126             }, acc);
1127         }
1128 
1129         /*
1130          * Coerce the array of class types provided into one which
1131          * looks the way the Reflection APIs expect.  This is done
1132          * by substituting primitive types for their Object counterparts,
1133          * and superclasses for subclasses used to add the
1134          * <code>UIResource</code> tag.
1135          */
1136         private Class<?>[] getClassArray(Object[] args) {
1137             Class<?>[] types = null;
1138             if (args!=null) {
1139                 types = new Class<?>[args.length];
1140                 for (int i = 0; i< args.length; i++) {
1141                     /* PENDING(ges): At present only the primitive types
1142                        used are handled correctly; this should eventually
1143                        handle all primitive types */
1144                     if (args[i] instanceof java.lang.Integer) {
1145                         types[i]=Integer.TYPE;
1146                     } else if (args[i] instanceof java.lang.Boolean) {
1147                         types[i]=Boolean.TYPE;
1148                     } else if (args[i] instanceof javax.swing.plaf.ColorUIResource) {
1149                         /* PENDING(ges) Currently the Reflection APIs do not
1150                            search superclasses of parameters supplied for
1151                            constructor/method lookup.  Since we only have
1152                            one case where this is needed, we substitute
1153                            directly instead of adding a massive amount
1154                            of mechanism for this.  Eventually this will
1155                            probably need to handle the general case as well.
1156                            */
1157                         types[i]=java.awt.Color.class;
1158                     } else {
1159                         types[i]=args[i].getClass();