【问题标题】:implement Undo Redo in form based editor在基于表单的编辑器中实现撤消重做
【发布时间】:2012-12-21 00:33:08
【问题描述】:

我正在开发一个多页表单编辑器来在 Eclipse 中编辑/创建自定义 XML 文件。 结构如下:

  • 实现类是 MyXMLFormEditor,它扩展了 FormEditor。
  • FormEditor 的每一页都扩展了 FormPage(即 MyXMLFormPage 扩展了 FormPage)。
  • 在 FormEditor 和实际 XML 文件之间,我正在维护 JDOM 模型。
  • 我还实现了脏标志处理。因此,用户在表单编辑器中的输入会保存到 JDOM 中,直到用户按下保存按钮。当用户按下保存按钮时,JDOM 被写入/序列化为 XML 文件。

在具有上述功能的编辑器中,我想实现如下撤消/重做功能:

当编辑器变脏时(用户将某些内容更改为表单编辑器但未保存)撤消操作应将表单编辑器以及 JDOM 中的更改恢复到其原始状态(即编辑器未变脏时的状态)和重做操作应该再次将更改带回 FormEditor 以及 JDOM 和编辑器应该变脏。

下面是我的代码sn-p

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;
                }

}

MyXMLFormPage .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 或工作台的撤消/重做框架会很好。

【问题讨论】:

  • 你可以看看gef的例子——它基本上使用命令模式,如果我没记错的话,相关的类名是CommandStack
  • 另外,看起来像 stackoverflow.com/questions/14120203/… 的副本
  • 这里的代码似乎与@Scorpion 强调的重复问题中发布的内容完全相同。这个问题的答案不令人满意吗?你应该回答原来的问题。

标签: java xml eclipse-plugin undo-redo


【解决方案1】:

关于 Eclipse 中的多页编辑器实现所使用的模式,有几点需要说明。可能还有其他方法可以做到,但 Eclipse 中的编辑器似乎坚持以下几点:

  • 维护编辑器中页面共享的数据模型(您正在这样做)。
  • 仅当页面即将显示时才使用模型数据刷新页面。不要试图让未显示的页面与模型保持同步。
  • 执行撤消或重做时,对模型进行适当的更改(根据 @Scorpion 的评论),然后刷新当前页面。
  • 每个页面都应该有一个 its-ok-to-leave-this-page 方法(我不记得名字了),该方法被调用以确保显示的数据没有错误,足以允许页面被更改(您不希望在未显示的数据上出现错误)。
  • 页面有一个 about-to-leave-this-page 方法,该方法被调用以在切换页面之前保存对模型的任何更改。大多数页面在这里不做任何事情,因为模型有时会被每次击键修改,但源页面会使用此方法将模型完全替换为文本编辑器内容的解析结果。

这意味着您的表单不必自己执行撤消/重做。相反,表示多页编辑器页面的类将在模型发生更改时与模型进行交互,然后将要显示的正确数据传递给表单。

表单将需要监听撤消/重做键事件并通过命令模式将这些事件传递给模型。

【讨论】:

    猜你喜欢
    • 2016-03-31
    • 1970-01-01
    • 2020-05-12
    • 2016-02-18
    • 1970-01-01
    • 2011-11-14
    • 2015-08-10
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多