JDK-6196089 : BasicPopupMenuUI$MenuKeyboardHelper added repeatedly to ChangeListener list
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_2.5.1,windows_xp
  • CPU: x86,sparc
  • Submitted: 2004-11-16
  • Updated: 2010-04-02
  • Resolved: 2005-02-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u4Fixed 6 b26Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)

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

A DESCRIPTION OF THE PROBLEM :
BasicPopupMenuUI.installListeners checks but never sets the menuKeyboardHelperInstalled field.  As a result, every time a popup menu is created the static menuKeyboardHelper is added to the MenuSelectionManger's ChangeListener list.

In our application the menus are very dynamic.  Under normal usage the MenuSelectionManager's ChangeListener list can grow to have thousands of, redundant entries.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The supplied source code demonstrates that after creating 100 JPopupMenus the MenuSelectionManager ChangeListener list includes 100 entries for the same menuKeyboardHelper.



REPRODUCIBILITY :
This bug can be reproduced always.

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

public class RedundantListenerProblem {

    public static void main(String[] args) {

        System.out.println("MenuSelectionManger ChangeListeners before creating JPopupMenus:");
        printListeners();
        for (int i = 0; i < 100; i++)
            new JPopupMenu();
        System.out.println("MenuSelectionManger ChangeListeners after creating JPopupMenus:");
        printListeners();
    }

    private static void printListeners()
    {
        ChangeListener[] listeners = MenuSelectionManager.defaultManager().getChangeListeners();
        for (int i = 0; i < listeners.length; i++)
            System.out.println(listeners[i].toString());
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
        new JPopupMenu() {
            public void setUI(PopupMenuUI ui) {
                super.setUI(ui);
                if (ui instanceof BasicPopupMenuUI) {
                    try {
                        Class basicClass = Class.forName("javax.swing.plaf.basic.BasicPopupMenuUI");
                        Field basicField = basicClass.getDeclaredField("menuKeyboardHelperInstalled");
                        basicField.setAccessible(true);
                        basicField.setBoolean(null, true);
                    } catch (Exception e) {}
                }
            }
        };
###@###.### 2004-11-16 18:57:57 GMT

Comments
SUGGESTED FIX *** /home/dbr/Mustang/webrev/src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java- Thu Feb 3 18:56:08 2005 --- BasicPopupMenuUI.java Thu Feb 3 17:31:50 2005 *************** *** 102,107 **** --- 102,108 ---- } MenuSelectionManager msm = MenuSelectionManager.defaultManager(); msm.addChangeListener(menuKeyboardHelper); + menuKeyboardHelperInstalled = true; } } ###@###.### 2005-2-18 16:53:38 GMT
18-02-2005

EVALUATION We need to set boolean variable menuKeyboardHelperInstalled to true when we are installing BasicPopupMenuUI$MenuKeyboardHelper. ###@###.### 2005-2-18 16:53:38 GMT
18-02-2005