如何将撤销/重做功能实现到Eclipse FormEditor中?

5
我正在开发一个多页面表单编辑器,用于在Eclipse中编辑/创建自定义的XML文件。
  1. 实现类是MyXMLFormEditor,它继承了FormEditor。
  2. 每个FormEditor页面都继承自FormPage(即MyXMLFormPage继承自FormPage)。
  3. 在FormEditor和实际的XML文件之间,我维护着JDOM模型。
  4. 我还实现了脏标志处理。因此,用户在表单编辑器中输入的内容会保存到JDOM中,直到用户按下保存按钮。当用户按下保存按钮时,JDOM将被写入/序列化为XML文件。
在具有以上功能的编辑器中,我想要实现撤销/重做功能,如下所示:
  • 当编辑器处于脏状态(用户更改了表单编辑器中的内容并且未保存)时,撤销操作应该将表单编辑器和JDOM中的更改恢复到原始状态(即编辑器处于非脏状态的状态),重做操作应该再次将更改带回到FormEditor和JDOM中,并使编辑器变为脏状态。
以下是我的代码片段:
MyXMLFormEditor.java
public class MyXMLFormEditor extends FormEditor {

    MyXMLFormEditor(){
                                super();                                
                                }

                @Override
                protected FormToolkit createToolkit(Display display) {
                                // Create a toolkit that shares colors between editors.
                                return new FormToolkit(Activator.getDefault().getFormColors(display));
                }

                @Override
                public void init(IEditorSite site, IEditorInput editorInput) {
                                setSite(site);
                                mSite = site;
                                setInput(editorInput);
                                try {
                                                super.init(site, editorInput);
                                } catch (PartInitException e1) {
                                                e1.printStackTrace();
                                }
                                if (!(editorInput instanceof IFileEditorInput))
                                                try {
                                                                throw new PartInitException("Invalid Input: Must be IFileEditorInput");
                                                                } catch (PartInitException e) {
                                                                                e.printStackTrace();
                                                                }
                                setPartName(fileName);
                }
                public void setUpProgFile(IEditorSite site, IEditorInput editorInput){                       
                                IFileEditorInput fileInput = ((IFileEditorInput) editorInput);

                                //create document builder and prepare JDom model for xml file.
                }


                @Override
                protected void addPages() {
                                try {
                                                //add 'Main' page
                                                objMyXMLFormPage = new MyXMLFormPage (this, "FirstPage","Main");
                                                //set rootNode of MyXMLFormPage 
                                                objMyXMLFormPage.rootNode = getRootNode();
                                                objMyXMLFormPage.filePath = filePath;
                                                objMyXMLFormPage.document = document;
                                                addPage(objMyXMLFormPage);

                                } catch (PartInitException e) {
                                                e.printStackTrace();
                                }
                }

                @Override
                public void doSave(IProgressMonitor monitor) {
                                System.out.println("MyXMLFormEditor: doSave");

                                //logic to write jdom contents into xml file.
                                objMyXMLFormPage.setDirty(false);
                }

                @Override
                public void doSaveAs() {
                                System.out.println("MyXMLFormEditor: doSaveAs");
                }
                @Override
                public boolean isSaveAsAllowed() {
                                System.out.println("MyXMLFormEditor: isSaveAsAllowed");
                                return true;
                }

}

我的XML表单页面.java

public class MyXMLFormPage  extends FormPage{

                //private members declaration.

                public MyXMLFormPage (MyXMLFormEditor editor,String title, String id) {
                                // initialize the editor and set its title and name.
                                super(editor,title,id );
                                }

                @Override
                public void createFormContent(IManagedForm managedForm) {
                    // Set page title
                                super.createFormContent(managedForm);

                                FormToolkit mMyXMLFormPage Toolkit = managedForm.getToolkit();

                                //Logic to creat UI and populating its contents from JDom

                }


                private void makeEditorDirty() {
                                updateJdom =  true;       
                                setDirty(true);                                                   
                }

                private void updateJDom() {
                                if(updateJdom){
                                                System.out.println("*** Jdom updated ***");
                                                updateJdom = false;
                                }
                }

                @Override
                public boolean isDirty() {
                                return isDirtyFlag;
                }

                protected void setDirty(boolean value) {
                                isDirtyFlag = value;
                                dirtyStateChanged();
                }

                public void dirtyStateChanged() {
                                getEditor().editorDirtyStateChanged();

                }

                @Override
                public boolean isSaveAsAllowed() {
                                System.out.println("MyXMLFormPage .isSaveAsAllowed");
                      return false;
                   }

                @Override
                public void doSave(IProgressMonitor monitor) {
                                System.out.println("MyXMLFormPage .doSave");
                }

}

有人能为我提供关于如何在FormEditor中实现撤销/重做功能的指针/示例吗? 如果该方法利用了Eclipse PDE或workbench的现有撤销/重做框架,那就太好了。


从你提出的问题来看,它似乎是作业。请提供一些你已经完成的代码片段。 - exexzian
1个回答

4
你需要阅读以下资源。这可能看起来像是额外的工作,但相信我,你的工作会变得更轻松,而且这些文章并不是很长。

你需要执行的基本步骤是:

1)在编辑器中添加撤销/重做操作的动作处理程序

@Override
public void init(IEditorSite site, IEditorInput editorInput) {
    ...

    UndoRedoActionGroup historyActionGroup = new UndoRedoActionGroup(editorSite, myUndoContext, true);
    historyActionGroup.fillActionBars(editorSite.getActionBars());
}

如果您不知道什么是myUndoContext,请先阅读第一篇文章。
2) 为用户在数据上进行的不同类型的修改创建自己的IUndoableOperation实现。如果它只依赖于像XPath->“new value”或id->“new value”之类的内容,则可以创建一个处理所有修改的单个操作。或者您可以为修改每种数据模型类型创建一系列不同的操作。由您决定。
3) 只通过您创建的操作对数据进行每一次修改。
MyDataModifyingOperation op = new MyDataModifyingOperation(xpath, newValue, oldValue);
op.addContext(myUndoContext);
IStatus status = OperationHistoryFactory.getOperationHistory().execute(operation, null, null);

一旦您掌握了基础操作,您需要了解其他高级操作,例如在数据模型上添加某种更改监听机制,以便在撤销/重做修改数据时,您可以更新UI。此外,在大多数情况下,执行操作时记录UI选择状态是可取的,这样在撤销或后续重做时,您可以将选择还原到已修改的元素,以便用户立即识别出按下Ctrl+z/Ctrl+y时发生了什么变化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接