-
Bug
-
Resolution: Won't Fix
-
P4
-
6u22
-
x86
-
windows_7
FULL PRODUCT VERSION :
JRE/JDK are involved in this new bug since the bug(id 4743225) has been fixed. So i think it's since 1.6.0_22
ADDITIONAL OS VERSION INFORMATION :
Linux, Windows (all versions)
A DESCRIPTION OF THE PROBLEM :
The bug(id 4743225) brings a new bug. The bug fix should allow the user to modify the popup of a JComboBox with the method popupMenuWillBecomeVisible().. But it's impossible to change the location with this method.
Let me explain :
On the version bugged, when a button mouse is pressed on a JComboBox :
MousePressed(event e)
Toggle()
If the popup is not visible, call show()
show() method first call firePopupMenuWillBecomeVisible()(should allow to change the property of the popup), but at that time, there is no popup, no invoker for BasicComboPopup associated with the JComboBox. So methods like BasicComboPopup.getInvoker returns null, but they should not.
Then, the show(Component Invoker, popupLocation.x, popupLocation.y) is called. But this method create new values(generic) for the BasicComboPopup(invoker, parent Frame, Location) and after show the new created popup. So the popup is showed always under the JComboBox.
Before the fix of the bug, the call of firePopupMenuWillBecomeVisible was in the method show(Component Invoker, popupLocation.x, popupLocation.y) and then before the popup was created, we could change the popup location because the new generic values were created before the call of firePopupMenuWillBecomeVisible(). And then the popup was well created.
REGRESSION. Last worked in version 6u29
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Easy !
Try to change the popop location of a JComboBox by yourself, without removing the MouseListener of the JComboBox and replacing by your MouseListener, only by using the method popupMenuWillBecomeVisible().
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Everything goes well and the popup is showed above the JComboBox
ACTUAL -
First :
getInvoker() returns null
Second :
The popup is showed after the JComboBox
ERROR MESSAGES/STACK TRACES THAT OCCUR :
getInvoker() returns null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//Creation of a Jframe (jf)
JComboBox jcb = new JComboBox({"a", "b", "c"});
jcb.addPopupMenuListener((PopupMenuListener) yourPopupMenuListener);
jf.add(jcb);
//Show the Jframe (jf)
public class yourPopupMenuListener extends PopupMenuListener {
.....
public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
JComboBox comboBox = (JComboBox)arg0.getSource();
if (comboBox.getItemCount() == 0) return;
AccessibleContext ac =
Object popup = comboBox.getAccessibleContext().getAccessibleChild(0);
if (popup instanceof BasicComboPopup)
{
Point parent = ((BasicComboPopup)child).getInvoker().getLocationOnScreen();
int height = ((BasicComboPopup)popup).getPreferredSize().height;
((BasicComboPopup)popup).setLocation(parent.x, parent.y - height);
}
}
.....
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only solution i have found is :
1] Delete the mouseListener of the JComboBox component : Delete the mouseListener of the BasicComboPopup and the two mouseListener of the JButton(of the JComboBox)
2] Give to the two Components, those we have removed their mouseListener, a new MouseListener
3] On the MousePressed event :
get the component which invoked the MousePressed
If it's an instance of the BasicComboPopup or the JButton, check if the popup is visible(isVisible). If it's visible, call the method hide(). If it's not visible, call the method show(JComboBox, popupLocationWanted.x, popupLocationWanted.y)
JRE/JDK are involved in this new bug since the bug(id 4743225) has been fixed. So i think it's since 1.6.0_22
ADDITIONAL OS VERSION INFORMATION :
Linux, Windows (all versions)
A DESCRIPTION OF THE PROBLEM :
The bug(id 4743225) brings a new bug. The bug fix should allow the user to modify the popup of a JComboBox with the method popupMenuWillBecomeVisible().. But it's impossible to change the location with this method.
Let me explain :
On the version bugged, when a button mouse is pressed on a JComboBox :
MousePressed(event e)
Toggle()
If the popup is not visible, call show()
show() method first call firePopupMenuWillBecomeVisible()(should allow to change the property of the popup), but at that time, there is no popup, no invoker for BasicComboPopup associated with the JComboBox. So methods like BasicComboPopup.getInvoker returns null, but they should not.
Then, the show(Component Invoker, popupLocation.x, popupLocation.y) is called. But this method create new values(generic) for the BasicComboPopup(invoker, parent Frame, Location) and after show the new created popup. So the popup is showed always under the JComboBox.
Before the fix of the bug, the call of firePopupMenuWillBecomeVisible was in the method show(Component Invoker, popupLocation.x, popupLocation.y) and then before the popup was created, we could change the popup location because the new generic values were created before the call of firePopupMenuWillBecomeVisible(). And then the popup was well created.
REGRESSION. Last worked in version 6u29
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Easy !
Try to change the popop location of a JComboBox by yourself, without removing the MouseListener of the JComboBox and replacing by your MouseListener, only by using the method popupMenuWillBecomeVisible().
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Everything goes well and the popup is showed above the JComboBox
ACTUAL -
First :
getInvoker() returns null
Second :
The popup is showed after the JComboBox
ERROR MESSAGES/STACK TRACES THAT OCCUR :
getInvoker() returns null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//Creation of a Jframe (jf)
JComboBox jcb = new JComboBox({"a", "b", "c"});
jcb.addPopupMenuListener((PopupMenuListener) yourPopupMenuListener);
jf.add(jcb);
//Show the Jframe (jf)
public class yourPopupMenuListener extends PopupMenuListener {
.....
public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
JComboBox comboBox = (JComboBox)arg0.getSource();
if (comboBox.getItemCount() == 0) return;
AccessibleContext ac =
Object popup = comboBox.getAccessibleContext().getAccessibleChild(0);
if (popup instanceof BasicComboPopup)
{
Point parent = ((BasicComboPopup)child).getInvoker().getLocationOnScreen();
int height = ((BasicComboPopup)popup).getPreferredSize().height;
((BasicComboPopup)popup).setLocation(parent.x, parent.y - height);
}
}
.....
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only solution i have found is :
1] Delete the mouseListener of the JComboBox component : Delete the mouseListener of the BasicComboPopup and the two mouseListener of the JButton(of the JComboBox)
2] Give to the two Components, those we have removed their mouseListener, a new MouseListener
3] On the MousePressed event :
get the component which invoked the MousePressed
If it's an instance of the BasicComboPopup or the JButton, check if the popup is visible(isVisible). If it's visible, call the method hide(). If it's not visible, call the method show(JComboBox, popupLocationWanted.x, popupLocationWanted.y)