需要 MenuBar 的 MouseOutEvent 来检测点击:GWT

Posted

技术标签:

【中文标题】需要 MenuBar 的 MouseOutEvent 来检测点击:GWT【英文标题】:Need MouseOutEvent of MenuBar to detect click: GWT 【发布时间】:2013-01-22 01:26:30 【问题描述】:

我是使用GWT 的初学者。我有一个menubar,即使鼠标不在它上面,我也想将它保留在屏幕上。但是,当鼠标不在menubar 上并单击屏幕上的某个位置时,我希望菜单栏消失。我尝试使用MouseOutEvent,但我需要它仅在单击鼠标时才触发,而不仅仅是退出。任何帮助将不胜感激。

this.menu.addDomHandler(menuHoverOutHandler, MouseOutEvent.getType());

 MouseOutHandler menuHoverOutHandler = new MouseOutHandler() 
       public void onMouseOut(MouseOutEvent event) 
            Window.alert("I am outside the region");
        
    ;

【问题讨论】:

【参考方案1】:

以下是从我的实时应用中获取的完整答案:

我解决鼠标退出菜单关闭的方法是在构造函数的顶部运行一个布尔变量“isMouseOut”来跟踪,然后以更OO友好的方式分配MouseListener来跟踪多个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);

然后在此阶段迭代 arrayList,使用 for() 循环添加 MouseListener:

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

现在为 MenuBar 设置 JMenu 父级:

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

然后将下拉 menuItems 子项添加到 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);
        
    

现在子 menuItem 元素都有自己的侦听器,这些侦听器与父 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 'parents'(在本例中为 3x),因为它们是子菜单下拉菜单的触发器。 timerMenuClear() 方法调用 MenuSelectionManager 以清空实际 mouseOUT 时处于活动状态的任何 selectedpath 点:

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

我进行了一些测试,监控在开发过程中我可以在 JVM 中访问哪些值 - 但它真的很管用!即使是嵌套菜单 :) 我希望很多人觉得这个完整的例子非常有用。

【讨论】:

【参考方案2】:

使用小部件的模糊处理程序。它会检测小部件何时失去焦点。

【讨论】:

MenuBar 没有模糊处理程序。

以上是关于需要 MenuBar 的 MouseOutEvent 来检测点击:GWT的主要内容,如果未能解决你的问题,请参考以下文章

如何向 wx.MenuBar() 添加一个按钮?

Qt OSX全屏窗口上部menuBar和Dock

QT QMianWindow类

primeng p-menubar 示例不起作用

如何在 Flutter 桌面自定义 AppMenu(MenuBar)?

Primefaces - menuBar - 禁用选项