Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4393778

JPopupMenu is moved to upper left corner of the screen (JDK1.3, Linux, Gnome)

XMLWordPrintable

    • x86
    • linux

      Following program behaves differently on different platforms. JDK1.2.2 is
      ok on (presumably) all platforms. The problem demonstrates itself only on
      Linux (tested on RedHat6.2) and with Gnome window manager.
      The program tries to insert menu items into already displayed popup menu. It
      works fine with JDK1.2.2 and the problem is introduced in JDK1.3.

      I am not 100% sure but it seems to me that the call to
      GlobalCursorManager.updateCursorImmediately();
      on line 737 in java.awt.Container
      surprisingly moves the heavyweight popup container to the location 0,0
      on the screen. Next call to pack() (and from there to the mentioned
      updateCursorImmediately) moves the window back to the correct
      location.

      Any fix or workaround would be highly appreciated since our bug #7872
      http://www.netbeans.org/bugs-cgi/show_bug.cgi?id=7872
      depends on this.

      package test;
      import java.awt.*;
      import javax.swing.*;

      public class MenuTest extends JFrame
      implements java.awt.event.ActionListener {
          private static JButton b1;
          private static JButton b2;
          
        /** Creates new MenuTest */
          public MenuTest() {
              super ("Test of menu");
          }
          
        /** Shows the menu.
         * @param hack use hack or not?
         */
          private void showMenu (final boolean hack) {
              Dimension d = getSize ();
              d.width /= 2;
              d.height /= 2;
              
              final JPopupMenu menu = new JPopupMenu ();
              final Component popupParent = getContentPane();
              menu.show(popupParent, d.width, d.height);
              for (int i = 0; i < 19; i++) {
                  final String name = "Item " + i;
                  try {
                      SwingUtilities.invokeLater(new Runnable () {
                          public void run () {
                              // is the menu inside the window of the parent component?
                              boolean previousContained = popupContained2(menu, popupParent);
                              
                              menu.add(name);
                              
                              if (previousContained) {
                                  // this works fine
                                  menu.pack ();
                                  java.awt.Component c = menu.getParent();
                                  if (c != null) {
                                      c.validate();
                                  }
                              } else {
                                  // the problem is here:
                                  menu.pack ();
                                  // the call to pack moves the popup to coordinates [0,0] ????!!!!!
                              }

                              if (hack) {
                                  // this hack redisplays the popup if it does not fit
                                  // into the parent's window anymore
                                  
                                  boolean nowContained = popupContained2(menu, popupParent);
                                  if (previousContained != nowContained) {
                                      System.out.println("changing state to " + nowContained);
                                      menu.setVisible (false);
                                      menu.setVisible (true);
                                  }
                              }
                          }
                      });
                      
                      Thread.sleep(500);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
          
          /** @return true if the popup menu is contained in a window */
          private static boolean popupContained2(JPopupMenu p, Component parent) {
              try {
                  java.awt.Point popup = p.getLocationOnScreen ();
                  Window w = SwingUtilities.windowForComponent (parent);
                  Rectangle r = new Rectangle (popup, p.getSize ());
                  return w != null && w.getBounds ().contains (r);
              } catch (java.awt.IllegalComponentStateException ex) {
                  return false;
              }
          }
          
        /**
         * @param args the command line arguments
         */
          public static void main (String args[]) throws Exception {
              MenuTest f = new MenuTest ();
              
              b1 = new JButton ("Without hack");
              b1.addActionListener(f);
              b2 = new JButton ("With hack");
              b2.addActionListener(f);
              
              f.getContentPane ().setLayout (new java.awt.FlowLayout ());
              f.getContentPane().add (b1);
              f.getContentPane().add (b2);
              
              f.setSize (300, 300);
              
              f.show ();
          }
          
          public void actionPerformed(final java.awt.event.ActionEvent ev) {
              new Thread ("Testing thread") {
                  public void run () {
                      showMenu (ev.getSource () == b2);
                  }
              }.start ();
          }
      }


      ###@###.### 2001-08-15
      Revised URL
      http://www.netbeans.org/issues/show_bug.cgi?id=7872

            mbronsonsunw Mike Bronson (Inactive)
            dstrupl David Štrupl (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: