command framework
Company comp = ...
EditingDomain ed = ...
RemoveCommand cmd =
new RemoveCommand(ed,comp,CompanyPackage.eINSTANCE.getCompany_Departments(),dep);
ed.getCommandStack().execute(cmd);
Object target = extractDropTarget(event.item);
command = DragAndDropCommand.create(domain, target, getLocation(event), event.operations, originalOperation, source);//domain就是上面的editingDomain
... {
return domain.createCommand
(DragAndDropCommand.class, new CommandParameter(owner, new Detail(location, operations, operation), collection));/*domain的具体类型是?由于前面说过AdapterFactoryEditingDomain委派给实现IEditingDomainItemProvider接口的item provider,那么就是YYYItemProvider.*/
}
... {
DragAndDropCommand.Detail detail = (DragAndDropCommand.Detail)commandParameter.getFeature();
result = createDragAndDropCommand
(domain, commandParameter.getOwner(), detail.location, detail.operations, detail.operation, commandParameter.getCollection());
}
(EditingDomain domain, Object owner, float location, int operations, int operation, Collection collection)
... {
return new DragAndDropCommand(domain, owner, location, operations, operation, collection);
}
Change Notification
for (int i = 0; i < size; ++ i)
... {
adapters[i].notifyChanged(notification);//给list中每个注册了的adapter发送notification.
}
case PurchasePackage.PURCHASE_ORDER__TO_SHIP:
case PurchasePackage.PURCHASE_ORDER__TO_BILL:
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
return;
case PurchasePackage.PURCHASE_ORDER__ITEMS:
fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
return;
}
super.notifyChanged(notification);
总共3个case子句,前2个是改变purchaseOrder的两个attribute,后1个是改变子对象Item.看看ViewerNotification的后两个参数.
说明前两个case导致label update,后一个case导致content refresh.
3.而这个fireNotifyChanged是调用父类ItemProviderAdapter的,用来把notification转交给adapter factory(YYYItemProviderAdapterFactory),再由factory发给各个listener.
[ItemProviderAdapter.fireNotifyChanged()]
... {
IChangeNotifier changeNotifier = (IChangeNotifier)adapterFactory;
changeNotifier.fireNotifyChanged(notification);
}
adapterFactory就是YYYItemProviderAdapterFactory.
跟踪如下:
在YYYItemProvider(父类就是ItemProviderAdapter)构造函数里调用了super(adapterFactory),而XXXAdapterFacotry调用了子类(XXXItemProviderAdapterFactory).createPurchaseOrderAdapter,createPurchaseOrderAdapter里面调用了new PurchaseOrderItemProvider(this).那么这个this也就是后来一直传递的adapterFactory,亦即XXXItemProviderAdapterFactory.
4.[YYYItemProviderAdapterFactory.fireNotifyChanged()]
if (parentAdapterFactory != null) ... {
parentAdapterFactory.fireNotifyChanged(notification);
}
注意到XXXItemProviderAdapterFactory).adapterFatory维持了一张自己的notifier list(changeNotifier)(生成的代码中这个似乎为null,难道没用?比如在set***引发的事件当中,这个list是空),把notification传递给这个list中的每一个notifier,让他们再进一步notify 它们自己的listerner.
对于parentAdapterFatory(ComposedAdapterFactory类型),如果非空,那么把notification传递过去.再传递notification下去(比如传给AdapterFactoryContentProvider-->viewer结束)
补充:
1.在XXXEditor的constructor中:
factories.add(new ResourceItemProviderAdapterFactory());
factories.add(new PurchaseItemProviderAdapterFactory());
factories.add(new ReflectiveItemProviderAdapterFactory());
将editingDomain注册几个能被delegate的adapter Factory.
在XXXEditor.createModel()中
editingDomain是AdapterFactoryEditingDomain类型,getResourceSet()返回一个ResourceSet接口类型的对象,ResourceSet继承了Notifier接口,editingDomain.getResourceSet().eAdapters()得到一个ResourceSet(notifier)的adapters(监听这个notifier的),并再加一个adapter--problemIndicationAdapter.
2. 在EMF.EDIT中包含的一些常用command
-
-
SetCommand sets the value of an attribute or reference on an EObject.
-
AddCommand adds one or more objects to a multiplicity-many feature of an EObject.
-
RemoveCommand removes one or more objects from a multiplicity-many feature of an EObject.
-
MoveCommand moves an object within a multiplicity-many feature of an EObject.
-
ReplaceCommand replaces an object in a multiplicity-many feature of an EObject.
-
CopyCommand performs a deep copy of one or more EObjects
-