java - 如何在 Eclipse FormEditor 中实现撤销/重做功能?

标签 java xml eclipse eclipse-plugin

我正在开发一个多页表单编辑器以在 Eclipse 中编辑/创建自定义 XML 文件。

  1. 实现类是扩展FormEditor的MyXMLFormEditor。

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

}

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 或工作台的撤消/重做框架,那就更好了。

最佳答案

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

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

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

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

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

如果你在想什么是myUndoContext,你会从阅读第一篇文章中知道这一点。

2) 创建你自己的 IUndoableOperation用户可以对您的数据进行的不同类型的修改的实现。如果它仅依赖于 XPath->“新值”或 id->“新值”之类的东西,它可能是处理所有修改的单个操作。或者您可以使用一系列不同的操作来修改每种类型的数据模型。由您决定。

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 被按下。

关于java - 如何在 Eclipse FormEditor 中实现撤销/重做功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14120203/

相关文章:

java - 通过类实现接口(interface)创建基于 CGLib 的代理

java - Perforce 链接文件

java - 如何用另一个 java.util.Properties 中的所有对覆盖 java.util.Properties 中的某些对?

c# - 无法读取包含 & 符号的 XML 文档

eclipse - Subversive 和 Subclipse 同时在 Eclipse 中如何禁用其中之一?

java - 调用java程序的Gradle脚本

java - Android - 无法运行、gradle 错误、重复条目

python - 使用 python 通过标记文本搜索 XML

c# - 仅获取 WCf 消息的正文

c++ - Eclipse CDT,build设置 - Hello World