在SWTBot中,触发右键菜单是简单的task,但是当要触发contextMenu的二级菜单时,就会出现问题,原因可能是事件的丢失,诸如下面的菜单:
Tree
TreeItem1
TreeItem2
想要在TreeItem2上触发SOMA->SOMA sub menu是困难的,下面是我的解决方案(从SWTBot 论坛上抄出来的呵呵http://www.eclipse.org/forums/index.php?t=msg&goto=629948&S=96549f36b839765eb99c047d8b51151c)
经验是,不能直接传入TreeItem, 要把整个Tree node传入才行
String[] paths={"SOMA-ME","Extract SOMA Service Model Elements"};
ContextMenuHelper.clickContextMenu(projectTree,paths);
ContextMenuHelper 源代码:
package com.ibm.asset.adit.mdhi.test.util; import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.instanceOf; import java.util.Arrays; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.VoidResult; import org.eclipse.swtbot.swt.finder.results.WidgetResult; import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot; import org.hamcrest.Matcher; public class ContextMenuHelper { /** * Clicks the context menu matching the text. * * @param text * the text on the context menu. * @throws WidgetNotFoundException * if the widget is not found. */ public static void clickContextMenu(final AbstractSWTBot<?> bot, final String... texts) { // show final MenuItem menuItem = UIThreadRunnable .syncExec(new WidgetResult<MenuItem>() { public MenuItem run() { MenuItem menuItem = null; Control control = (Control) bot.widget; Menu menu = control.getMenu(); for (String text : texts) { Matcher<?> matcher = allOf( instanceOf(MenuItem.class), withMnemonic(text)); menuItem = show(menu, matcher); if (menuItem != null) { menu = menuItem.getMenu(); } else { hide(menu); break; } } return menuItem; } }); if (menuItem == null) { throw new WidgetNotFoundException("Could not find menu: " + Arrays.asList(texts)); } // click click(menuItem); // hide UIThreadRunnable.syncExec(new VoidResult() { public void run() { hide(menuItem.getParent()); } }); } private static MenuItem show(final Menu menu, final Matcher<?> matcher) { if (menu != null) { menu.notifyListeners(SWT.Show, new Event()); MenuItem[] items = menu.getItems(); for (final MenuItem menuItem : items) { if (matcher.matches(menuItem)) { return menuItem; } } menu.notifyListeners(SWT.Hide, new Event()); } return null; } private static void click(final MenuItem menuItem) { final Event event = new Event(); event.time = (int) System.currentTimeMillis(); event.widget = menuItem; event.display = menuItem.getDisplay(); event.type = SWT.Selection; UIThreadRunnable.asyncExec(menuItem.getDisplay(), new VoidResult() { public void run() { menuItem.notifyListeners(SWT.Selection, event); } }); } private static void hide(final Menu menu) { menu.notifyListeners(SWT.Hide, new Event()); if (menu.getParentMenu() != null) { hide(menu.getParentMenu()); } } }