关于Eclipse中新建菜单的实现

新建菜单里面都是声明过NewWizard的东东.

不过既然已经声明了NewWizard还要在ActionSet或者PopupMenus里面再声明一遍不是很痛苦?

其实可以如下做法:
先声明一个PullDown的菜单.
          < action
               
class ="xxx.NewAction"
               hoverIcon
="icons/full/objects/new_project.gif"
               id
="xxx.NewAction"
               label
="新建(&amp;N)"
               menubarPath
="xxx.menus.file/sep1"
               style
="pulldown"
               toolbarPath
="sep1" >
         
</ action >

如果这个菜单用Coolbar, 那么需要继承IWorkbenchWindowPulldownDelegate接口, 如果要用在Menu上, 那么继承IWorkbenchWindowPulldownDelegate2接口.实现基本是一样的
public   class  NewAction  implements  IWorkbenchWindowPulldownDelegate2, SelectionListener  {
    
private IWorkbench workbench;

    @SuppressWarnings(
"unused")
    
private IWorkbenchWindow window;

    
private Menu parent = null;

    
private Menu inMenu = null;

    
private Menu inToolbar = null;

    
private IStructuredSelection selection;

    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
     
*/

    
public void dispose() {
        
if (inMenu != null{
            inMenu.dispose();
            inMenu 
= null;
        }

        
this.workbench = null;
        
this.window = null;
    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
     
*/

    
public void init(IWorkbenchWindow window) {
        
this.window = window;
        
this.workbench = window.getWorkbench();
    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
     
*/

    
public void run(IAction action) {
    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
     *      org.eclipse.jface.viewers.ISelection)
     
*/

    
public void selectionChanged(IAction action, ISelection selection) {
        
this.selection = (IStructuredSelection) selection;
        
if (parent != null{
            
// 找到新建菜单项
            
// 重新创建其子菜单
            MenuItem[] items = parent.getItems();
            
if (items != null{
                MenuItem parentItem 
= null;
                
for (int index = 0, count = items.length; index < count; index++{
                    MenuItem item 
= items[index];
                    Object data 
= item.getData();
                    
if (data instanceof ActionSetContributionItem) {
                        IContributionItem innerItem 
= ((ActionSetContributionItem) data)
                                .getInnerItem();
                        
if (innerItem.getId().equals(getClass().getName())) {
                            parentItem 
= item;
                            
break;
                        }

                    }

                }

                
if (parentItem != null{
                    Menu menu 
= getMenu(parent);
                    parentItem.setMenu(menu);
                    parentItem.setImage(
null);
                }

            }

        }

    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IWorkbenchWindowPulldownDelegate#getMenu(org.eclipse.swt.widgets.Control)
     
*/

    
public Menu getMenu(Control parent) {
        
if (inToolbar != null)
            inToolbar.dispose();

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


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IWorkbenchWindowPulldownDelegate2#getMenu(org.eclipse.swt.widgets.Menu)
     
*/

    
public Menu getMenu(Menu parent) {
        
if (inMenu != null)
            inMenu.dispose();

        
this.parent = parent;
        inMenu 
= new Menu(parent);
        
return createMenu(inMenu);
    }


    
/**
     * 
@param parent
     * 
@return
     
*/

    
private Menu createMenu(Menu menu) {
        
boolean hasMenu = false;
        IWizardRegistry registry 
= workbench.getNewWizardRegistry();
        IWizardCategory rootCategory 
= registry.getRootCategory();
        IWizardCategory[] categories 
= rootCategory.getCategories();
        
if (categories != null{
            reverseArray(categories);
            
for (IWizardCategory category : categories) {
                hasMenu 
= createMenuItems(menu, category, hasMenu) || hasMenu;
            }

        }

        
if (hasMenu)
            
new MenuItem(menu, SWT.SEPARATOR);

        MenuItem mnuOther 
= new MenuItem(menu, SWT.NONE);
        mnuOther.setText(
"其他(&R)...");
        mnuOther.addSelectionListener(
new SelectionAdapter() {
            
/**
             * (non-Javadoc)
             * 
             * 
@see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             
*/

            @Override
            
public void widgetSelected(SelectionEvent e) {
                NewWizardDialog dialog 
= new NewWizardDialog(workbench.getActiveWorkbenchWindow()
                        .getShell(), selection);
                dialog.open();
            }

        }
);
        
return menu;
    }


    
/**
     * 创建菜单
     * 
     * 
@param menu
     * 
@param category
     * 
@param hasMenu 是否在之前已经有菜单
     * 
@return 是否成功创建了菜单
     
*/

    
private boolean createMenuItems(Menu menu, IWizardCategory category, boolean hasMenu) {
        
boolean create = false;
        IWizardDescriptor[] wizards 
= category.getWizards();
        
if (wizards != null{
            reverseArray(wizards);
            List
<IWizardDescriptor> shown = new ArrayList<IWizardDescriptor>();

            
for (IWizardDescriptor wizard : wizards) {
                IConfigurationElement element 
= (IConfigurationElement) wizard
                        .getAdapter(IConfigurationElement.
class);
                IConfigurationElement[] children 
= element
                        .getChildren(IWorkbenchRegistryConstants.TAG_ENABLEMENT);
                
if (children != null && children.length != 0{
                    IConfigurationElement enablement 
= children[0];
                    ActionExpression exp 
= new ActionExpression(enablement);
                    
if (!exp.isEnabledFor(this.selection)) {
                        
continue;
                    }

                }

                shown.add(wizard);
            }


            
if (shown.size() != 0{
                create 
= true;
                
if (hasMenu) {
                    
new MenuItem(menu, SWT.SEPARATOR);
                }


                
for (IWizardDescriptor wizard : shown) {
                    MenuItem item 
= new MenuItem(menu, SWT.NONE);
                    item.setText(wizard.getLabel());
                    
if (wizard.getImageDescriptor() != null)
                        item.setImage(wizard.getImageDescriptor().createImage());
                    item.setData(wizard);
                    item.addSelectionListener(
this);
                }

            }

        }

        
return create;
    }


    
/**
     * 反转数组
     * 
     * 
@param array
     
*/

    
private void reverseArray(Object[] array) {
        
if (array != null{
            
int count = array.length;
            
int last = count - 1;
            
for (int index = 0; index < count / 2; index++{
                Object temp 
= array[index];
                array[index] 
= array[last - index];
                array[last] 
= temp;
            }

        }

    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
     
*/

    
public void widgetDefaultSelected(SelectionEvent e) {
        
// do nothing
    }


    
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
     
*/

    
public void widgetSelected(SelectionEvent e) {
        MenuItem item 
= (MenuItem) e.getSource();
        IWizardDescriptor desc 
= (IWizardDescriptor) item.getData();
        
try {
            IWorkbenchWizard wizard 
= desc.createWizard();
            wizard.init(
this.workbench, this.selection);
            WizardDialog dialog 
= new WizardDialog(workbench.getActiveWorkbenchWindow().getShell(),
                    wizard);
            dialog.open();
        }
 catch (CoreException ex) {
            
// TODO 处理异常
        }

    }

}


这里有几个重点, 是我自己摸索出来的.
第一个是IWorkbenchWindowPulldownDelegate2是继承IWorkbenchWindowPulldownDelegate的, 因此只要实现这一个就可以在menu和coolbar2个地方用了. 实际上, 如果你只在一个地方用的话, 另外一个方法返回null就可以了. 因为永远不会被调用的. getMenu(Menu)是用在菜单的, getMenu(Control)是用在Coolbar的.

第二个就是getMenu(Menu)方法只会被调用一次, 就是初始化的时候, 而getMenu(Control)方法每次你打开菜单都会被调用. 因此selectionChanged里面也只需要处理菜单的内容, 而不需要处理coolbar的内容.
 
第三就是selectionChanged的操作
/**
     * (non-Javadoc)
     * 
     * 
@see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
     *      org.eclipse.jface.viewers.ISelection)
     
*/

    
public   void  selectionChanged(IAction action, ISelection selection) ... {
        
this.selection = (IStructuredSelection) selection;
        
if (parent != null) ...{
            
// 找到新建菜单项
            
// 重新创建其子菜单
            MenuItem[] items = parent.getItems();
            
if (items != null) ...{
                MenuItem parentItem 
= null;
                
for (int index = 0, count = items.length; index < count; index++) ...{
                    MenuItem item 
= items[index];
                    Object data 
= item.getData();
                    
if (data instanceof ActionSetContributionItem) ...{
                        IContributionItem innerItem 
= ((ActionSetContributionItem) data)
                                .getInnerItem();
                        
if (innerItem.getId().equals(getClass().getName())) ...{
                            parentItem 
= item;
                            
break;
                        }

                    }

                }

                
if (parentItem != null) ...{
                    Menu menu 
= getMenu(parent);
                    parentItem.setMenu(menu);
                    parentItem.setImage(
null);
                }

            }

        }

    }

parent是在getMenu(menu)中记录下来的, 等于是上级菜单. 说到这里, 我们来说一下SWT里面菜单的构造(不一定对, 只是我的理解而已):
所有你可以看到的带文字的条目都是MenuItem. MenuItem分为2种, 一种是没有子菜单的, 一种是有子菜单的.
没有子菜单的很简单, 不说了. 有子菜单的就是SWT.CASCADE类型的. 这个时候MenuItem会产生一个Menu, 而Menu是一个容器. 基本可以认为弹出菜单的整体. 里面可以包含很多MenuItem. 就是这么个关系.
说完这个, 我们来看SelectionChanged方法. Parent是个Menu, 实际上是[文件]菜单, 在里面查找id为类名的MenuItem, 注意看Plugin.xml的声明, 类名和ID是一致的. 实际上找到的就是[新建]菜单. 然后重新创建菜单. 并且设置成为MenuItem的Menu. 这样就可以了.

实际上JDT就是这么做的, 但是具体的实现可能不一样. 我也没有仔细的研究他的做法, 因为系统比较庞大, 研究的话时间太厉害了.

至于PopupMenus, 处理的方式是差不多的, 略微有些修改而已, 这里就不再把代码贴出来了.

还有这一段
 IConfigurationElement element = (IConfigurationElement) wizard
                        .getAdapter(IConfigurationElement.class);
                IConfigurationElement[] children = element
                        .getChildren(IWorkbenchRegistryConstants.TAG_ENABLEMENT);
                if (children != null && children.length != 0) ...{
                    IConfigurationElement enablement = children[0];
                    ActionExpression exp = new ActionExpression(enablement);
                    if (!exp.isEnabledFor(this.selection)) ...{
                        continue;
                    }
                }

Wizard里面好像只能添加selection的限制. 我这里是解析了enablement的限制, 和action一样的, 怎么判断看ActionExpression类就行了, 我什么都没干, 哈哈. 因为JDT的NewWizard在任何情况下都可以进行, 我的不可以, 和选择的对象有很大的关系, 因此增强一下条件的声明是必要的. 顺便说一句, 你用Eclipse的工具创建, 在NewWizard下没办法创建<enablement/>节点的, 但是你再Plugin.xml里面写好以后, extensions页面却可以认识, 然后就可以在extensions页面里面改了.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值