1 将viewer作为内容提供者(需要实现ISelectionProvider,JFace所有的查看器类都实现了该接口),在Aressview中添加以下代码
getViewSite().setSelectionProvider(viewer);
若Action是通过扩展点生产,为了使Action的enablefor属性起作用,必须也要设置以上语句。
由于属性实体仅能理解实现IPropertySource的对象,为了对属性页提供支持,元素AdressItem必须实现IPropertySource,但有更好的方法,是实现IAdaptable接口,其允许将不理解的对象转换为可以理解的对象,此处将一个AddressItem对象转化为一个IPropertySource对象。
public class AddressItem implements IAdaptable{
//...
//为属性视图提供支持
public Object getAdapter(Class adapter) {
if(adapter == IPropertySource.class)
return new AddressItemPropertySource(this);
return null;
}
}
AddressItemPropertySource是一个将AdressItem转换为 IPropertySource的类
public class AddressItemPropertySource implements IPropertySource {
protected AddressItem addressItem;
protected static final String PROPERTY_CATEGORY = "com.plugindev.addressbook.properties.category";
protected static final String PROPERTY_NAME = "com.plugindev.addressbook.properties.name";
private String[] categoryNames;
private int property;
private String name;
private ComboBoxPropertyDescriptor categoryPropertyDescriptor;
private TextPropertyDescriptor namePropertyDescriptor;
public AddressItemPropertySource(AddressItem item)
{
super();
this.addressItem = item;
initProperties();
}
private void initProperties(){
if(categoryNames == null)
{
categoryNames = new String[9];
AddressCategory[] categories = AddressCategory.getTypes();
for(int i = 0; i < categories.length; i++)
categoryNames[i] = categories[i].getCategoryName();
}
for(int i = 0; i < categoryNames.length; i++)
{
if(categoryNames[i].equals(addressItem.getCategory().getCategoryName()))
property = i;
}
name = addressItem.getName();
}
public Object getEditableValue() {
return addressItem;
}
public IPropertyDescriptor[] getPropertyDescriptors() {
categoryPropertyDescriptor = new ComboBoxPropertyDescriptor(PROPERTY_CATEGORY,
"类别", categoryNames);
categoryPropertyDescriptor.setLabelProvider(new LabelProvider(){
public String getText(Object element){
Integer item = (Integer)element;
return categoryNames[item.intValue()];
}});
categoryPropertyDescriptor.setCategory("地址元素信息");
namePropertyDescriptor = new TextPropertyDescriptor(PROPERTY_NAME,"姓名");
namePropertyDescriptor.setLabelProvider(new LabelProvider(){
public String getText(Object element){
return (String)element;
}
});
namePropertyDescriptor.setCategory("地址元素信息");
return new IPropertyDescriptor[]{categoryPropertyDescriptor, namePropertyDescriptor};
}
public Object getPropertyValue(Object id) {
if(id.equals(PROPERTY_CATEGORY))
return new Integer(property);
if(id.equals(PROPERTY_NAME))
return name;
return null;
}
public boolean isPropertySet(Object id) {
return false;
}
public void resetPropertyValue(Object id) {
}
public void setPropertyValue(Object id, Object value) {
hookPropertyChanged(id, value);
if(id.equals(PROPERTY_CATEGORY))
property = ((Integer)value).intValue();
if(id.equals(PROPERTY_NAME))
name = (String)value;
}
//属性改变之后,激活propertychange事件
public void hookPropertyChanged(Object id,Object newValue){
if(id.equals(PROPERTY_CATEGORY))
{
addressItem.setCategory(AddressCategory.getCategoryMap().
get(categoryNames[((Integer)newValue).intValue()]));
AddressManager.getManager().propertyChange(new PropertyChangeEvent(
this.addressItem, "Category", property,newValue));
}
else if(id.equals(PROPERTY_NAME)){
addressItem.setName((String)newValue);
AddressManager.getManager().propertyChange(new PropertyChangeEvent(
this.addressItem, "Name", name, newValue));
}
}
}
其中用到了属性描述器,系统定义的属性描述器有ComboBoxPropertyDescription,TextPropertyDescription,ColorPropertyDescripter。
3属性页中可以对模型进行修改,为了使模型能及时知道属性改变,并更新模型,模型需要支持属性改变事件监听,修改代码如下:
public class AddressManager implements IPropertyChangeListener{
//...
public void propertyChange(PropertyChangeEvent event) {
//响应属性页属性改变事件,产生地址改变事件
fireAddressesChanged(AddressItem.NONE, AddressItem.NONE,
new AddressItem[]{(AddressItem)event.getSource()});
}
}