-
Bug
-
Resolution: Unresolved
-
P4
-
8, 9
-
None
With Java8b119 an auto-completion widget we've been using since Java-1.3 days broke on at least on windows and linux due to JDK-7160604 (OSX wasn't tested).
The auto-completion JTextField has a KeyListener registered, which shows/hides a JPopupMenu as soon as text is enetered into the text field. To allow the user to continue typing, each time the JPopup is shown, requestFocus() is called on the JTextField.
Please have a look at the attached testcase (simply type in the JTextField), it has two modi:
a. requestFocus() is called inside the KeyListener
b. requestFocus() is submitted to the event queue using invokeLater() (command line parameter "rfl").
Both ways used to work pre b119, especially interesting is that b. is now completely broken and keyboard focus is permanetly lost - even clicking directly into the JTextField doesn't restore keyboard focus.
I did some digging, these are my finding:
Beside some refactorings, the only functional change I can spot inJDK-7160604 is
that the order of the assignment of the "popup"-member and
popup.show() have changed in JPopupMenu.showPopup():
Popup newPopup = getUI().getPopup(this, desiredLocationX,
desiredLocationY);
popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
popup = newPopup;
newPopup.show();
If I change the order of newPopup.show() and popup=newPopup, the old
behaviour is restored.
At least it looks somehow suspicious the original author introduced a
variable "newPopup" (and the patch still uses it without a good
reason, "popup" could be assigned directly), so at first sight it
looks intentional to assign popup only after show() was called.
During the call to newPopup.show() the method JPopupMenu.isVisible()
is called several times.
Before the fix forJDK-7160604 it would return false, now it returns
true - the focus issue mentioned is triggered by returning "true" at
the following call-stack (full one available at
http://pastebin.com/4qG8h7Td).
at javax.swing.JPopupMenu.isVisible(JPopupMenu.java:854)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:141)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:135)
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(SortingFocusTraversalPolicy.java:110)
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:445)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:166)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(SortingFocusTraversalPolicy.java:535)
at java.awt.Window.isFocusableWindow(Window.java:2496)
If I introspect the call-stack and return "false" only when
"enumerateCycle" is contained in the stack, everything works again.
So from what I understand the JPopupMenu would never receive focus
before the fix, because during show() it wasn't believed to be
visible.
The auto-completion JTextField has a KeyListener registered, which shows/hides a JPopupMenu as soon as text is enetered into the text field. To allow the user to continue typing, each time the JPopup is shown, requestFocus() is called on the JTextField.
Please have a look at the attached testcase (simply type in the JTextField), it has two modi:
a. requestFocus() is called inside the KeyListener
b. requestFocus() is submitted to the event queue using invokeLater() (command line parameter "rfl").
Both ways used to work pre b119, especially interesting is that b. is now completely broken and keyboard focus is permanetly lost - even clicking directly into the JTextField doesn't restore keyboard focus.
I did some digging, these are my finding:
Beside some refactorings, the only functional change I can spot in
that the order of the assignment of the "popup"-member and
popup.show() have changed in JPopupMenu.showPopup():
Popup newPopup = getUI().getPopup(this, desiredLocationX,
desiredLocationY);
popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
popup = newPopup;
newPopup.show();
If I change the order of newPopup.show() and popup=newPopup, the old
behaviour is restored.
At least it looks somehow suspicious the original author introduced a
variable "newPopup" (and the patch still uses it without a good
reason, "popup" could be assigned directly), so at first sight it
looks intentional to assign popup only after show() was called.
During the call to newPopup.show() the method JPopupMenu.isVisible()
is called several times.
Before the fix for
true - the focus issue mentioned is triggered by returning "true" at
the following call-stack (full one available at
http://pastebin.com/4qG8h7Td).
at javax.swing.JPopupMenu.isVisible(JPopupMenu.java:854)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:141)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateCycle(SortingFocusTraversalPolicy.java:156)
at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:135)
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(SortingFocusTraversalPolicy.java:110)
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:445)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:166)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(SortingFocusTraversalPolicy.java:535)
at java.awt.Window.isFocusableWindow(Window.java:2496)
If I introspect the call-stack and return "false" only when
"enumerateCycle" is contained in the stack, everything works again.
So from what I understand the JPopupMenu would never receive focus
before the fix, because during show() it wasn't believed to be
visible.