我们有一位客户抱怨右键点击功能突然停止工作。所以我调试了一下,发现RCP应用程序没有抛出任何异常,只是右键单击menuItem监听器没有被调用。以下是我们在应用中使用的代码大纲。
rightClickListener = new Listener(){
public void handleEvent(Event event) {
TRACER.trace("Handle event for tree's right click listener");
if(treeComp.tree.getSelectionCount()>0 && PlatformUI.getPreferenceStore().getBoolean("RightClickEnabled")){
TRACER.trace(currSelection + " selected.");
rcmenu.selectionMenu(event);
}
}
};
treeComp.tree.addListener(SWT.MenuDetect,rightClickListener);
实际的菜单和菜单项是在rcmenu类中创建的。听众被添加到那里。
public void selectionMenu(Event event){
TRACER.trace("Begin selectionMenu()");
shell = tree.getShell();
display = tree.getDisplay();
Menu menu = null;
try{
menu = new Menu(shell, SWT.POP_UP);
}catch(Exception e){
ERROR_REPORTER.report("Error when creating menu ", e);
}
menu.addDisposeListener(new DisposeListener(){
@Override
public void widgetDisposed(DisposeEvent e) {
TRACER.trace("Menu Disposed");
}
});
TreeItem[] selectionItems = tree.getSelection();
if(selectionItems.length=1){
addMenuItems(menu);
}
handleSetEnableLogic(); //after adding the menu items in addMenuItems(menu) we enable them here in this method.
menu.setLocation(event.x, event.y);
menu.setVisible(true);
try{
while (!menu.isDisposed() && menu.isVisible()) {
boolean readAndDispatch = display.readAndDispatch();
if (!readAndDispatch){
display.sleep();
}
}
}catch(Exception e){
ERROR_REPORTER.report("Error during dispatch event ",e);
}
try{
menu.dispose();
}catch(Exception e){
ERROR_REPORTER.report("Error during menu dispose ",e);
}
TRACER.trace("End selectionMenu()");
}
addMenuItems()方法如图所示
item_modify = new MenuItem(menu, SWT.PUSH);
item_modify.setText("Modify"); //Modify
//"Modify"
item_modify.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
BusyIndicator.showWhile(Display.getCurrent(), new Runnable(){
public void run(){
TRACER.trace("Handle event for right click menu-- modify: ");
//listener code
}
});
}
});
item_modify.setEnabled(false);
正在创建右键菜单,启用了item_modify菜单项。什么都没有处理。当我们选择item_modify菜单项时,display.readAndDispatch返回true,因此显示不会进入休眠状态。但是在那时,item_modify的选择监听器没有被触发。然后菜单变得不可见并从while循环中出来并按预期处理。但关键是我不明白为什么选择听众没有被解雇。有没有办法知道一个事件是否被解雇?计算机上的任何组策略是否会影响事件的触发方式?
应用程序中的每个其他侦听器都可以正常工作。