How to make GWT MenuBar automatically display submenus?

We recently added the GWT MenuBar to part of our application, for which the menus were used.

Basically, I want the submenu to open when you hover over the top-level menu, which is easy enough to do:

menubar.setAutoOpen(true);

I would also like the submenu to hide automatically when the user mouse leaves the submenu. Ideally, with some delay to prevent its sudden disappearance, but I would only agree to hide.

This does not seem to be inlined, but the MenuItem in GWT directly subclasses UIObject, which means there is no relatively trivial onBrowserEvent () or somewhere to attach the mouse. Perhaps an extension of MenuItem and sinking / incompatible events would allow me to add this behavior, but I'm not sure if this is the best approach.

So what would be the best approach to auto-adjusting the GWT submenu?

Thanks.

+3
source share
4 answers

After a big horrible hack trying to achieve something similar, we wrote our cascading menu as part of the GWT portlet framework . It displays menu items and submenus from an HTML template that look something like this:

<a href="#home">Home</a>
<a href="#submenu1()">Sub Menu 1</a>
<a href="#away">Away</a>

<div id="submenu1">
    <a href="#hello_world">Hello World</a>
    <a href="#free_memory">Free Memory</a>
    <a href="#submenu2()">Sub Menu 2</a>
</div>

<div id="submenu2">
    <a href="#command_demo">Command Demo</a>
    <a href="#command1()">Command1</a>
    <a href="#command2(arg1,arg2)">Command2</a>
</div>

URL-, , CommandEvent. , . -, .

+2

, , :

public class MyMenuBar extends Composite {

    private class OpenTab implements ScheduledCommand {
        private String wid;

        public OpenTab(String windowId) {
            wid = windowId;
        }

        @Override
        public void execute() {
            WinUtl.newAppTab(wid);
        }
    }

    interface MyMenuBarUiBinder extends UiBinder<Widget, MyMenuBar> {}

    private static MyMenuBarUiBinder uiBinder =
                                GWT.create(MyMenuBarUiBinder.class);

    @UiField MenuBar mainMenu;

    @UiField MenuBar subsMenu;
    @UiField MenuItem subsChoice1;
    @UiField MenuItem subsChoice2;
    @UiField MenuItem subsChoice3;

    @UiField MenuBar svcPrvdrMenu;
    @UiField MenuItem svcPrvdrChoice1;
    @UiField MenuItem svcPrvdrChoice2;

    @UiField MenuBar netMgtMenu;
    @UiField MenuItem netMgtChoice1;

    @UiField MenuBar reportsMenu;
    @UiField MenuItem reportsChoice1;

    @UiField MenuBar auditsMenu;
    @UiField MenuItem auditsChoice1;

    @UiField MenuBar securityMenu;
    @UiField MenuItem securityChoice1;

    @UiField MenuBar helpMenu;
    @UiField MenuItem helpChoice1;

    private boolean subMenuPopped = false;
    private boolean subMenuEntered = false;

    private static Type<MouseOverHandler> OVR_EVT = MouseOverEvent.getType();
    private static Type<MouseOutHandler> OUT_EVT = MouseOutEvent.getType();

    private MouseOverHandler mainOverHandler = new MouseOverHandler() {
        @Override
        public void onMouseOver(MouseOverEvent event) {
            subMenuPopped = true;
        }
    };

    private MouseOutHandler mainOutHandler = new MouseOutHandler() {
        @Override
        public void onMouseOut(MouseOutEvent event) {
            Element e = event.getRelativeElement()
            boolean movedUp = (event.getRelativeY(e) < 0);
            if ((movedUp && subMenuPopped) || subMenuEntered) {
                subMenuPopped = false;
                subMenuEntered = false;
                mainMenu.closeAllChildren(true);
            }
        }
    };

    private MouseOverHandler subOverHandler = new MouseOverHandler() {
        @Override
        public void onMouseOver(MouseOverEvent event) {
            subMenuEntered = true;
        }
    };

    private MouseOutHandler subOutHandler = new MouseOutHandler() {
        @Override
        public void onMouseOut(MouseOutEvent event) {
            subMenuPopped = false;
            subMenuEntered = false;
            mainMenu.closeAllChildren(true);
        }
    };

    public MyMenuBar() {
        initWidget(uiBinder.createAndBindUi(this));

        mainMenu.addStyleName("npac-MenuBar");
        mainMenu.setAutoOpen(true);
        mainMenu.setAnimationEnabled(true);
        mainMenu.setFocusOnHoverEnabled(true);

        subsChoice1.setScheduledCommand(new OpenTab(Names.Wid.NPA));

        mainMenu.addDomHandler(mainOverHandler, OVR_EVT);
        mainMenu.addDomHandler(mainOutHandler, OUT_EVT);

        addHandlers(subsMenu);
        addHandlers(svcPrvdrMenu);
        addHandlers(netMgtMenu);
        addHandlers(reportsMenu);
        addHandlers(auditsMenu);
        addHandlers(securityMenu);
        addHandlers(helpMenu);
    }

    private void addHandlers(MenuBar m) {
        m.addDomHandler(subOverHandler, OVR_EVT);
        m.addDomHandler(subOutHandler, OUT_EVT);
    }
}

, mouseOver subMenu, UP, off mainMenu (subMenu ). , subMenu ( ) , , ; -)

+2

CSS JAVA MenuBar . " + " mouseOut .

, , - ((JMenu) e.getSource()). doClick(); mouseEntered JMenu, mouseExited, MouseListener MenuItems, JMenu. ( MenuBar - JMenu).

, , MouseExit "" , (.. Child).

:

, , "isMouseOut" , MouseListener OO MouseIn -MouseOut . menuClear , "isMouseOut". MouseListener. .

ArrayList, . :

    Font menuFont = new Font("Arial", Font.PLAIN, 12);
    JMenuBar menuBar = new JMenuBar();
    getContentPane().add(menuBar, BorderLayout.NORTH); 

// Array of MenuItems
    ArrayList<JMenuItem> aMenuItms = new ArrayList<JMenuItem>();
    JMenuItem mntmRefresh = new JMenuItem("Refresh");
    JMenuItem mntmNew = new JMenuItem("New");
    JMenuItem mntmNormal = new JMenuItem("Normal");
    JMenuItem mntmMax = new JMenuItem("Max");
    JMenuItem mntmStatus = new JMenuItem("Status");
    JMenuItem mntmFeedback = new JMenuItem("Send Feedback");
    JMenuItem mntmEtsyTWebsite = new JMenuItem("EtsyT website");
    JMenuItem mntmAbout = new JMenuItem("About");

    aMenuItms.add(mntmRefresh);
    aMenuItms.add(mntmNew);
    aMenuItms.add(mntmNormal);
    aMenuItms.add(mntmMax);
    aMenuItms.add(mntmStatus);
    aMenuItms.add(mntmFeedback);
    aMenuItms.add(mntmEtsyTWebsite);
    aMenuItms.add(mntmAbout);

, MouseListener, for():

  for (Component c : aMenuItms) {
        if (c instanceof JMenuItem) {
            c.addMouseListener(ml);
        }
    }

JMenu MenuBar:

// Now set JMenu parents on MenuBar
    final JMenu mnFile = new JMenu("File");
    menuBar.add(mnFile).setFont(menuFont);
    final JMenu mnView = new JMenu("View");
    menuBar.add(mnView).setFont(menuFont);
    final JMenu mnHelp = new JMenu("Help");
    menuBar.add(mnHelp).setFont(menuFont);

Items JMenu:

// Now set menuItems as children of JMenu parents
    mnFile.add(mntmRefresh).setFont(menuFont);
    mnFile.add(mntmNew).setFont(menuFont);
    mnView.add(mntmNormal).setFont(menuFont);
    mnView.add(mntmMax).setFont(menuFont);
    mnHelp.add(mntmStatus).setFont(menuFont);
    mnHelp.add(mntmFeedback).setFont(menuFont);
    mnHelp.add(mntmEtsyTWebsite).setFont(menuFont);
    mnHelp.add(mntmAbout).setFont(menuFont);

mouseListeners JMenu :

    for (Component c : menuBar.getComponents()) {
        if (c instanceof JMenu) {
            c.addMouseListener(ml);
        }
    }

, childEtem , JMenu MenuBar - MouseListener(), mouseover ( 3x JMenu), mouseout , , . MouseListener :

MouseListener ml = new MouseListener() {
        public void mouseClicked(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
            isMouseOut = true;
            timerMenuClear();
        }

        public void mouseEntered(MouseEvent e) {
            isMouseOut = false;
            Object eSource = e.getSource();
            if(eSource == mnHelp || eSource == mnView || eSource == mnFile){
                ((JMenu) eSource).doClick();
            }
        }
    }; 

JMenu (3x ), . timerMenuClear() MenuSelectionManager , :

public void timerMenuClear(){
    ActionListener task = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
          if(isMouseOut == true){
              System.out.println("Timer");
          MenuSelectionManager.defaultManager().clearSelectedPath();
          }
      }
  };        
    //Delay timer half a second to ensure real mouseOUT
  Timer timer = new Timer(1000, task); 
  timer.setInitialDelay(500);        
  timer.setRepeats(false);
  timer.start();
}

It took me a bit of testing, keeping track of what values ​​I could get in the JVM during its development, but it works! even with nested menus :) I hope many find this complete example very useful.

0
source

Use this code:

public class MenuBarExt extends MenuBar {

public MenuBarExt()
{
    super();
}

@Override
public void onBrowserEvent(Event event)
{
    switch (DOM.eventGetType(event))
    {
        case Event.ONMOUSEOUT:
            closeAllChildren(false);
            break;
        default:
            super.onBrowserEvent(event);
            break;

    } 
    super.onBrowserEvent(event);
}

}
0
source

Source: https://habr.com/ru/post/1718427/


All Articles