EMF+GEF的属性页问题

最近有朋友问使用EMF作为GEF模型时,如何在选中editpart时在属性页里显示属性的问题。是的,因为GEF是这样判断是否填充属性 页的:

public  Object getAdapter(Class key) {
    
if  (IPropertySource. class   ==  key) {
        
if  (getModel()  instanceof  IPropertySource)
            
return  getModel();
        
if  (getModel()  instanceof  IAdaptable)
            
return  ((IAdaptable)getModel()).getAdapter(key);
    }
    
if  (AccessibleEditPart. class   ==  key)
        
return  getAccessibleEditPart();
    
return   null ;
}

所以,一般(不使用EMF)我们让模型类实现IPropertySource接口即可看到属性。而用EMF生成的模型类是不实现这个接口的,因此用户在界面上选中 editpart时属性页里只能是空白。

要解决这个问题,一种方式是覆盖editpart的getAdapter()方法,返回一个自定义的PropertySource, 这个办法比较直接,但那么多属性写起来很麻烦,更重要的是当ecore模型改变后这些属性是不会跟着变的;另一种方式是在editor类里作文章,工作量 比较小,具体办法如下:

ModelItemProviderAdapterFactory adapterFactory;
AdapterFactoryContentProvider adapterFactoryConentProvider;

// Constructor of the editor
public  TobeEditor() {
    setEditDomain(
new  DefaultEditDomain( this ));
    
// For getting propertysource from emf.edit
    adapterFactory  =   new  ModelItemProviderAdapterFactory();
    adapterFactoryConentProvider 
=   new  AdapterFactoryContentProvider(adapterFactory);
}

public  Object getAdapter(Class type) {
    
if  (type  ==  IContentOutlinePage. class )
        
return   new  OutlinePage();
    
if  (type  ==  org.eclipse.ui.views.properties.IPropertySheetPage. class ) {
        PropertySheetPage page 
=   new  PropertySheetPage();
        UndoablePropertySheetEntry root 
=   new  UndoablePropertySheetEntry(getCommandStack());
        root.setPropertySourceProvider(
new  IPropertySourceProvider() {
            
public  IPropertySource getPropertySource(Object object) {
                
if  (object  instanceof  EditPart) {
                    Object model 
=  ((EditPart) object).getModel();
                    
return   new  PropertySource(model, (IItemPropertySource) adapterFactory.adapt(model,
                            IItemPropertySource.
class ));
                } 
else  {
                    
return  adapterFactoryConentProvider.getPropertySource(object);
                }
            }
        });
        page.setRootEntry(root);
        
return  page;
    }
    
return   super .getAdapter(type);
}

也就是对UndoablePropertySheetEntry做一些处理,让它能够适应editpart的选择(GEF里选中元素的都是 editpart而非model本身)。这个方法在显示属性方面没有什么问题,但在属性页里修改属性值后,是不能undo的,而且不会显示表示dirty 的*号,所以还有待改进。

EMF+GEF里像这种别扭的地方还远不只这一处,不过我相信大部分都是可以适当修改一些代码解决的,希望它们之间增加一些合作,同时继续期待GMF

你可能感兴趣的:(gef)