八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  232 随笔 :: 0 文章 :: 3000 评论 :: 11 Trackbacks

最近有朋友问使用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

posted on 2005-10-24 21:34 八进制 阅读(3691) 评论(24)  编辑 收藏 所属分类: EclipseGEF

评论

#1楼  2005-10-31 14:47 ak [未注册用户]
ModelItemProviderAdapterFactory在哪个包中?
  回复  引用    

#2楼 [楼主] 2005-10-31 15:47 八进制      
ModelItemProviderAdapterFactory是EMF帮你生成的,名字根据你genmodel也可能是XYZItemProviderAdapterFactory,在.edit项目里
  回复  引用  查看    

#3楼  2005-11-02 16:20 probing [未注册用户]
想请教一下:怎么对GEF项目进行单元测试呢?
  回复  引用    

#4楼  2005-11-03 16:46 yyqq [未注册用户]
你好,我想请教一个问题。
现在我需要定制模型的属性页,使之象VS.net中属性页一样在两个页面区分显示两类属性,我应该怎么做呢?
  回复  引用    

#5楼 [楼主] 2005-11-03 17:14 八进制      
probing: 这方面我不太了解,抱歉。
yyqq: 恐怕要对propertysheet做一些修改,标准的属性页应该不支持。或者用自己的视图实现一个类似功能的属性页。
  回复  引用  查看    

yyqq:对于你的问题,我个人认为应该重写以个继承PropertySheet的子类,在里面构造两个PropertySheetPage
  回复  引用    

#7楼  2005-11-08 16:41 张贤伟 [未注册用户]
我有一段model-xml代码:
<struts-config>
<action path="/action1" type="">
<forward name="forward2" path="/page1.jsp"/>
</action>
</struts-config>

如何实现当我把鼠标光标放在action上时,在属性栏里面列出action的属性列表????
  回复  引用    

#8楼  2005-11-09 15:32 fuyuhui [未注册用户]
你好,我希望把节点变成圆形,在你的程序基础上,把NODEFIGURE中的RETANGLE换成了ELLIPSE,但是外面还是有一个矩形框架,为什么?多谢
  回复  引用    

#9楼 [楼主] 2005-11-09 19:02 八进制      
是不是表示选择的矩形框?缺省是矩形,如果需要改形状要做一些修改,这个矩形是一个MoveHandle。
  回复  引用  查看    

#10楼  2005-11-10 11:18 brack [未注册用户]
看了你的blog觉得非常好,我有一个问题也请教一下,如何利用EMF生成的属性页代码使一个GEF上的EditPart可以显示树形结构的属性页?因为有的model的属性EMF并不生成折叠的属性页,你只有在它生成的editor的树形editor点选才能看得到子属性的属性。如何在GEF中点击一个editpart就将其全部属性都以树形结构显示在属性页中呢?谢谢。
  回复  引用    

#11楼  2005-11-10 13:33 fuyuhui [未注册用户]
非常感谢老兄的帮忙,是我犯了一个低级错误,继承的是RECTANGLE,改成ELLIPSE就好了
还有个问题,我的节点很小,另外做了一个继承LABEL的MODEL来放置节点的名字,定位的时候,需要计算LABEL的长度来定位这个LABEL,没有找到合适的方法.当初在SWT里用GC的GETCHARWIDTH来算字体宽度的时候就不准,老兄有什么高招吗,
  回复  引用    

#12楼 [楼主] 2005-11-10 13:38 八进制      
不知道我理解的对不对,你希望选一个editpart时在属性页里显示它的所有子孙editpart的属性?EMF的genmodel里可以指定属性的分类(category),但你这个需求显然比较复杂,用现有的属性页无法很好的实现,或者把子editpart的属性以某种方式转换为父editpart的某个属性,以特定格式的字符串展示,不过这样只能是只读的……除了自己扩展属性页,没有想到更好的方法。
  回复  引用  查看    

#13楼  2005-11-10 14:15 brack [未注册用户]
嗯举个例子就是这样的,我一个model四个属性,id,name,(都为string),position(Point类),size(Dimension类),emf生成属性页的时候,id,name都生成出来了,支持的很好,但是posion里的x,y,size里的width,length也生成出来了,也不错,但就是你必须选中posion这个属性节点(这在GEF中是无法办到的,只在在EMF生成的树形editor中才能实现) 才能在属性页中显示x,y.
我现在就想选中一个model,然后属性页中是如下结构:

id
name
+position
--x
--y
+size
--width
--lenth

真的没有办法吗??很急啊。。。能否修改修改emf生成的属性页的代码呢?

  回复  引用    

#14楼  2005-11-10 15:08 张贤伟 [未注册用户]
多谢八进制!是我问得不清楚

action和forward都是像node一样的控件,我用来做流程图的
name和path是action的属性
我想实现的是:如果我把光标放在action这一行的时候,能够在属性列里面列出来属性name和path及属性值。就像jbuilder里面似的,不知道这个过程是怎么样的?



  回复  引用    

#15楼  2005-11-11 16:29 yyqq [未注册用户]
关于分页属性页,我已试验出来了。
只需派生个PropertySheetPage的子类 A ,重载createControl函数,并在Editor的getAdapter中返回 A 类的实例即可。为区分两种属性,可派生一个IPropertySource的子接口,加入获得/设置第二种属性的接口方法,使各Model实现该接口,这样在子类 A 中就能获得两种属性并显示了

这两天忙其他事情,今天才来看回复,又作了点代码试验。希望这个结果可以作为对八进制精彩文章的一点点回报吧;)

感谢八进制和IntoTheRain 的回复!期待更多更精彩的文章
  回复  引用    

#16楼 [楼主] 2005-11-11 20:49 八进制      
张贤伟:不太确定你的问题,不过好像和emf没有关系;
yyqq:在emf的genmodel里,选中x,y属性,将它们的property category设置为"size",这样好像也能实现你的需求。
fuyuhui:我以前就是用这个方法算的。

(麻烦各位尽量使用一致的id评论)
  回复  引用  查看    

#17楼  2006-03-06 13:51 幽幽西山      
请问属性页里面的属性显示顺序如何自己制定,默认的好像是按照字母顺序显示,现在需要根据优先级显示,请帮忙!谢谢!
  回复  引用  查看    

#18楼  2007-07-05 21:31 Enoch [未注册用户]
AdapterFactoryContentProvider这个是在哪个包里啊?
我的.edit里面没这个类。
请高手指导
  回复  引用    

#19楼 [楼主] 2007-07-05 23:56 八进制      
在org.eclipse.emf.edit.ui插件里,全名是org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider
  回复  引用  查看    

#20楼  2007-07-06 10:13 Enoch [未注册用户]
谢谢八进制。我已经搞好了。
把代码加上以后有一个问题,画一个结点的时候,出现这样的错误。
Unhandled event loop exception
Reason:
loader constraints violated when linking org/eclipse/draw2d/geometry/Rectangle class

  回复  引用    

#21楼  2007-09-19 16:02 likui [未注册用户]
八进制你好!
我现在想改一个开源项目中属性视图中的属性名称(就是TableViewer第一列的名称),它的名称是在一个插件配置文件中设定的,属性名称的类型是Eattribute类型。我现在想不用插件配置文件而是自己设定其名称,让属性名称是动态从数据库获取的,请教一下有什么好的办法吗?
  回复  引用    

#22楼  2008-07-25 15:49 Wsea [未注册用户]
我现在正在做一个EMF和GEF的东西,在实现属性页上遇到了一些问题。请问有关于这个的一个简单的例子吗,如果有能发给我一下吗 ,,谢谢~~~小弟急求啊。(wjq.td@163.com)
  回复  引用    

#23楼 [楼主] 2008-08-06 20:39 八进制      
@Wsea
试试这个例子:http://bjzhanghao.cnblogs.com/Files/bjzhanghao/emfsubject.zip
  回复  引用  查看    

#24楼 [楼主] 2008-08-06 20:40 八进制      
@likui
既然是开源的,你只要找到它原来读取配置文件的地方,改为从数据库读取,就可以了吧。
  回复  引用  查看