XP L&F: Non-TopLevel JMenu's painting error

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.6.0-ea"
      Java(TM) Runtime Environment, Standard Edition (build 1.6.0-ea-b19)
      Java HotSpot(TM) Client VM (build 1.6.0-ea-b19, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      Non-TopLevel ("pull-right") JMenu's get repainted when the mouse exits the item. If the popup menu is still visible to the right, repainting the JMenu causes the selection background to be repainted over the top of the popup, even though the popup is supposed to appear above the JMenu.

      It is a minor error since the overlap is only a few pixels wide, but it is especially noticeable when moving the mouse slowly on to a seperator, or space between items. I've included a suggestion for a minor change to the WindowsMenuUI source that fixes this issue.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test code. Position the mouse in the JMenu so that the popup menu appears to the right. Slowly move the mouse towards the edge of the item, one pixel at a time (up or down is best). When the mouse hits the edge, you'll see the selection background spill over on to the popup.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Non-TopLevel JMenu menu items should not be repainted while their popup menu is visible to the right.
      ACTUAL -
      The overlap between the JMenu and the popup menu cases the popup to be partially obscured by the selection background of the JMenu.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;

      public class MenuTest {
          public static void main(String[] args) {
              try {
              UIManager.setLookAndFeel(
                      new com.sun.java.swing.plaf.windows.WindowsLookAndFeel());
              }
              catch(UnsupportedLookAndFeelException e) {
                  System.err.println("Windows L&F Not Supported!");
                  System.exit(0);
              }
              JFrame f = new JFrame();
              JMenuBar bar = new JMenuBar();
              JMenu clickMe = new JMenu("Click Me");
              JMenu culprit = new JMenu("Slowly Move Mouse Out of This");
              culprit.add("This item gets partially obscured");
              culprit.add(" ");
              clickMe.add(" ");
              clickMe.addSeparator();
              clickMe.add(culprit);
              clickMe.addSeparator();
              clickMe.add(" ");
              bar.add(clickMe);
              f.setJMenuBar(bar);
              f.setExtendedState(JFrame.MAXIMIZED_BOTH);
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.setVisible(true);
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The problem is caused by the mouse handling code in the protected inner class WindowsMenuUI.WindowsMouseInputHandler. The mouseEntered() and mouseExited() handlers set the RollOver property and the JMenu gets repainted. However, setting the RollOver property is only necessary for top-level JMenus. Non-TopLevel JMenu menu items such as these get painted by the super class BasicMenuItemUI which uses isSelected() rather than isRollOver() to determine whether the selection background color should be used.

      So in mouseExited() of WindowsMenuUI.WindowsMouseInputHandler we find:

      if (menu.isRolloverEnabled()) {
          model.setRollover(false);
          menuItem.repaint();
      }

      I suggest modifying this so that it applies only to TopLevel items:

      if (menu.isRolloverEnabled() && menu.isTopLevelMenu()) {
          model.setRollover(false);
          menuItem.repaint();
      }

      This additional check also needs to be added to the mouseEntered() method. Thus the JMenu item does not get repainted while the popup is visible to the right, and the problem is completely fixed! This change does not affect the normal behavior of JMenu items since its painting code in BasicMenuItemUI does not use isRollOver() at all.
      ###@###.### 2005-1-31 20:55:17 GMT

            Assignee:
            Unassigned
            Reporter:
            Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: