如何访问GWT菜单栏弹出式面板/子菜单?

时间:2014-06-19 18:18:48

标签: java gwt popup submenu menubar

我试图将一些鼠标监听器添加到GWT的MenuBar的子菜单/级联菜单中。可悲的是,我似乎无法直接访问子菜单popuppanel - 这样做的方法(getPopup())是私有的。由于GWT编译的方式,你无法通过反射访问它。

将鼠标监听器添加到主菜单栏(以检测鼠标何时位于菜单栏边界内)非常简单。但我无法找出任何方法来添加一个鼠标监听器来告诉鼠标何时进入其中一个级联子菜单。

我正在做的是:

com.google.gwt.user.client.ui.MenuBar myMainBar = new MenuBar();
myMainBar.addDomHandler(menuHoverOutHandler, MouseOutEvent.getType());
myMainBar.addDomHandler(menuHoverOverHandler, MouseOverEvent.getType());

这适用于实际的GWT MenuBar。当我鼠标进入时,mouseOverEvent会触发。当我鼠标移出时,MouseOutEvent会触发。

问题在于,如果我从主菜单栏打开一个子菜单,鼠标进入该菜单也会触发MouseOutEvent。我不需要那样做。

当我说子菜单时,我指的是像这里看到的那样:

http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/MenuBar.html

只要我在主要的'列出样式,水果和术语的栏,鼠标事件识别这一点。

但是,如果我下到菜单上显示Bold,Italicized,More,则鼠标事件相信我完全离开了菜单栏。我需要一种方法来确定鼠标是否位于其中一个子菜单中。 (或者这个主菜单栏的子菜单在某处打开)

你不能简单地做

myMainBar.getPopup()

并将侦听器添加到生成的PopupPanel中,因为getPopup是私有的。我正在寻找另一种方法来访问MenuBar.popup

似乎没有方法可以判断其中一个子菜单是否打开,这对我来说有点令人困惑。似乎有一种令人沮丧的缺乏与这些子菜单交互的能力,我想知道我是否遗漏了一些东西。

2 个答案:

答案 0 :(得分:4)

如果您在每个子菜单中添加MouseOverHandlerMouseOutHandler而不是主菜单栏,则应该执行您想要的操作。

例如:

MenuBar subMenu = new MenuBar(true);
subMenu.addItem("Item1", new Command() {
    @Override
    public void execute() {
        Window.alert("Item1 clicked");
    }
});

subMenu.addDomHandler(new MouseOverHandler() {
    @Override
    public void onMouseOver(MouseOverEvent arg0) {
        Window.alert("SubMenu over!");
    }
}, MouseOverEvent.getType());

subMenu.addDomHandler(new MouseOutHandler() {
    @Override
    public void onMouseOut(MouseOutEvent arg0) {
        Window.alert("SubMenu out!");
    }
}, MouseOutEvent.getType());

MenuBar mainMenu = new MenuBar();
mainMenu.addItem("SubMenu", subMenu);

RootPanel.get().add(mainMenu);

答案 1 :(得分:2)

您的问题与其自身的事件逻辑有关:您希望有一种新类型的事件,只有当鼠标移出菜单时才会触发,而如果它在菜单之间移动则不会触发。

要做到这一点,您可以添加侦听mouve和mouse out的代码,并编译可用信息以了解正在发生的事情。

您可以确保在使用Scheduler

传递所有事件后执行代码
 Scheduler.get().scheduleDeferred(new Command() {
    public void execute () {
      //check all what happened in a static shared variable, there was a mouse out, was there a mouse over after it? if yes then stay calm; If there wasn't, then trigger a MouseOutOfAllMenus event
    }
  });

此代码段应放在onMouseOut()内,而另一个仅更新静态类实例状态的代码应放在onMouseOver()中。由于Scheduling延迟机制,您可以确保Scheduler.execute()中的代码将在onMouseOver()执行后执行。所以当你来检查状态时,它会在鼠标进入另一个菜单后(或没有);因此,您可以知道用户是否确实离开了菜单项,或者他是否已进入子菜单。

最后推荐:在单独的类中执行此代码,以便您可以将此丰富菜单作为组件提供以供将来使用。另外请记住,通过保持独立性,您可以更轻松地测试和运行自动化测试场景。

我希望你理解我试图解释的所有内容,如果没有,请随意发表评论,我会尽力回答你

最诚挚的问候,

p.s:当我说一个静态实例状态时,它只是为了便于理解。当然建议避免静态使用,以便在同一个应用程序中有多个菜单。静态我的意思是:所有组件都可以访问的实例