java

位置:IT落伍者 >> java >> 浏览文章

关于Eclipse中新建菜单的实现方法


发布日期:2022年11月05日
 
关于Eclipse中新建菜单的实现方法

新建菜单里面都是声明过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接口实现基本是一样的

publicclassNewActionimplementsIWorkbenchWindowPulldownDelegateSelectionListener{

privateIWorkbenchworkbench;

@SuppressWarnings(\unused\)

privateIWorkbenchWindowwindow;

privateMenuparent=null;

privateMenuinMenu=null;

privateMenuinToolbar=null;

privateIStructuredSelectionselection;

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIWorkbenchWindowActionDelegate#dispose()

*/

publicvoiddispose(){

if(inMenu!=null){

inMenudispose();

inMenu=null;

} [Page]

thisworkbench=null;

thiswindow=null;

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIWorkbenchWindowActionDelegate#init(orgeclipseuiIWorkbenchWindow)

*/

publicvoidinit(IWorkbenchWindowwindow){

thiswindow=window;

thisworkbench=windowgetWorkbench();

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIActionDelegate#run(orgeclipsejfaceactionIAction)

*/

publicvoidrun(IActionaction){

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIActionDelegate#selectionChanged(orgeclipsejfaceactionIAction

*orgeclipsejfaceviewersISelection)

*/

publicvoidselectionChanged(IActionactionISelectionselection){

thisselection=(IStructuredSelection)selection;

if(parent!=null){

//找到新建菜单项

//重新创建其子菜单

MenuItem[]items=parentgetItems();

if(items!=null){

MenuItemparentItem=null;

for(intindex=count=itemslength;index<count;index++){ [Page]

MenuItemitem=items[index];

Objectdata=itemgetData();

if(datainstanceofActionSetContributionItem){

IContributionIteminnerItem=((ActionSetContributionItem)data)

getInnerItem();

if(innerItemgetId()equals(getClass()getName())){

parentItem=item;

break;

}

}

}

if(parentItem!=null){

Menumenu=getMenu(parent);

parentItemsetMenu(menu);

parentItemsetImage(null); [Page]

}

}

}

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIWorkbenchWindowPulldownDelegate#getMenu(orgeclipseswtwidgetsControl)

*/

publicMenugetMenu(Controlparent){

if(inToolbar!=null)

inToolbardispose();

inToolbar=newMenu(parent);

returncreateMenu(inToolbar);

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIWorkbenchWindowPulldownDelegate#getMenu(orgeclipseswtwidgetsMenu)

*/

publicMenugetMenu(Menuparent){

if(inMenu!=null)

inMenudispose();

thisparent=parent;

inMenu=newMenu(parent);

returncreateMenu(inMenu);

}

/***//**

*@paramparent

*@return

*/

privateMenucreateMenu(Menumenu){

booleanhasMenu=false;

IWizardRegistryregistry=workbenchgetNewWizardRegistry();

IWizardCategoryrootCategory=registrygetRootCategory();

IWizardCategory[]categories=rootCategorygetCategories(); [Page]

if(categories!=null){

reverseArray(categories);

for(IWizardCategorycategory:categories){

hasMenu=createMenuItems(menucategoryhasMenu)||hasMenu;

}

}

if(hasMenu)

newMenuItem(menuSWTSEPARATOR);

MenuItemmnuOther=newMenuItem(menuSWTNONE);

mnuOthersetText(\其他(&R)\);

mnuOtheraddSelectionListener(newSelectionAdapter(){

/***//**

*(nonJavadoc)

*

*@seeorgeclipseswteventsSelectionAdapter#widgetSelected(orgeclipseswteventsSelectionEvent)

*/

@Override

publicvoidwidgetSelected(SelectionEvente){

NewWizardDialogdialog=newNewWizardDialog(workbenchgetActiveWorkbenchWindow()

getShell()selection);

dialogopen();

}

}); [Page]

returnmenu;

}

/***//**

*创建菜单

*

*@parammenu

*@paramcategory

*@paramhasMenu是否在之前已经有菜单

*@return是否成功创建了菜单

*/

privatebooleancreateMenuItems(MenumenuIWizardCategorycategorybooleanhasMenu){

booleancreate=false;

IWizardDescriptor[]wizards=categorygetWizards();

if(wizards!=null){

reverseArray(wizards);

List<IWizardDescriptor>shown=newArrayList<IWizardDescriptor>();

for(IWizardDescriptorwizard:wizards){

IConfigurationElementelement=(IConfigurationElement)wizard

getAdapter(IConfigurationElementclass);

IConfigurationElement[]children=element

getChildren(IWorkbenchRegistryConstantsTAG_ENABLEMENT);

if(children!=null&&childrenlength!=){

IConfigurationElementenablement=children[];

ActionExpressionexp=newActionExpression(enablement); [Page]

if(!expisEnabledFor(thisselection)){

continue;

}

}

shownadd(wizard);

}

if(shownsize()!=){

create=true;

if(hasMenu){

newMenuItem(menuSWTSEPARATOR);

}

for(IWizardDescriptorwizard:shown){

MenuItemitem=newMenuItem(menuSWTNONE);

itemsetText(wizardgetLabel());

if(wizardgetImageDescriptor()!=null)

itemsetImage(wizardgetImageDescriptor()createImage());

itemsetData(wizard);

itemaddSelectionListener(this); [Page]

}

}

}

returncreate;

}

/***//**

*反转数组

*

*@paramarray

*/

privatevoidreverseArray(Object[]array){

if(array!=null){

intcount=arraylength;

intlast=count;

for(intindex=;index<count/;index++){

Objecttemp=array[index];

array[index]=array[lastindex];

array[last]=temp;

}

}

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseswteventsSelectionListener#widgetDefaultSelected(orgeclipseswteventsSelectionEvent)

*/

publicvoidwidgetDefaultSelected(SelectionEvente){

//donothing

}

/***//**

*(nonJavadoc)

*

*@seeorgeclipseswteventsSelectionListener#widgetSelected(orgeclipseswteventsSelectionEvent)

*/ [Page]

publicvoidwidgetSelected(SelectionEvente){

MenuItemitem=(MenuItem)egetSource();

IWizardDescriptordesc=(IWizardDescriptor)itemgetData();

try{

IWorkbenchWizardwizard=desccreateWizard();

wizardinit(thisworkbenchthisselection);

WizardDialogdialog=newWizardDialog(workbenchgetActiveWorkbenchWindow()getShell()

wizard);

dialogopen();

}catch(CoreExceptionex){

//TODO处理异常

}

}

}

这里有几个重点 是我自己摸索出来的

第一个是IWorkbenchWindowPulldownDelegate是继承IWorkbenchWindowPulldownDelegate的 因此只要实现这一个就可以在menu和coolbar个地方用了 实际上 如果你只在一个地方用的话 另外一个方法返回null就可以了 因为永远不会被调用的 getMenu(Menu)是用在菜单的 getMenu(Control)是用在Coolbar的

第二个就是getMenu(Menu)方法只会被调用一次 就是初始化的时候 而getMenu(Control)方法每次你打开菜单都会被调用 因此selectionChanged里面也只需要处理菜单的内容 而不需要处理coolbar的内容

第三就是selectionChanged的操作

/***//**

*(nonJavadoc)

*

*@seeorgeclipseuiIActionDelegate#selectionChanged(orgeclipsejfaceactionIAction

*orgeclipsejfaceviewersISelection)

*/

publicvoidselectionChanged(IActionactionISelectionselection){

thisselection=(IStructuredSelection)selection; [Page]

if(parent!=null){

//找到新建菜单项

//重新创建其子菜单

MenuItem[]items=parentgetItems();

if(items!=null){

MenuItemparentItem=null;

for(intindex=count=itemslength;index<count;index++){

MenuItemitem=items[index];

Objectdata=itemgetData();

if(datainstanceofActionSetContributionItem){

IContributionIteminnerItem=((ActionSetContributionItem)data)

getInnerItem();

if(innerItemgetId()equals(getClass()getName())){

parentItem=item;

break;

} [Page]

}

}

if(parentItem!=null){

Menumenu=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 处理的方式是差不多的 略微有些修改而已 这里就不再把代码贴出来了

还有这一段

IConfigurationElementelement=(IConfigurationElement)wizard

getAdapter(IConfigurationElementclass);

IConfigurationElement[]children=element [Page]

getChildren(IWorkbenchRegistryConstantsTAG_ENABLEMENT);

if(children!=null&&childrenlength!=){

IConfigurationElementenablement=children[];

ActionExpressionexp=newActionExpression(enablement);

if(!expisEnabledFor(thisselection)){

continue;

}

}

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

               

上一篇:Struts模块化编程经典实战教程(一)

下一篇:关于junit实现过程详细介绍