在EMF自動生成的editor中,只提供了TreeViewer作為編輯控件,自動生成的代碼能讓TreeViewer處理Redo&Undo操作,如果還需要對EMF對應(yīng)的Attribute使用Text, Combo等Widget進行編輯的話,那么如何將這些Widget的編輯也能實現(xiàn)Undo&Redo操作呢?
首先我們來分析一下,對于TreeViewer是如何實現(xiàn)Redo&Undo操作的,在生成的editor代碼中有類似這樣的一句(這個是我改寫后的,實際生成的可能有所區(qū)別):為了只針對Redo&Undo對UI進行更新,還需要對RedoAction和UndoAction做進一步處理:
其做法就是要讓editor知道當前的Action,然后在修改UI的時候,取得該Action看是否是我們指定的Action(RedoAction&UndoAction).
- viewer.setContentProvider(new AdapterFactoryContentProvider(
- getAdapterFactory()));
AdapterFactoryContentProvider實現(xiàn)了INotifyChangedListener接口,該接口就是用來處理在EMF模型發(fā)生變動時,如何更新綁定的UI控件:
- public void notifyChanged(Notification notification)
- {
- if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed())
- {
- // If the notification is an IViewerNotification, it specifies how ViewerRefresh should behave. Otherwise fall
- // back to NotifyChangedToViewerRefresh, which determines how to refresh the viewer directly from the model
- // notification.
- //
- if (notification instanceof IViewerNotification)
- {
- if (viewerRefresh == null)
- {
- viewerRefresh = new ViewerRefresh(viewer);
- }
- if (viewerRefresh.addNotification((IViewerNotification)notification))
- {
- viewer.getControl().getDisplay().asyncExec(viewerRefresh);
- }
- }
- else
- {
- NotifyChangedToViewerRefresh.handleNotifyChanged(
- viewer,
- notification.getNotifier(),
- notification.getEventType(),
- notification.getFeature(),
- notification.getOldValue(),
- notification.getNewValue(),
- notification.getPosition());
- }
- }
- }
再看代碼:
- public AdapterFactoryContentProvider(AdapterFactory adapterFactory)
- {
- this.adapterFactory = adapterFactory;
- if (adapterFactory instanceof IChangeNotifier)
- {
- ((IChangeNotifier)adapterFactory).addListener(this);
- }
- }
這里關(guān)鍵的一句就是:
- ((IChangeNotifier)adapterFactory).addListener(this);
它將更新UI的通知操作與adapterFactory關(guān)聯(lián)起來,然后在EMF模型發(fā)生變動的時候,會從adapterFactory來找到所有注冊的INotifyChangedListener
因此做法就相當簡單了,即將EMF模型對應(yīng)的編輯控件實現(xiàn)INotifyChangedListener接口,然后拿到adapterFactory,并把該控件注冊進去.
下面我的一個實現(xiàn):
AbstractDoradoSection包含了EMF模型當前節(jié)點屬性的對應(yīng)編輯控件集合,讓其實現(xiàn)INotifyChangedListener接口
并在構(gòu)造函數(shù)中注冊到adapterFactory中:
- public AbstractDoradoSection(IAdaptable adaptable, Object input,
- Composite parent, String title, int style) {
- this.adaptable = adaptable;
- this.input = input;
- this.title = title;
- this.style = ExpandableComposite.TITLE_BAR | style;
- AdapterFactory adapterFactory = (AdapterFactory) adaptable
- .getAdapter(AdapterFactory.class);
- ((IChangeNotifier) adapterFactory).addListener(this);
- initialize(parent);
- }
- /**
- * 當emf模型發(fā)生變化之后,更新ui,主要針對redo和undo處理
- *
- * @see org.eclipse.emf.edit.provider.INotifyChangedListener#notifyChanged(org.eclipse.emf.common.notify.Notification)
- */
- public void notifyChanged(final Notification notification) {
- IActionProvider actionProvider = (IActionProvider) adaptable
- .getAdapter(IActionProvider.class);
- if (actionProvider.getAction() instanceof NotifierAction) {
- Object feature = notification.getFeature();
- if (feature instanceof EAttribute && rows != null) {
- for (Iterator iter = rows.iterator(); iter.hasNext();) {
- final AttributeRow row = (AttributeRow) iter.next();
- if (row.getAttribute() == feature) {
- row.setTextContent(notification.getNewStringValue(), true);
- break;
- }
- }
- }
- }
安徽新華電腦學校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢】