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&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&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();
|