如何在Eclipse FormEditor中实现撤消/重做功能? [英] How to implement undo/redo functionality into Eclipse FormEditor?

查看:852
本文介绍了如何在Eclipse FormEditor中实现撤消/重做功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 实现类是MyXMLFormEditor它扩展了FormEditor。


  2. FormEditor的每一页都扩展了FormPage(即MyXMLFormPage extends FormPage)。


  3. 在FormEditor和实际的XML文件之间我正在维护JDOM模型。


  4. 此外,我还实现了脏标志处理。因此,用户输入表单编辑器将保存到JDOM中,直到用户按下保存按钮。当用户按下保存按钮时,JDOM被写入/序列化为XML文件。


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




  • 当编辑器变脏(用户将表单编辑器更改为不保存)时,撤消操作应将表单编辑器中的更改还原为JDOM原始状态(即编辑器不脏的状态)和重做操作应该再次将更改带回FormEditor以及JDOM,编辑器应变脏。



以下是我的代码片段:



MyXMLFormEditor.java

 code> public class MyXMLFormEditor扩展FormEditor {

MyXMLFormEditor(){
super();
}

@Override
protected FormToolkit createToolkit(显示显示){
//创建一个在编辑器之间共享颜色的工具包。
返回新的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);

//创建文档构建器并为xml文件准备JDom模型。
}


@Override
protected void addPages(){
try {
//添加'Main'页
objMyXMLFormPage = new MyXMLFormPage(this,FirstPage,Main);
//设置MyXMLFormPage的rootNode
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);

//将jdom内容写入xml文件的逻辑。
objMyXMLFormPage.setDirty(false);
}

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

}

MyXMLFormPage .java

  public class MyXMLFormPage extends FormPage {

//私有成员声明。

public MyXMLFormPage(MyXMLFormEditor editor,String title,String id){
//初始化编辑器并设置其标题和名称。
super(editor,title,id);
}

@Override
public void createFormContent(IManagedForm managedForm){
//设置页面标题
super.createFormContent(managedForm);

FormToolkit mMyXMLFormPage Toolkit = managedForm.getToolkit();

//逻辑创建UI和填充其内容从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);
返回false;
}

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

}

任何人都可以提供指针/样本关于如何在FormEditor中实现撤消/重做功能?
如果方法使用Eclipse PDE或工作台的现有撤消/重做框架,那将是好的。

解决方案

您需要阅读以下资源。这可能看起来像额外的工作,但相信我的工作会更容易一些,这些文章不是很长。





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



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


I am developing a multipage Form Editor to edit/create a customized XML file in Eclipse.

  1. Implementation class is MyXMLFormEditor which extends FormEditor.

  2. Each page of FormEditor extends FormPage (i.e. MyXMLFormPage extends FormPage).

  3. Between FormEditor and actual XML file I am maintaining JDOM model.

  4. Also I implemented dirty flag handling. So user’s inputs into form editor gets saved into JDOM till the time user presses Save button. When user presses save button JDOM is written/serialized into XML file.

In an editor with above functionality I would like to implement undo/redo functionality as follow:

  • When editor is dirty (user changed something into form editor and it is not saved) undo operation should revert back the changes in form editor as well as JDOM to its original state (i.e. the state when editor was non-dirty) and redo operation should again bring back the changes into FormEditor as well as JDOM and editor should become dirty.

Following is my code snippet:

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

}

Can anyone provide me pointer/samples on how to implement undo/redo functionality into FormEditor? It would be good if the approach make use of existing undo/redo framework of Eclipse PDE or workbench.

解决方案

You need to read the following resources. It may seem like extra work but believe me your job will be a lot easier and these articles aren't really long.

The basic steps you need to perform are:

1) Add action handlers for undo/redo operations in your editor

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

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

If you are thinking what is myUndoContext, you will know this from reading the first article.

2) Create your own IUndoableOperation implementations for different types of modifications that the user can make on your data. It could be a single operation that handles all your modifications if it only depends on something like XPath->"new value", or id->"new value". Or you could have a range of different operations for modifying each type of your data model. Its up to you.

3) Make each and every modification to your data only through the operations you created

MyDataModifyingOperation op = new MyDataModifyingOperation(xpath, newValue, oldValue);
op.addContext(myUndoContext);
IStatus status = OperationHistoryFactory.getOperationHistory().execute(operation, null, null);

Once you get the basic stuff working you will need to look at some other advanced stuff, like adding some kind of change listening mechanism on the data model so that when undo/redo modify the data, you can update the UI. Also in most cases it is desirable that when you perform an operation you record UI selection state, so that on undo or subsequent redos you can restore selection to the element that was modified so that the user immediately recognizes what changed when Ctrl+z/Ctrl+y was pressed.

这篇关于如何在Eclipse FormEditor中实现撤消/重做功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆