Home » openjdk-7 » sun » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.swing;
   27   
   28   import java.beans;
   29   import java.lang.reflect.Method;
   30   
   31   public class BeanInfoUtils
   32   {
   33       /* The values of these createPropertyDescriptor() and
   34        * createBeanDescriptor() keywords are the names of the
   35        * properties they're used to set.
   36        */
   37       public static final String BOUND = "bound";
   38       public static final String CONSTRAINED = "constrained";
   39       public static final String PROPERTYEDITORCLASS = "propertyEditorClass";
   40       public static final String READMETHOD = "readMethod";
   41       public static final String WRITEMETHOD = "writeMethod";
   42       public static final String DISPLAYNAME = "displayName";
   43       public static final String EXPERT = "expert";
   44       public static final String HIDDEN = "hidden";
   45       public static final String PREFERRED = "preferred";
   46       public static final String SHORTDESCRIPTION = "shortDescription";
   47       public static final String CUSTOMIZERCLASS = "customizerClass";
   48   
   49       static private void initFeatureDescriptor(FeatureDescriptor fd, String key, Object value)
   50       {
   51           if (DISPLAYNAME.equals(key)) {
   52               fd.setDisplayName((String)value);
   53           }
   54   
   55           if (EXPERT.equals(key)) {
   56               fd.setExpert(((Boolean)value).booleanValue());
   57           }
   58   
   59           if (HIDDEN.equals(key)) {
   60               fd.setHidden(((Boolean)value).booleanValue());
   61           }
   62   
   63           if (PREFERRED.equals(key)) {
   64               fd.setPreferred(((Boolean)value).booleanValue());
   65           }
   66   
   67           else if (SHORTDESCRIPTION.equals(key)) {
   68               fd.setShortDescription((String)value);
   69           }
   70   
   71           /* Otherwise assume that we have an arbitrary FeatureDescriptor
   72            * "attribute".
   73            */
   74           else {
   75               fd.setValue(key, value);
   76           }
   77       }
   78   
   79       /**
   80        * Create a beans PropertyDescriptor given an of keyword/value
   81        * arguments.  The following sample call shows all of the supported
   82        * keywords:
   83        *<pre>
   84        *      createPropertyDescriptor("contentPane", new Object[] {
   85        *                     BOUND, Boolean.TRUE,
   86        *               CONSTRAINED, Boolean.TRUE,
   87        *       PROPERTYEDITORCLASS, package.MyEditor.class,
   88        *                READMETHOD, "getContentPane",
   89        *               WRITEMETHOD, "setContentPane",
   90        *               DISPLAYNAME, "contentPane",
   91        *                    EXPERT, Boolean.FALSE,
   92        *                    HIDDEN, Boolean.FALSE,
   93        *                 PREFERRED, Boolean.TRUE,
   94        *          SHORTDESCRIPTION, "A top level window with a window manager border",
   95        *         "random attribute","random object value"
   96        *        }
   97        *     );
   98        * </pre>
   99        * The keywords correspond to <code>java.beans.PropertyDescriptor</code> and
  100        * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
  101        * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
  102        * Using createPropertyDescriptor instead of the PropertyDescriptor
  103        * constructor and set methods is preferrable in that it regularizes
  104        * the code in a <code>java.beans.BeanInfo.getPropertyDescriptors()</code>
  105        * method implementation.  One can use <code>createPropertyDescriptor</code>
  106        * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
  107        * "random object value".
  108        * <p>
  109        * All properties should provide a reasonable value for the
  110        * <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
  111        * to <code>Boolean.TRUE</code> if neccessary.  The remaining keywords
  112        * are optional.  There's no need to provide values for keywords like
  113        * READMETHOD if the correct value can be computed, i.e. if the properties
  114        * get/is method follows the standard beans pattern.
  115        * <p>
  116        * The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
  117        * It's still worth setting it to true for properties that are most
  118        * likely to be interested to the average developer, e.g. AbstractButton.title
  119        * is a preferred property, AbstractButton.focusPainted is not.
  120        *
  121        * @see java.beans#BeanInfo
  122        * @see java.beans#PropertyDescriptor
  123        * @see java.beans#FeatureDescriptor
  124        */
  125       public static PropertyDescriptor createPropertyDescriptor(Class cls, String name, Object[] args)
  126       {
  127           PropertyDescriptor pd = null;
  128           try {
  129               pd = new PropertyDescriptor(name, cls);
  130           } catch (IntrospectionException e) {
  131               // Try creating a read-only property, in case setter isn't defined.
  132               try {
  133                   pd = createReadOnlyPropertyDescriptor(name, cls);
  134               } catch (IntrospectionException ie) {
  135                   throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
  136               }
  137           }
  138   
  139           for(int i = 0; i < args.length; i += 2) {
  140               String key = (String)args[i];
  141               Object value = args[i + 1];
  142   
  143               if (BOUND.equals(key)) {
  144                   pd.setBound(((Boolean)value).booleanValue());
  145               }
  146   
  147               else if (CONSTRAINED.equals(key)) {
  148                   pd.setConstrained(((Boolean)value).booleanValue());
  149               }
  150   
  151               else if (PROPERTYEDITORCLASS.equals(key)) {
  152                   pd.setPropertyEditorClass((Class)value);
  153               }
  154   
  155               else if (READMETHOD.equals(key)) {
  156                   String methodName = (String)value;
  157                   Method method;
  158                   try {
  159                       method = cls.getMethod(methodName, new Class[0]);
  160                       pd.setReadMethod(method);
  161                   }
  162                   catch(Exception e) {
  163                       throwError(e, cls + " no such method as \"" + methodName + "\"");
  164                   }
  165               }
  166   
  167               else if (WRITEMETHOD.equals(key)) {
  168                   String methodName = (String)value;
  169                   Method method;
  170                   try {
  171                       Class type = pd.getPropertyType();
  172                       method = cls.getMethod(methodName, new Class[]{type});
  173                       pd.setWriteMethod(method);
  174                   }
  175                   catch(Exception e) {
  176                       throwError(e, cls + " no such method as \"" + methodName + "\"");
  177                   }
  178               }
  179   
  180               else {
  181                   initFeatureDescriptor(pd, key, value);
  182               }
  183           }
  184   
  185           return pd;
  186       }
  187   
  188   
  189       /**
  190        * Create a BeanDescriptor object given an of keyword/value
  191        * arguments.  The following sample call shows all of the supported
  192        * keywords:
  193        *<pre>
  194        *      createBeanDescriptor(JWindow..class, new Object[] {
  195        *           CUSTOMIZERCLASS, package.MyCustomizer.class,
  196        *               DISPLAYNAME, "JFrame",
  197        *                    EXPERT, Boolean.FALSE,
  198        *                    HIDDEN, Boolean.FALSE,
  199        *                 PREFERRED, Boolean.TRUE,
  200        *          SHORTDESCRIPTION, "A top level window with a window manager border",
  201        *         "random attribute","random object value"
  202        *        }
  203        *     );
  204        * </pre>
  205        * The keywords correspond to <code>java.beans.BeanDescriptor</code> and
  206        * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
  207        * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
  208        * Using createBeanDescriptor instead of the BeanDescriptor
  209        * constructor and set methods is preferrable in that it regularizes
  210        * the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
  211        * method implementation.  One can use <code>createBeanDescriptor</code>
  212        * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
  213        * "random object value".
  214        *
  215        * @see java.beans#BeanInfo
  216        * @see java.beans#PropertyDescriptor
  217        */
  218       public static BeanDescriptor createBeanDescriptor(Class cls, Object[] args)
  219       {
  220           Class customizerClass = null;
  221   
  222           /* For reasons I don't understand, customizerClass is a
  223            * readOnly property.  So we have to find it and pass it
  224            * to the constructor here.
  225            */
  226           for(int i = 0; i < args.length; i += 2) {
  227               if (CUSTOMIZERCLASS.equals((String)args[i])) {
  228                   customizerClass = (Class)args[i + 1];
  229                   break;
  230               }
  231           }
  232   
  233           BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
  234   
  235           for(int i = 0; i < args.length; i += 2) {
  236               String key = (String)args[i];
  237               Object value = args[i + 1];
  238               initFeatureDescriptor(bd, key, value);
  239           }
  240   
  241           return bd;
  242       }
  243   
  244       static private PropertyDescriptor createReadOnlyPropertyDescriptor(
  245           String name, Class cls) throws IntrospectionException {
  246   
  247           Method readMethod = null;
  248           String base = capitalize(name);
  249           Class[] parameters = new Class[0];
  250   
  251           // Is it a boolean?
  252           try {
  253               readMethod = cls.getMethod("is" + base, parameters);
  254           } catch (Exception ex) {}
  255           if (readMethod == null) {
  256               try {
  257                   // Try normal accessor pattern.
  258                   readMethod = cls.getMethod("get" + base, parameters);
  259               } catch (Exception ex2) {}
  260           }
  261           if (readMethod != null) {
  262               return new PropertyDescriptor(name, readMethod, null);
  263           }
  264   
  265           try {
  266               // Try indexed accessor pattern.
  267               parameters = new Class[1];
  268               parameters[0] = int.class;
  269               readMethod = cls.getMethod("get" + base, parameters);
  270           } catch (NoSuchMethodException nsme) {
  271               throw new IntrospectionException(
  272                   "cannot find accessor method for " + name + " property.");
  273           }
  274           return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
  275       }
  276   
  277       // Modified methods from java.beans.Introspector
  278       private static String capitalize(String s) {
  279           if (s.length() == 0) {
  280               return s;
  281           }
  282           char chars[] = s.toCharArray();
  283           chars[0] = Character.toUpperCase(chars[0]);
  284           return new String(chars);
  285       }
  286   
  287       /**
  288        * Fatal errors are handled by calling this method.
  289        */
  290       public static void throwError(Exception e, String s) {
  291           throw new Error(e.toString() + " " + s);
  292       }
  293   }

Home » openjdk-7 » sun » swing » [javadoc | source]