我想为我的 Java Bean 创建一个属性编辑器。为此,我需要一个实现 BeanInfo 的类.问题:我真的不喜欢像这样将属性名称声明为字符串(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。对类的属性名称的某种注释支持?
非常感谢您的专业知识!
最佳答案
我尝试使用自定义注释,它似乎有效。至少它现在是类型安全的并且与字段耦合。
代码
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;
}
}
描述符.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 "";
}
属性.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;
}
}
主.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 和属性描述符。
如果谁有更好的方法,请告诉我。
关于java - 你如何在 2016 年创建一个 SimpleBeanInfo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35987076/