JDK-7092300 : Regression: Setting JComboBox popup location via PopupMenuListener fails
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-09-19
  • Updated: 2012-03-20
  • Resolved: 2011-11-16
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.
JDK 8
8Resolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
We are developing an e-learning application that supports bidirectional math transformations. You can see a screenshot here:
http://www.sail-m.de/sail-m/tiki-download_file.php?fileId=234&preview

As you can see from the screenshot, the popup menus in the lower combo boxes open upwards. Java's default behavior is to only open combo box popups upwards when there is not enough screen space below the combo box. However, we want them to always open upwards.

This worked fine using jdk1.6.0_21. It no longer works with 1.7.0.

REGRESSION.  Last worked in version 6u26

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case. Open the popup menu.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The popup menu should always open upwards.
ACTUAL -
The popup menu always opens upwards when using 1.6.0_21. Using 1.7.0, it opens downwards unless the window is close to the bottom of the screen.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Point;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboPopup;

public class ComboPopupTest extends JFrame {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");

        final JComboBox comboBox = new JComboBox(new String[] { "apples",
                "pears", "bananas", "grapes", "oranges" });

        comboBox.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                // Always open the popup upwards
                BasicComboPopup popup = (BasicComboPopup) comboBox.getUI()
                        .getAccessibleChild(comboBox, 0);

                Point location = comboBox.getLocationOnScreen();
                popup.setLocation(location.x,
                        location.y - popup.getPreferredSize().height);
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        });

        frame.add(comboBox);
        frame.pack();
        frame.setLocationRelativeTo(null); // Center the frame
        frame.setVisible(true);
    }
}

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

Comments
EVALUATION The provided test uses undocumented JDK functionality (see comment "This is currently hacky..." for the BasicComboBoxUI#getAccessibleChild method). So there is no regression here. Fortunately there is a workaround that could help to keep wanted functionality. PopupMenuListener for the popup should be used instead of PopupMenuListener of the comboBox. See the following fragment for details: final BasicComboPopup popup = (BasicComboPopup) comboBox.getUI() .getAccessibleChild(comboBox, 0); popup.addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { Point location = comboBox.getLocationOnScreen(); popup.setLocation(location.x, location.y - popup.getPreferredSize().height); } ....
05-11-2011