熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

關於Eclipse中新建菜單的實現方法

2013-11-23 20:22:11  來源: Java開源技術 

  新建菜單裡面都是聲明過NewWizard的東東

  不過既然已經聲明了NewWizard還要在ActionSet或者PopupMenus裡面再聲明一遍不是很痛苦?

  其實可以如下做法

  先聲明一個PullDown的菜單

   <action
     class=\xxxNewAction\
     hoverIcon=\icons/full/objects/new_projectgif\
     id=\xxxNewAction\
     label=\新建(&amp;N)\
     menubarPath=\nusfile/sep\
     style=\pulldown\
     toolbarPath=\sep\>
</action>

  如果這個菜單用Coolbar 那麼需要繼承IWorkbenchWindowPulldownDelegate接口 如果要用在Menu上 那麼繼承IWorkbenchWindowPulldownDelegate接口實現基本是一樣的

  

  public class NewAction implements IWorkbenchWindowPulldownDelegate SelectionListener {
    private IWorkbench workbench;

    @SuppressWarnings(\unused\)
    private IWorkbenchWindow window;

    private Menu parent = null;

    private Menu inMenu = null;

    private Menu inToolbar = null;

    private IStructuredSelection selection;

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIWorkbenchWindowActionDelegate#dispose()
     */
    public void dispose() {
        if (inMenu != null) {
            inMenudispose();
            inMenu = null;
        } [Page]
        thisworkbench = null;
        thiswindow = null;
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIWorkbenchWindowActionDelegate#init(orgeclipseuiIWorkbenchWindow)
     */
    public void init(IWorkbenchWindow window) {
        thiswindow = window;
        thisworkbench = windowgetWorkbench();
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIActionDelegate#run(orgeclipsejfaceactionIAction)
     */
    public void run(IAction action) {
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIActionDelegate#selectionChanged(orgeclipsejfaceactionIAction
     *      orgeclipsejfaceviewersISelection)
     */
    public void selectionChanged(IAction action ISelection selection) {
        thisselection = (IStructuredSelection) selection;
        if (parent != null) {
            // 找到新建菜單項
            // 重新創建其子菜單
            MenuItem[] items = parentgetItems();
            if (items != null) {
                MenuItem parentItem = null;
                for (int index =  count = itemslength; index < count; index++) { [Page]
                    MenuItem item = items[index];
                    Object data = itemgetData();
                    if (data instanceof ActionSetContributionItem) {
                        IContributionItem innerItem = ((ActionSetContributionItem) data)
                                getInnerItem();
                        if (innerItemgetId()equals(getClass()getName())) {
                            parentItem = item;
                            break;
                        }
                    }
                }
                if (parentItem != null) {
                    Menu menu = getMenu(parent);
                    parentItemsetMenu(menu);
                    parentItemsetImage(null); [Page]
                }
            }
        }
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIWorkbenchWindowPulldownDelegate#getMenu(orgeclipseswtwidgetsControl)
     */
    public Menu getMenu(Control parent) {
        if (inToolbar != null)
            inToolbardispose();

        inToolbar = new Menu(parent);
        return createMenu(inToolbar);
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIWorkbenchWindowPulldownDelegate#getMenu(orgeclipseswtwidgetsMenu)
     */
    public Menu getMenu(Menu parent) {
        if (inMenu != null)
            inMenudispose();

        thisparent = parent;
        inMenu = new Menu(parent);
        return createMenu(inMenu);
    }

    /** *//**
     * @param parent
     * @return
     */
    private Menu createMenu(Menu menu) {
boolean hasMenu = false;
        IWizardRegistry registry = workbenchgetNewWizardRegistry();
        IWizardCategory rootCategory = registrygetRootCategory();
        IWizardCategory[] categories = rootCategorygetCategories(); [Page]
        if (categories != null) {
            reverseArray(categories);
            for (IWizardCategory category : categories) {
                hasMenu = createMenuItems(menu category hasMenu) || hasMenu;
            }
        }
        if (hasMenu)
            new MenuItem(menu SWTSEPARATOR);

        MenuItem mnuOther = new MenuItem(menu SWTNONE);
        mnuOthersetText(\其他(&R)\);
        mnuOtheraddSelectionListener(new SelectionAdapter() {
            /** *//**
             * (nonJavadoc)
             * 
             * @see orgeclipseswteventsSelectionAdapter#widgetSelected(orgeclipseswteventsSelectionEvent)
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                NewWizardDialog dialog = new NewWizardDialog(workbenchgetActiveWorkbenchWindow()
                        getShell() selection);
                dialogopen();
            }
        }); [Page]
        return menu;
    }

    /** *//**
     * 創建菜單
     * 
     * @param menu
     * @param category
     * @param hasMenu 是否在之前已經有菜單
     * @return 是否成功創建了菜單
     */
    private boolean createMenuItems(Menu menu IWizardCategory category boolean hasMenu) {
        boolean create = false;
        IWizardDescriptor[] wizards = categorygetWizards();
        if (wizards != null) {
            reverseArray(wizards);
            List<IWizardDescriptor> shown = new ArrayList<IWizardDescriptor>();

            for (IWizardDescriptor wizard : wizards) {
                IConfigurationElement element = (IConfigurationElement) wizard
                        getAdapter(IConfigurationElementclass);
                IConfigurationElement[] children = element
                        getChildren(IWorkbenchRegistryConstantsTAG_ENABLEMENT);
if (children != null && childrenlength != {
                    IConfigurationElement enablement = children[];
                    ActionExpression exp = new ActionExpression(enablement); [Page]
                    if (!expisEnabledFor(thisselection)) {
                        continue;
                    }
                }
                shownadd(wizard);
            }

            if (shownsize() != {
                create = true;
                if (hasMenu) {
                    new MenuItem(menu SWTSEPARATOR);
                }

                for (IWizardDescriptor wizard : shown) {
                    MenuItem item = new MenuItem(menu SWTNONE);
                    itemsetText(wizardgetLabel());
                    if (wizardgetImageDescriptor() != null)
                        itemsetImage(wizardgetImageDescriptor()createImage());
                    itemsetData(wizard);
                    itemaddSelectionListener(this); [Page]
                }
            }
        }
        return create;
    }

    /** *//**
     * 反轉數組
     * 
     * @param array
     */
    private void reverseArray(Object[] array) {
        if (array != null) {
            int count = arraylength;
            int last = count  ;
            for (int index = ; index < count / ; index++) {
                Object temp = array[index];
                array[index] = array[last  index];
                array[last] = temp;
            }
        }
    }

    /** *//**
     * (nonJavadoc)
     * 
* @see orgeclipseswteventsSelectionListener#widgetDefaultSelected(orgeclipseswteventsSelectionEvent)
     */
    public void widgetDefaultSelected(SelectionEvent e) {
        // do nothing
    }

    /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseswteventsSelectionListener#widgetSelected(orgeclipseswteventsSelectionEvent)
     */ [Page]
    public void widgetSelected(SelectionEvent e) {
        MenuItem item = (MenuItem) egetSource();
        IWizardDescriptor desc = (IWizardDescriptor) itemgetData();
        try {
            IWorkbenchWizard wizard = desccreateWizard();
            wizardinit(thisworkbench thisselection);
            WizardDialog dialog = new WizardDialog(workbenchgetActiveWorkbenchWindow()getShell()
                    wizard);
            dialogopen();
        } catch (CoreException ex) {
            // TODO 處理異常
        }
    }
}

  這裡有幾個重點 是我自己摸索出來的

  第一個是IWorkbenchWindowPulldownDelegate是繼承IWorkbenchWindowPulldownDelegate的 因此只要實現這一個就可以在menu和coolbar個地方用了 實際上 如果你只在一個地方用的話 另外一個方法返回null就可以了 因為永遠不會被調用的 getMenu(Menu)是用在菜單的 getMenu(Control)是用在Coolbar的

  第二個就是getMenu(Menu)方法只會被調用一次 就是初始化的時候 而getMenu(Control)方法每次你打開菜單都會被調用 因此selectionChanged裡面也只需要處理菜單的內容 而不需要處理coolbar的內容

  第三就是selectionChanged的操作

   /** *//**
     * (nonJavadoc)
     * 
     * @see orgeclipseuiIActionDelegate#selectionChanged(orgeclipsejfaceactionIAction
     *      orgeclipsejfaceviewersISelection)
     */
    public void selectionChanged(IAction action ISelection selection) {
        thisselection = (IStructuredSelection) selection; [Page]
        if (parent != null) {
            // 找到新建菜單項
            // 重新創建其子菜單
            MenuItem[] items = parentgetItems();
            if (items != null) {
                MenuItem parentItem = null;
                for (int index =  count = itemslength; index < count; index++) {
                    MenuItem item = items[index];
                    Object data = itemgetData();
                    if (data instanceof ActionSetContributionItem) {
                        IContributionItem innerItem = ((ActionSetContributionItem) data)
                                getInnerItem();
if (innerItemgetId()equals(getClass()getName())) {
                            parentItem = item;
                            break;
                        } [Page]
                    }
                }
                if (parentItem != null) {
                    Menu menu = getMenu(parent);
                    parentItemsetMenu(menu);
                    parentItemsetImage(null);
                }
            }
        }
    }

  parent是在getMenu(menu)中記錄下來的 等於是上級菜單 說到這裡 我們來說一下SWT裡面菜單的構造(不一定對 只是我的理解而已)所有你可以看到的帶文字的條目都是MenuItem MenuItem分為 一種是沒有子菜單的 一種是有子菜單的

  沒有子菜單的很簡單 不說了 有子菜單的就是SWTCASCADE類型的 這個時候MenuItem會產生一個Menu 而Menu是一個容器 基本可以認為彈出菜單的整體 裡面可以包含很多MenuItem 就是這麼個關系

  說完這個 我們來看SelectionChanged方法 Parent是個Menu 實際上是[文件]菜單 在裡面查找id為類名的MenuItem 注意看Pluginxml的聲明 類名和ID是一致的 實際上找到的就是[新建]菜單 然後重新創建菜單 並且設置成為MenuItem的Menu 這樣就可以了

  實際上JDT就是這麼做的 但是具體的實現可能不一樣 我也沒有仔細的研究他的做法 因為系統比較龐大 研究的話時間太厲害了

  至於PopupMenus 處理的方式是差不多的 略微有些修改而已 這裡就不再把代碼貼出來了

  還有這一段

   IConfigurationElement element = (IConfigurationElement) wizard
                        getAdapter(IConfigurationElementclass);
                IConfigurationElement[] children = element [Page]
                        getChildren(IWorkbenchRegistryConstantsTAG_ENABLEMENT);
                if (children != null && childrenlength != {
                    IConfigurationElement enablement = children[];
                    ActionExpression exp = new ActionExpression(enablement);
                    if (!expisEnabledFor(thisselection)) {
                        continue;
                    }
                }

  Wizard裡面好像只能添加selection的限制 我這裡是解析了enablement的限制 和action一樣的 怎麼判斷看ActionExpression類就行了 我什麼都沒干 哈哈 因為JDT的NewWizard在任何情況下都可以進行 我的不可以 和選擇的對象有很大的關系 因此增強一下條件的聲明是必要的 順便說一句 你用Eclipse的工具創建 在NewWizard下沒辦法創建<enablement/>節點的 但是你再Pluginxml裡面寫好以後 extensions頁面卻可以認識 然後就可以在extensions頁面裡面改了


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28387.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.