天天看點

RCP應用程式開發之四——應用程式窗體生成過程1

在eclipse平台下,導入一個應用程式模闆後,可以直接運作。這篇文章主要将窗體在生成的過程中有哪些重要的步驟總結了一下。

本篇文章分為那兩個部分:

第一個部分為rcp應用程式生成窗體經曆的幾個步驟。

第二個部分描述窗上尚菜單、工具欄的生成。

1.1        rcp應用程式生成窗體經曆的幾個步驟:<o:p></o:p>

生成應用程式的窗體,主要經曆了以下幾個步驟:<o:p></o:p>

1、在application中:建立了工作台<o:p></o:p>

int returnCode = PlatformUI.createAndRunWorkbench(display, <o:p></o:p>

new ApplicationWorkbenchAdvisor());<o:p></o:p>

2、在ApplicationWorkbenchAdvisor中:配置應用程式的窗體<o:p></o:p>

public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(<o:p></o:p>

           IWorkbenchWindowConfigurer configurer) {<o:p></o:p>

       return new ApplicationWorkbenchWindowAdvisor(configurer);<o:p></o:p>

   }<o:p></o:p>

3、在ApplicationWorkbenchWindowAdvisor類中:配置菜單欄工具欄<o:p></o:p>

public ActionBarAdvisor createActionBarAdvisor(<o:p></o:p>

           IActionBarConfigurer configurer) {<o:p></o:p>

       if (fActionBuilder == null)<o:p></o:p>

       fActionBuilder = new WorkbenchActionBuilder(configurer);<o:p></o:p>

       return fActionBuilder.makeWinAction();<o:p></o:p>

   }<o:p></o:p>

4、在WorkbenchActionBuilder類中:傳回不同工作台窗體的ActionBarAdvisor<o:p></o:p>

…<o:p></o:p>

   public WorkbenchActionBuilder(IActionBarConfigurer Ibarconfigurer) {<o:p></o:p>

       this.Ibarconfigurer = Ibarconfigurer;<o:p></o:p>

   }<o:p></o:p>

       <o:p></o:p>

   public ActionBarAdvisor makeWinAction(){ <o:p></o:p>

       switch(WorkbenchControler.flag){<o:p></o:p>

       case WorkbenchControler.main:<o:p></o:p>

           actionBarAdvisor = new MainActionBarAdvisor(Ibarconfigurer);<o:p></o:p>

           break;<o:p></o:p>

       case WorkbenchControler.child_1:<o:p></o:p>

           actionBarAdvisor = new Child_1_ActionBarAdvisor(Ibarconfigurer);<o:p></o:p>

           break;<o:p></o:p>

       case WorkbenchControler.child_2:<o:p></o:p>

           actionBarAdvisor = new MainActionBarAdvisor(Ibarconfigurer);<o:p></o:p>

           break;<o:p></o:p>

       }<o:p></o:p>

       return actionBarAdvisor;<o:p></o:p>

   }<o:p></o:p>

   …<o:p></o:p>

那麼eclipse是怎樣來幫助我們生成一個主窗體的呢?在這個過程中又經曆了哪些過程?現在詳細的學習這個過程。<o:p></o:p>

(1)PlatformUI的方法createAndRunWorkbench(),這個方法用來建立工作台。<o:p></o:p>

在(1)中,調用的是PlatformUI的這個方法:<o:p></o:p>

public static int createAndRunWorkbench(Display display,<o:p></o:p>

            WorkbenchAdvisor advisor) {<o:p></o:p>

        return Workbench.createAndRunWorkbench(display, advisor);<o:p></o:p>

    }<o:p></o:p>

通過createAndRunWorkbench來建立工作台窗體,在這個方法中,調用了Workbench了的createAndRunWorkbench這個方法。<o:p></o:p>

(2) Workbench的createAndRunWorkbench()方法<o:p></o:p>

public static final int createAndRunWorkbench(Display display,<o:p></o:p>

           WorkbenchAdvisor advisor) {<o:p></o:p>

       // create the workbench instance<o:p></o:p>

       Workbench workbench = new Workbench(display, advisor);<o:p></o:p>

       // run the workbench event loop<o:p></o:p>

       int returnCode = workbench.runUI();<o:p></o:p>

       return returnCode;<o:p></o:p>

   }<o:p></o:p>

在這個方法中,建立了一個工作台的執行個體,并把adivsor作為參數傳入。然後運作一個Workbench中的一個runUI方法,主要通過這個方法建立了工作台的窗體。我們看看這個方法都實作了什麼。<o:p></o:p>

(3)Workbench的runUI()方法<o:p></o:p>

我們看下面這行代碼,int returnCode = workbench.runUI();<o:p></o:p>

runUI()的功能就是:用來運作workbench UI(工作台窗體),直到工作台(workbench)關閉和重新啟動,它用來承擔處理和分派事件。(Internal method for running the workbench UI. This entails processing and dispatching events until the workbench is closed or restarted.)<o:p></o:p>

當正常退出時,傳回RETURN_OK,當工作台通過一個針對IWorkbench.restart的通路終止時,傳回RETURN_RESTART 當工作台不能被啟動時傳回RETURN_UNSTARTABLE。其他值留為後用。 <o:p></o:p>

在這個runUI()方法中,我們看到一個比較重要的方法:<o:p></o:p>

(4)runUI()方法中的init(display)方法<o:p></o:p>

boolean initOK = init(display);這個方法屬于Workbench的内部方法,用來初始化工作台,重建或打開一個窗體。如果init成功,傳回initOK。在這個方法中,建立了針對窗體的管理WindowManager,指令的管理CommandManager,上下文的管理ContextManager.<o:p></o:p>

另外在這個方法中還初始化了圖像,顔色等。<o:p></o:p>

initializeImages();<o:p></o:p>

initializeFonts();<o:p></o:p>

initializeColors();<o:p></o:p>

initializeApplicationColors();<o:p></o:p>

{通過這些方法,可以學習eclipse是怎麼初始化Image,Font,Color等這些比較耗費資源的例子,針對這方面的學習,以後再續。}<o:p></o:p>

在init中,還有個比較重要的方法:通過advisor引用internalBasicInitialize方法:<o:p></o:p>

advisor.internalBasicInitialize(getWorkbenchConfigurer());<o:p></o:p>

我們首先看看它的參數:一個WorkbenchConfiguer對象,getWorkbenchConfigurer()方法在WorkbenchConfiguer類中定義,它傳回一個單例WorkbenchConfiguer對象。這個對象用來配置工作台。<o:p></o:p>

public final void internalBasicInitialize(IWorkbenchConfigurer configurer) {<o:p></o:p>

        if (workbenchConfigurer != null) {<o:p></o:p>

            throw new IllegalStateException();<o:p></o:p>

        }<o:p></o:p>

        this.workbenchConfigurer = configurer;<o:p></o:p>

        initialize(configurer);<o:p></o:p>

    }<o:p></o:p>

在internalBasicInitialize将configure對象引用傳遞給WorkbenchAdvisor對象的workbenchConfigurer屬性,并調用了WorkbenchAdvisor類的initialize方法。這個很重要。我們在有關工作台(Workbench)生命周期的文章中提到:initialize方法是在任何窗體打開前調用這個方法。可以用來初始化。我們可以在WorkbenchAdvisor的子類中來實作這個方法。<o:p></o:p>

我們來看看這個方法的官方譯文:<o:p></o:p>

在工作台啟動之前,執行任意的初始化内容。<o:p></o:p>

在任何窗體被打開之前,工作台初始化時,這個方法會被優先的通路。使用者不能直接通路這個方法,,預設的沒有任何的實作。子類可以繼承這個方法。使用者會用configuer來配置工作台,如果需要用,則使用者需要獲得通過getWorkbenchConfigurer來獲得configurer。<o:p></o:p>

[Performs arbitrary initialization before the workbench starts running. <o:p></o:p>

This method is called during workbench initialization prior to any windows being opened. Clients must not call this method directly (although super calls are okay). The default implementation does nothing. Subclasses may override. Typical clients will use the configurer passed in to tweak the workbench. If further tweaking is required in the future, the configurer may be obtained using getWorkbenchConfigurer. ]<o:p></o:p>

(5)preStartup()方法<o:p></o:p>

在init()這個方法中,還調用了:<o:p></o:p>

advisor.preStartup();<o:p></o:p>

具體的可以參考:前面講到WorkbenchAdvisor的生命周期中的preStartup方法,它的調用是在第一個視窗打開之前。在啟動或者恢複期間暫時禁用某些項時,該方法非常有用。<o:p></o:p>

這個方法在第一個工作台窗體被打開或恢複(重建)時,執行任意的操作。<o:p></o:p>

這個的實在workbench被初始化的之後被通路的,使用者不能直接通路這個方法,必須通過子類繼承。<o:p></o:p>

[Performs arbitrary actions just before the first workbench window is opened (or restored). <o:p></o:p>

This method is called after the workbench has been initialized and just before the first window is about to be opened. Clients must not call this method directly (although super calls are okay). The default implementation does nothing. Subclasses may override.] <o:p></o:p>

然後再執行下面這個if語句:<o:p></o:p>

if (!advisor.openWindows()) {<o:p></o:p>

               return false;<o:p></o:p>

           }<o:p></o:p>

(6)WorkbenchAdvisor的openWindows()方法<o:p></o:p>

繼續閱讀