Search code examples
javagwtpopupsubmenumenubar

How can I access a GWT menubar popup panel / submenu?


I'm trying to add some mouse listeners to the sub menus/ cascading menus of GWT's MenuBar. Sadly, I cannot seem to access the submenu popuppanel directly - the method to do so (getPopup() ) is private. And you can't access it via reflection due to the way GWT compiles.

Adding a mouse listener to the main menu bar (to detect when the mouse is inside the menu bar boundaries) was nice and simple. But I can't figure out any way to add a mouse listener to tell when the mouse is inside one of the cascading sub menus.

What I am doing is this:

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

This works great for the actual GWT MenuBar. When I mouse in, the mouseOverEvent triggers. When I mouse out, the MouseOutEvent triggers.

The problem is that if I open a submenu from the main menubar, mousing into that menu will also trigger the MouseOutEvent. I need it not to do that.

When I say submenu I mean something like the ones seen here:

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

So as long as I'm in the 'main' bar that lists Style, Fruit, and Term, the mouse events recognize this.

But if I drop down to the sub menu that says Bold, Italicized, More, the mouse events believe I have left the menu bar entirely. I need a way to determine if the mouse is inside one of these submenus. (Or that a submenu of this main menu bar is open somewhere)

You cannot simply do

myMainBar.getPopup()

and add listeners to the resulting PopupPanel as getPopup is private. I'm looking for another way to get to MenuBar.popup

It seems there is no method to tell if one of the sub menus is open, as well, which is a bit perplexing to me. There seems to be a frustrating lack of ability to interact with these submenus, and I am wondering if I am missing something.


Solution

  • If you add a MouseOverHandler and MouseOutHandler to each of your submenus as opposed to your main menu bar it should do what you want.

    For example:

    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);