<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    nighty

    折騰的年華
    posts - 37, comments - 143, trackbacks - 0, articles - 0

    RssOwl2源碼閱讀 -- ActionSet

    Posted on 2008-08-21 11:29 寒武紀 閱讀(1798) 評論(0)  編輯  收藏 所屬分類: Eclipse
        ActionSet是Eclipse RCP里面一非常重要的概念,因為菜單、工具欄、上下文菜單、狀態欄很多操作都是共享的,所以Action就是用來處理重復出現的東西。至于Eclipse里面定義ActionSet有非常多的技巧,可能無法一一列舉,而且使用方法也多種多樣。下面介紹的是RssOwl2項目的ui源代碼部分的一小塊。
       1.  菜單的插入點 -- GroupMarker和Separator的使用
            ApplicationActionBarAdvisor類是定義全局所有Action插入點和入口,查看fillMenuBar(IMenuManager)方法,為了簡化,以其中的輔助方法createFileMenu(IMenuManager)為例,講述一下實現菜單“文件”的內容,先看一下菜單的結構

           像Close,Import...之類的非常簡單,看一下它是如何實現New這個子菜單的。首先看一下它的源代碼如何定義插入點
         
    /* Menu: File */
      
    private void createFileMenu(IMenuManager menuBar) {
        MenuManager fileMenu 
    = new MenuManager("&File", IWorkbenchActionConstants.M_FILE);
        menuBar.add(fileMenu);

        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.FILE_START));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.NEW_EXT));
        fileMenu.add(
    new Separator());

        fileMenu.add(getAction(ActionFactory.CLOSE.getId()));
        fileMenu.add(getAction(ActionFactory.CLOSE_ALL.getId()));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.CLOSE_EXT));
        fileMenu.add(
    new Separator());
        fileMenu.add(getAction(ActionFactory.SAVE_AS.getId()));
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.SAVE_EXT));
        fileMenu.add(
    new Separator());
        fileMenu.add(getAction(ActionFactory.PRINT.getId()));

        fileMenu.add(
    new Separator());
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        fileMenu.add(fReopenEditors); 
    // TODO Consider moving into a "Go" Menu!

        fileMenu.add(
    new Separator());
        fileMenu.add(
    new GroupMarker(IWorkbenchActionConstants.FILE_END));
        fileMenu.add(
    new Separator());

        fileMenu.add(getAction(ActionFactory.QUIT.getId()));
      }
           其中有一行fileMenu.add(new GroupMarker(IWorkbenchActionConstants.NEW_EXT)); 這里是定義一個GroupMarker作為組標記,把子菜單New容納進來。這個NEW_EXT的值是:new.ext
          現在跳回到plugin.xml去看一下它的ActionSet定義,結構如下:
    ,點擊New(menu),它的path值為:file/new.ext,這個路徑就是在createFileMenu方法定義的路徑,第一個是“File”本身的ID。也就是把子菜單New(menu)插入到指定的那個GroupMarker,ID為new.ext。然后定義了三個ID分別為bookmark,newsbin,searchmark,的groupmarker和一個folder的separator,這個三ID分別就對應上面actionSet定義的三個action,以其中的Bookmark(action)為例,它的menubarPath為:file/new_sub/bookmark,代表插入到"File"主菜單中定義的new_sub子菜單中,new_sub是New(menu)的ID。因為folder是定義為separator,所以它會有一條分隔線。這只是RssOwl的定義方法,其實以前自己做開發的時候是沒有這樣定義的,而且把子菜單New也寫在方法fillMenuBar中的,菜單把ID都寫在里面,ActionSet的配置就沒有子菜單出現了,但是這樣定義看起來就比較亂。采用這種寫法感覺比較簡潔。
        2.  Action的實現
           仍以bookmark為例,它的實現類是NewBookMarkAction,實現了IWorkbenchWindowActionDelegate, IObjectActionDelegate二個接口,第一個是ActionSet指定實現接口,第二個是對象操作菜單要求實現的接口(但事實發現沒有再定義它的配置,可能是internal版本的原因),也就是說這個Action是多功能,它將會出現在主菜單,工具欄,和局部的右鍵菜單上。主菜單和工具欄的位置都在ActionSet配置定義了,看看它的右鍵菜單實現是在哪里的,這個右鍵是在視圖Bookmarks定義的,那么跳轉到org.rssowl.ui.internal.views.explorer.BookMarkExplorer類去看看。里面有一個hookContextualMenu()方法,就是定義它的右鍵菜單的,看一下代碼實現:
    private void hookContextualMenu() {
        MenuManager manager 
    = new MenuManager();

        
    /* New Menu */
        MenuManager newMenu 
    = new MenuManager("New");
        manager.add(newMenu);

        
    /* New BookMark */
        newMenu.add(
    new Action("Bookmark"{
          @Override
          
    public void run() {
            IStructuredSelection selection 
    = (IStructuredSelection) fViewer.getSelection();
            IFolder parent 
    = getParent(selection);
            IMark position 
    = (IMark) ((selection.getFirstElement() instanceof IMark) ? selection.getFirstElement() : null);
            
    new NewBookMarkAction(fViewSite.getShell(), parent, position).run(null);
          }


          @Override
          
    public ImageDescriptor getImageDescriptor() {
            
    return OwlUI.BOOKMARK;
          }

        }
    );

       
    //其它定義
    }
         原來實現也很簡單,只是往MenuManager里面添加一個Action而已,而且run方法就是直接調用定義好的NewBookMarkAction的run方法,但是把選中對象做為參數傳進去,因為這個new是涉及當前上下文選擇對象的。
        3. 下拉類型的工具按鈕定義
        非常常見的Dropdown類型的工具欄按鈕可以把功能類型的按鈕歸為一類,做成一個下拉菜單形式,有默認的按下功能,也有可以選擇其它類似功能的下三角形式,樣子如下:

        這個dropdown的Action是定義在ActionSet配置里的。style是pulldown類型的,所以實現類NewTypeDropdownAction實現了IWorkbenchWindowPulldownDelegate接口,它的run方法就是定義默認點擊不做選擇時的事情,這個下拉菜單是實現getMenu(Control parent)方法而來,它定義了如何生成這個菜單,這就用到了最原始的SWT中的MenuItem了,并且為它們添加SelectionListener,方法實現,不用說都知道了,又是New一個先前定義好的NewBookMarkAction類,然后又是調用它的run方法。所以總結一下,Action的重用不一定是這個類的重用,關鍵是它的run方法的重用,在不同的場景下它的外在表現形式可能會多種多樣,但是它的run內容是一致的。像添加這種添加的run大部分時候都是彈出一個對話框,而對話框大都又是Winzard類型的,因為Winzard可以共享放到dialog里面。所以這種復用的思想在Eclipse里面隨處可見。
       歸結一下,其實這些技巧都是次要的,因為做GUI一個比較痛苦的事情就是經常要寫很多重復類似的代碼,抽取的不好,可能就變得不倫不類了。怎么利用它的這種思想,把復用的代碼都抽取在一起,而閱讀起來又比較輕松才是關鍵。
       知道的就這些,先介紹到這里,下次再談談其它新的發現。


    剛進場的時候戲就落幕
    主站蜘蛛池模板: 亚洲电影日韩精品| 亚洲人成电影在线观看青青| 叮咚影视在线观看免费完整版| 亚洲高清视频在线观看| 在线观看无码AV网站永久免费| 色一情一乱一伦一视频免费看| 久久被窝电影亚洲爽爽爽 | 国产免费一区二区三区在线观看 | 亚洲黄色网址大全| 日韩黄色免费观看| 免费h视频在线观看| 亚洲精品日韩一区二区小说| 亚洲伊人久久大香线蕉综合图片| 亚洲免费一级视频| 一边摸一边桶一边脱免费视频 | 中文字幕乱码免费看电影| 亚洲一区在线视频| 亚洲午夜精品一级在线播放放| free哆啪啪免费永久| jizz免费观看| 亚洲综合欧美色五月俺也去| 亚洲情综合五月天| 免费欧洲美女牲交视频| 亚洲最大免费视频网| 久久av免费天堂小草播放| 亚洲精品伊人久久久久| 亚洲熟妇av一区二区三区漫画| 女人18一级毛片免费观看| 99re在线精品视频免费| yellow视频免费在线观看| 亚洲av第一网站久章草| 亚洲精品国产免费| 亚洲国产日韩一区高清在线| 亚洲综合精品网站| 大胆亚洲人体视频| 香蕉视频在线观看免费国产婷婷 | 无遮挡呻吟娇喘视频免费播放| 国产成人精品日本亚洲专区| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 色片在线免费观看| 疯狂做受xxxx高潮视频免费|