2013-01-02 139 views
5

我正在開發一個多頁面表單編輯器來在Eclipse中編輯/創建一個自定義的XML文件。如何在Eclipse FormEditor中實現撤銷/重做功能?

  1. 實現類是擴展FormEditor的MyXMLFormEditor。

  2. FormEditor的每個頁面都擴展FormPage(即MyXMLFormPage擴展FormPage)。

  3. 在FormEditor和實際的XML文件之間我維護着JDOM模型。

  4. 另外我實現了髒標誌處理。因此,用戶輸入到表單編輯器的內容將保存到JDOM中,直到用戶按下Save按鈕。當用戶按下保存按鈕時,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或工作臺的現有撤銷/重做框架,那將是一件好事。

+0

你提出你的問題的方式,它似乎是作業,提供你已經完成的一小段代碼片段 – exexzian

回答

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