3 Replies Latest reply: Feb 26, 2010 9:59 AM by 843807 RSS

    Unable to receive grab event by using GRAB_EVENT_MASK?

    843807
      I added an AWTEventListener to process grab event. So this listener just use sun.awt.SunToolkit.GRAB_EVENT_MASK
      mark.
      But This listener can not capture UngrabEvent. The tricky thing is, when a JComboBox popuped its menulist, it can capture this event.
      I use the following code for testing.
      Start the program, click on the empty area of the frame, click on the frame title. Then there should be an UngrabEvent. But the listener does not capture it.
      Start the program, click on the combobox and make its menulist popuped. click on the
      frame title. Then there should be an UngrabEvent. And the listener captures it.
      It is very strange...Is there any relationship between UngrabEvent and JComboBox?
      public class ComboboxLearn {
      
          public static void main(String[] args) {
              // TODO Auto-generated method stub
              Toolkit toolkit = Toolkit.getDefaultToolkit();
              toolkit.addAWTEventListener(new AWTEventListener() {
      
                  @Override
                  public void eventDispatched(AWTEvent event) {
                      System.out.println(event);
                  }
              }, sun.awt.SunToolkit.GRAB_EVENT_MASK);
              JComboBox box = new JComboBox(new Object[] { "AAA", "BBB", "CCC" });
      
              box.addPopupMenuListener(new PopupMenuListener() {
      
                  @Override
                  public void popupMenuCanceled(PopupMenuEvent e) {
                      System.out.println(e);
                  }
      
                  @Override
                  public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                      System.out.println(e);// Set a breakpoint here
                  }
      
                  @Override
                  public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                      System.out.println(e);
                  }
              });
      
              JFrame f = new JFrame();
              f.getContentPane().setLayout(new FlowLayout());
              f.getContentPane().add(box);
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.setSize(new Dimension(100, 100));
      
              f.setVisible(true);
          }
      }
        • 1. Re: Unable to receive grab event by using GRAB_EVENT_MASK?
          843807
          A quick grep of the source shows that BasicPopupMenuUI uses GRAB_EVENT_MASK and UngrabEvent.

          One question for you is: what are you actually trying to accomplish? There is likely a better way than relying on undocumented events. Your code might not work on non-Sun JRE's, for example.
          • 2. Re: Unable to receive grab event by using GRAB_EVENT_MASK?
            843807
            I am trying to implement a popup panel using java.swing.Popup. Unlike JComboBox popup list (BasicPopupMenuUI), I wanan a popup that could chould add any component but not only item.

            The problem of Java,swing.Popup is it will not hide when userws click on ther place. So I try to add a AWTEventListener and hide Popup when some event occurs such as WINDOWS_LOSE_FOUCS. It works fine on other kinds of events, but not for grab event.

            Here is my listener:
            class PopupHider implements AWTEventListener {
            
                    @Override
                    public void eventDispatched(AWTEvent event) {
                        if (event instanceof sun.awt.UngrabEvent) {
                            // Popup should be canceled in case of ungrab event
                            handleHide();
                            return;
                        }
                        if (event instanceof MouseEvent) {
            
                            MouseEvent me = (MouseEvent) event;
                            Component src = me.getComponent();
                            if (!(event instanceof MouseEvent)) {
                                return;
                            }
                            switch (me.getID()) {
                            case MouseEvent.MOUSE_PRESSED:
                                if (!isInPopupPanel(src)) {
                                    // should not happen
                                    handleHide();
                                }
                                break;
                            }
                        } else if (event instanceof WindowEvent) {
                            switch (event.getID()) {
                            case WindowEvent.WINDOW_LOST_FOCUS:
                                handleHide();
                                break;
                            case WindowEvent.WINDOW_ACTIVATED:
                                handleHide();
                                break;
                            case WindowEvent.WINDOW_GAINED_FOCUS:
                                handleHide();
                                break;
                            }
                        } else if (event instanceof KeyEvent) {
                            if (((KeyEvent) event).getKeyCode() == KeyEvent.VK_ESCAPE) {
                                handleHide();
                            }
                        }
                    }
                }
            Add the listener when popup shows
                private void registorListener() {
                    Toolkit toolkit = Toolkit.getDefaultToolkit();
                    toolkit.addAWTEventListener(hider, AWTEvent.MOUSE_EVENT_MASK
                            | AWTEvent.WINDOW_EVENT_MASK
                            | sun.awt.SunToolkit.GRAB_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
                }
            And remove it when popup hides
                private void handleHide() {
                    Toolkit toolkit = Toolkit.getDefaultToolkit();
                    toolkit.removeAWTEventListener(hider);
                    popup.hide();
                }
            • 3. Re: Unable to receive grab event by using GRAB_EVENT_MASK?
              843807
              I must admit I'm still not 100% clear on what an "ungrab event' is, even after reading its Javadoc (specifically, what couldn't be accomplished with a WindowListener, for example). But that aside, I've implemented custom popups in the past with JWindows. You can make an undecorated window look however you want (in my case, it was custom, focusable tool tips). It was a more robust solution than using javax.swing.Popup.

              so I'd suggest trying to use JWindows instead of Popups. It might be a little more legwork, but it'll pay off in the end. I bet you can accomplish what you're trying to do without resorting to using private API's.