浏览 3211 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-02-10
EMF.Edit里面有几个类比较绕,很容易被搞得晕头转向,所以需要澄清以下: ★AdapterFactoryContentProvider, ItemProviderAdapterFactory和ItemProviderAdapter之间的关系,ItemProviderAdapterFactory用来创建各种Adapter以及将各种notifier跟这些adapter关联起来,AdapterFactoryContentProvider包装了一个ItemProviderAdapterFactory(AdapterFactory),它用来将JFace需要的content provider代理到item content provider上,对content provider各种方法的调用将调用到相应的item content provider上,对org.eclipse.jface.viewers.IStructuredContentProvider的调用将代理到IStructuredItemContentProvider上,对ITreeContentProvider的调用将代理到ITreeItemContentProvider上,而对IPropertySourceProvider的调用将代理到IItemPropertySource,而ItemProviderAdapter是所有ItemProvider的基类,AdapterFactoryLabelProvider和ItemProviderAdapter之间也存在类似的关系 ★为了显示model内容,我们需要使用content provider和label provider,而编辑model内容则需要使用到editing domain,AdapterFactoryEditingDomain是一个和AdapterFactoryContentProvider、AdapterFactoryLabelProvider类似的东东 ★editing domain主要有两个功能:一个是作为command的factory(所以它的实现类是AdapterFactoryEditingDomain);另一个对EMF Model(ResourceSet,因此提供了getResource()方法)进行管理 ★EditingDomain,AdapterFactoryEditingDomain,EditingDomainItemProvider和Command之间的关系,AdapterFactoryEditingDomain实现了EditingDomain接口,AdapterFactoryEditingDomain和AdapterFactoryContentProvider一样,也是用来将EditingDomain的方法代理到EditingDomainItemProvider上去。 从一般的操作说起,比如从一个company对象上删除一个department对象,通常我们的做法是: java 代码
但是如果是使用command,则会这样做: java 代码
不过这个做法有一个问题,就是不是很通用,因为所有的删除操作基本上都差不多,所以还需要继续抽象,这时就必须引入EditingDomain. EditingDomain的接口定义如下: java 代码
为了创建一个Command对象,我们需要构造一个CommandParameter对象。在createCommand方法里面会调用指定的Command的静态create方法来创建指定的Command对象,通过使用create方法,我们可以对上面的操作做进一步的改写: java 代码
通过上面的改写,差不多实现了一个通用的删除操作流程 接下来我们可以看看一个command的创建过程,首先是调用指定command的静态create方法,该方法将调用EditingDomain的createCommand方法,AdapterFactoryEditingDomain作为EditingDomain的实现类,又将command的创建过程代理到EditingDomainItemProvider上,在Itemprovider(实现了EditingDomainItemProvider接口)中,最终使用new创建指定的Command实例 我们可以采用多种方式对command定制,第一种就是复写generated的EditingDomainItemProvider实现类的createCommand方法: java 代码
这里的RemoveDepartmentCommand 就是我们自己实现的删除操作。 第二种方式就是复写createRemoveCommand()来实现定制: java 代码
通知的处理 在创建AdapterFactoryContentProvider的时候会将其作为一个listener注册到AdapterFactory里面,这个AdapterFactory实现了IChangeNotifier接口,而AdapterFactory在创建每一个ItemProvider的时候又会把自己传递过去,从而使得AdapterFactory成为model的消息分发中心,在AdapterFactoryContentProvider又会记录所有需要接受通知的viewer(也就是为其提供了content provider的viewer)。 当model被改变之后,将触发和该model相关的adapter的notifyChanged()方法(这里面的adapter就包括itemprovider),当然这里还有一个过滤的过程,只把那些跟viewer相关的notification才会发送给viewer。为了将notification继续传递,会使用ViewerNotification这样一个对象来对notifation以及其他的信息进行封装,因此它继承了Notification,除了Notification相关的信息之外,还封装了要更新的viewer的相关元素,IViewerNotification 的定义如下: java 代码
对于消息的传递还会进行分类,这个是在notifyChanged这个方法里面做的,如下面的代码: java 代码
可以看出,如果是attribute,那么会对label进行更新,如果是reference,那么需要更新content了,否则什么都不做。fireNotifyChanged方法是在ItemProviderAdapter(就是所有ItemProvider的基类)里面定义的,它会把notifaction传给adapter factory,前面我们说过adapter factory是notification的分发器,因此它会将notification发送给所有注册的listener,我们前面也说过AdapterFactory实现IChangeNotifier接口,并作为listener注册到adapter factory中去了,因此在最后会调用adapter factory的fireNotifyChanged方法,当然了adapter factory也会将notification代理别的对象(可能是tree或者table的content/label provider,当然在emf中就是itemprovider了)上去,最后viewer被更新了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |