这一节主要介绍如何给编辑器增加属性页,属性页主要用来显示编辑器中选中对象的属性的,比如在编辑器选中活动,可以在属性页上显示活动的大小和位置等信息,要实现这一功能,首先要让模型实现IPropertySource接口,我们让模型的基类ModelElement实现这个接口,基类要实现这接口中六个方法,这六个方法如下:
/** */ /** An empty property descriptor. */
private static final IPropertyDescriptor[] EMPTY_ARRAY = new IPropertyDescriptor[ 0 ];
/** */ /**
* Returns a value for this property source that can be edited in a property sheet.
* @return this instance
*/
public Object getEditableValue() {
return this;
}
/** */ /**
* Children should override this. The default implementation returns an empty array.
*/
public IPropertyDescriptor[] getPropertyDescriptors() {
return EMPTY_ARRAY;
}
/** */ /**
* Children should override this. The default implementation returns null.
*/
public Object getPropertyValue(Object id) {
// TODO Auto-generated method stub
return null;
}
/** */ /**
* Children should override this. The default implementation returns false.
*/
public boolean isPropertySet(Object id) {
// TODO Auto-generated method stub
return false;
}
/** */ /**
* Children should override this. The default implementation does nothing.
*/
public void resetPropertyValue(Object id) {
// TODO Auto-generated method stub
}
/** */ /**
* Children should override this. The default implementation does nothing.
*/
public void setPropertyValue(Object id, Object value) {
// TODO Auto-generated method stub
}
这六个方法的含义在JavaDoc中已经说的很清楚了,在这个类中我们还定义了IPropertyDescriptor类型的数组,这个数组的作用是存放要显示属性的名称,由于根模型没有什么可显示的属性,所以为空。当我们在编辑器中选中活动时,在属性页上要显示它的属性,因此我们应该在AbstractActivity类中覆盖父类中相应的方法,代码如下:
/** */
/**
* 活动要显示属性的名称
* There is one IPropertyDescriptor entry per editable property.
* @see #getPropertyDescriptors()
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
private static IPropertyDescriptor[] descriptors;
/**/ /*
* Initializes the property descriptors array.
* @see #getPropertyDescriptors()
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
static {
descriptors = new IPropertyDescriptor[] {
new TextPropertyDescriptor(XPOS_PROP, "X"), // id and
description pair
new TextPropertyDescriptor(YPOS_PROP, "Y"),
new TextPropertyDescriptor(WIDTH_PROP, "Width"),
new TextPropertyDescriptor(HEIGHT_PROP, "Height")
};
// use a custom cell editor validator for all four array entries
for (int i = 0; i < descriptors.length; i++) {
((PropertyDescriptor) descriptors[i]).setValidator(new
ICellEditorValidator() {
public String isValid(Object value) {
int intValue = -1;
try {
intValue = Integer.parseInt((String)
value);
} catch (NumberFormatException exc) {
return "Not a number";
}
return (intValue >= 0) ? null : "Value must be >=
0";
}
});
}
} // static
/** */ /**
* Returns an array of IPropertyDescriptors for this AbstractActivity.
* <p>The returned array is used to fill the property view, when the edit-part
corresponding
* to this model element is selected.</p>
* @see #descriptors
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
public IPropertyDescriptor[] getPropertyDescriptors() {
return descriptors;
}
/** */ /**
* Return the property value for the given propertyId, or null.
* <p>The property view uses the IDs from the IPropertyDescriptors array
* to obtain the value of the corresponding properties.</p>
* @see #descriptors
* @see #getPropertyDescriptors()
*/
public Object getPropertyValue(Object propertyId) {
if (XPOS_PROP.equals(propertyId)) {
return Integer.toString(location.x);
}
if (YPOS_PROP.equals(propertyId)) {
return Integer.toString(location.y);
}
if (HEIGHT_PROP.equals(propertyId)) {
return Integer.toString(size.height);
}
if (WIDTH_PROP.equals(propertyId)) {
return Integer.toString(size.width);
}
return super.getPropertyValue(propertyId);
}
/** */ /**
* Set the property value for the given property id.
* If no matching id is found, the call is forwarded to the superclass.
* <p>The property view uses the IDs from the IPropertyDescriptors array to set the
values
* of the corresponding properties.</p>
*/
public void setPropertyValue(Object propertyId, Object value) {
if (XPOS_PROP.equals(propertyId)) {
int x = Integer.parseInt((String) value);
setLocation(new Point(x, location.y));
} else if (YPOS_PROP.equals(propertyId)) {
int y = Integer.parseInt((String) value);
setLocation(new Point(location.x, y));
} else if (HEIGHT_PROP.equals(propertyId)) {
int height = Integer.parseInt((String) value);
setSize(new Dimension(size.width, height));
} else if (WIDTH_PROP.equals(propertyId)) {
int width = Integer.parseInt((String) value);
setSize(new Dimension(width, size.height));
} else {
super.setPropertyValue(propertyId, value);
}
}
* 活动要显示属性的名称
* There is one IPropertyDescriptor entry per editable property.
* @see #getPropertyDescriptors()
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
private static IPropertyDescriptor[] descriptors;
/**/ /*
* Initializes the property descriptors array.
* @see #getPropertyDescriptors()
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
static {
descriptors = new IPropertyDescriptor[] {
new TextPropertyDescriptor(XPOS_PROP, "X"), // id and
description pair
new TextPropertyDescriptor(YPOS_PROP, "Y"),
new TextPropertyDescriptor(WIDTH_PROP, "Width"),
new TextPropertyDescriptor(HEIGHT_PROP, "Height")
};
// use a custom cell editor validator for all four array entries
for (int i = 0; i < descriptors.length; i++) {
((PropertyDescriptor) descriptors[i]).setValidator(new
ICellEditorValidator() {
public String isValid(Object value) {
int intValue = -1;
try {
intValue = Integer.parseInt((String)
value);
} catch (NumberFormatException exc) {
return "Not a number";
}
return (intValue >= 0) ? null : "Value must be >=
0";
}
});
}
} // static
/** */ /**
* Returns an array of IPropertyDescriptors for this AbstractActivity.
* <p>The returned array is used to fill the property view, when the edit-part
corresponding
* to this model element is selected.</p>
* @see #descriptors
* @see #getPropertyValue(Object)
* @see #setPropertyValue(Object, Object)
*/
public IPropertyDescriptor[] getPropertyDescriptors() {
return descriptors;
}
/** */ /**
* Return the property value for the given propertyId, or null.
* <p>The property view uses the IDs from the IPropertyDescriptors array
* to obtain the value of the corresponding properties.</p>
* @see #descriptors
* @see #getPropertyDescriptors()
*/
public Object getPropertyValue(Object propertyId) {
if (XPOS_PROP.equals(propertyId)) {
return Integer.toString(location.x);
}
if (YPOS_PROP.equals(propertyId)) {
return Integer.toString(location.y);
}
if (HEIGHT_PROP.equals(propertyId)) {
return Integer.toString(size.height);
}
if (WIDTH_PROP.equals(propertyId)) {
return Integer.toString(size.width);
}
return super.getPropertyValue(propertyId);
}
/** */ /**
* Set the property value for the given property id.
* If no matching id is found, the call is forwarded to the superclass.
* <p>The property view uses the IDs from the IPropertyDescriptors array to set the
values
* of the corresponding properties.</p>
*/
public void setPropertyValue(Object propertyId, Object value) {
if (XPOS_PROP.equals(propertyId)) {
int x = Integer.parseInt((String) value);
setLocation(new Point(x, location.y));
} else if (YPOS_PROP.equals(propertyId)) {
int y = Integer.parseInt((String) value);
setLocation(new Point(location.x, y));
} else if (HEIGHT_PROP.equals(propertyId)) {
int height = Integer.parseInt((String) value);
setSize(new Dimension(size.width, height));
} else if (WIDTH_PROP.equals(propertyId)) {
int width = Integer.parseInt((String) value);
setSize(new Dimension(width, size.height));
} else {
super.setPropertyValue(propertyId, value);
}
}
我们首先定义一个IPropertyDescriptor类型的数组,然后初始化这个数组,该数组存放要显示活动的属性,这里我们显示活动图形的坐标,大小属性,由于属性页既能显示属性,还能编辑属性,而坐标和大小属性只能输入数字,所以我们加入了校验,如果给这些属性输入字符,就抛异常。getPropertyValue方法就是得到IPropertyDescriptor数组中对应属性名的属性值,setPropertyValue方法就是对属性值进行修改时,要同时修改模型的属性,让模型通知控制器来刷新视图,例如我们修改坐标x的值,编辑器中活动
的位置就要发生改变,