2013-01-07 79 views
0

我正在開發一個多頁面表單編輯器來編輯/創建一個Eclipse中的自定義XML文件。 結構是這樣的:實施撤消重做基於窗體的編輯器

  • 實現類是MyXMLFormEditor延伸FormEditor。
  • FormEditor的每一頁擴展FormPage(即MyXMLFormPage擴展FormPage)。
  • 在FormEditor和實際的XML文件之間我維護着JDOM模型。
  • 另外我實現了髒標誌處理。因此,用戶輸入到表單編輯器的內容將保存到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或Workbench的現有撤銷/重做框架,那將是一件好事。

+0

你可以看看gef的例子 - 它基本上使用命令模式,如果我沒有記錯的話,相關的類名也是CommandStack – Scorpion

+0

,看起來像是http://stackoverflow.com/questions/14120203/how-to -implement-undo-redo-functionality-into-eclipse-formeditor – Scorpion

+0

此處的代碼似乎是@Scorpion突出顯示的重複問題中的內容的確切副本。這個問題的答案是不是令人滿意?你應該回答原來的問題。 –

回答

0

對於Eclipse中多頁面編輯器實現使用的模式有幾點需要重點說明。可能有這樣做的其他方式,但在Eclipse的編輯似乎要堅持以下幾點:

  • 維護多數民衆贊成在編輯器(你這樣做)的頁面共享的數據模型。
  • 當頁面即將顯示時,僅刷新包含模型數據的頁面。不要試圖保持非顯示頁面與模型同步。
  • 執行撤銷或重做時,對模型進行相應的更改(per @ Scorpion的評論),然後刷新當前頁面。
  • 每個頁面應該有一個可以離開這個頁面的方法(我不記得名字),它被調用以確保顯示的數據沒有錯誤,足以允許頁面被改變(你不想在未顯示的數據上發生錯誤)。
  • 頁面有一個即將離開此頁面的方法,在切換頁面之前調用此方法以保存模型的任何更改。大多數頁面在這裏沒有做任何事情,因爲模型有時會被每次擊鍵修改,但源頁面將使用此方法將模型完全替換爲文本編輯器內容的解析結果。

這意味着你的表單不必執行undo/redo自己。相反,表示多頁編輯器頁面的類將在模型更改時與模型交互,然後將正確的數據傳遞給表單。

表單需要偵聽撤消/重做鍵事件,並通過命令模式將其傳遞給模型。