你如何在 2016 年创建一个 SimpleBeanInfo?

How do you create a SimpleBeanInfo in the year 2016?

我想为我的 Java Beans 创建一个 属性 编辑器。为此,我需要一个实现 BeanInfo 的 class。问题:我真的不喜欢像这样将属性名称声明为 String (floodColor, fillColor, percent):

import java.beans.*;
public class BarChartBeanBeanInfo extends SimpleBeanInfo
{
    private final static Class myClass = BarChartBean.class;

    public PropertyDescriptor[] getPropertyDescriptors()
    {
        try {
            PropertyDescriptor flc = new PropertyDescriptor("floodColor", myClass);
            PropertyDescriptor fic = new PropertyDescriptor("fillColor", myClass);
            PropertyDescriptor pct = new PropertyDescriptor("percent", myClass);

            PropertyDescriptor[] list = { flc, fic, pct };
            return list;
        }
        catch (IntrospectionException iexErr)
        {
            throw new Error(iexErr.toString());
        }
    }

};

我从一篇关于如何创建自定义 属性 编辑器的示例文章中得到了这个:The trick to controlling bean customization。这篇文章是1997年的。

如何在 2016 年创建一个 属性 编辑器而不使用变量的字符串声明,一旦有人更改变量名称显然会导致运行时异常?

我的意思不是使用 Introspector。有没有e。 G。对 classes?

的属性名称的某种注释支持

非常感谢您的专业知识!

我尝试使用自定义注释,它似乎有效。至少它现在是类型安全的并且与字段耦合。

代码

ExampleBean.java

import annotations.Descriptor;
import annotations.Property;

@Descriptor(displayName = "Example Bean", shortDescription = "This is an example bean")
public class ExampleBean {

    @Property(displayName = "Integer Value", shortDescription = "This is an integer value")
    int integerValue;

    @Property(displayName = "Double Value", shortDescription = "This is a double value")
    double doubleValue;

    @Property(displayName = "String Value", shortDescription = "This is a string value")
    String stringValue;

    public int getIntegerValue() {
        return integerValue;
    }

    public void setIntegerValue(int integerValue) {
        this.integerValue = integerValue;
    }

    public double getDoubleValue() {
        return doubleValue;
    }

    public void setDoubleValue(double doubleValue) {
        this.doubleValue = doubleValue;
    }

    public String getStringValue() {
        return stringValue;
    }

    public void setStringValue(String stringValue) {
        this.stringValue = stringValue;
    }

}

Descriptor.java

package annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Descriptor {

    public String displayName() default "";

    public String shortDescription() default "";

}

Property.java

package annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface Property {

    public String displayName() default "";

    public String shortDescription() default "";

}

ExampleBeanBeanInfo.java

import java.beans.BeanDescriptor;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import annotations.Descriptor;
import annotations.Property;

public class ExampleBeanBeanInfo extends SimpleBeanInfo {

    private final static Class<ExampleBean> myClass = ExampleBean.class;

    public PropertyDescriptor[] getPropertyDescriptors() {

        List<PropertyDescriptor> propertyDescriptors = new ArrayList<>();

        try {

            for (Field field : myClass.getDeclaredFields()) {

                if (field.isAnnotationPresent(Property.class)) {

                    Annotation annotation = field.getAnnotation(Property.class);
                    Property property = (Property) annotation;

                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), myClass);
                    propertyDescriptor.setDisplayName(property.displayName());
                    propertyDescriptor.setShortDescription(property.shortDescription());

                    propertyDescriptors.add(propertyDescriptor);
                }

            }

            return propertyDescriptors.toArray(new PropertyDescriptor[propertyDescriptors.size()]);
        } catch (Exception iexErr) {
            throw new Error(iexErr.toString());
        }
    }

    public BeanDescriptor getBeanDescriptor() {
        BeanDescriptor desc = new BeanDescriptor(myClass);

        if (myClass.isAnnotationPresent(Descriptor.class)) {

            Annotation annotation = myClass.getAnnotation(Descriptor.class);
            Descriptor descriptor = (Descriptor) annotation;

            desc.setDisplayName(descriptor.displayName());
            desc.setShortDescription(descriptor.shortDescription());

        }

        return desc;
    }

}

Main.java

import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class Main {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, IntrospectionException {

        BeanInfo beanInfo = Introspector.getBeanInfo(ExampleBean.class);

        BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();

        System.out.printf( "Bean display name = '%s', description = '%s'\n", beanDescriptor.getDisplayName(), beanDescriptor.getShortDescription());

        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

            String propertyName = propertyDescriptor.getName();

            System.out.printf("Property field name = '%s', display name = '%s', description = '%s'\n", propertyName, propertyDescriptor.getDisplayName(), propertyDescriptor.getShortDescription());

        }

        System.exit(0);
        ;
    }
}

控制台输出:

Bean display name = 'Example Bean', description = 'This is an example bean'
Property field name = 'doubleValue', display name = 'Double Value', description = 'This is a double value'
Property field name = 'integerValue', display name = 'Integer Value', description = 'This is an integer value'
Property field name = 'stringValue', display name = 'String Value', description = 'This is a string value'

此示例公开了 displayname 和 shortdescription 方法,必须添加其他 bean 和 属性 描述符。

如果谁有更好的方法,请告诉我。