-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
1.4.2
-
Fix Understood
-
x86
-
windows_xp
Name: gm110360 Date: 05/20/2004
FULL PRODUCT VERSION :
java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
MS Windows XP version 5.1.2600
A DESCRIPTION OF THE PROBLEM :
With an editable JComboBox, if you add an input verifier to the editor component of the box, like:
JTextField jtf = (JTextField)myCbox.getEditor().getEditorComponent();
jtf.setInputVerifier( new InputVerifier() ....
The verifier will fire every time the selected item in the list changes, but the value of the component when it fires will be the last selected item. It's only when the focus actually leaves the JComboBox that the verifier fires with the correct, or current value of the field.
NOTE: the bug also exists if you have a non-editable JComboBox and you place the InputVerifier on the JComboBox directly.
A user on the forums board, Kleopatra, suggests this as a hint to the cause:
No idea how to fix it, but the reason for it seems to be a very old artefact introduced by BasicListUI.MouseHandler. A code comment there:
/* Request focus before updating the list selection. This implies
* that the current focus owner will see a focusLost() event
* before the lists selection is updated IF requestFocus() is
* synchronous (it is on Windows). See bug 4122345
*/
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the sample code.
Select the value 'Dog' from the list. The value shown in the input verifier will be the starting value of the combobox. With Dog Selected, select 'Pig'. The input verifier will fire and show the value as 'Dog'.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The input verifier should either only fire when focus leaves the JComboBox, or if it is going to fire on list selections, it should show the current value, not the previous.
ACTUAL -
The values in the input verifier are always one step behind the actual selected value. It is correct only when focus leaves the JComboBox.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
[code]
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class CBoxInputVerifierTest
{
public static void main(String[] args)
{
JFrame f = new JFrame("ComboBox Text");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
JComboBox cBox = new JComboBox (petStrings);
cBox.setEditable(true);
// set an InputVerifier on the focusable component to perform the validation
JTextField jtf = (JTextField) cBox.getEditor().getEditorComponent();
jtf.setInputVerifier(
new InputVerifier()
{
public boolean verify(JComponent input)
{
JTextField temp = (JTextField) input;
System.out.println("verifying value->" + temp.getText());
return true;
}
});
f.getContentPane().add(cBox, BorderLayout.NORTH);
f.getContentPane().add(new JTextField("A Field"), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
[/code]
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
http://forum.java.sun.com/thread.jsp?forum=57&thread=523832&start=0&range=30#2510318
From the forums, Kleopatra suggests:
private static void adjustList(JComboBox box) {
// ask the accessibleContext for the popup
JComponent comp = (JComponent) box.getUI().getAccessibleChild(box, 0);
// use your favourite method to find a list child of the popup
JList list = KleoUtilities.findListChild(comp);
if (list != null) {
// hint to client code for not calling requestFocus
list.setRequestFocusEnabled(false);
}
}
(Incident Review ID: 270537)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
MS Windows XP version 5.1.2600
A DESCRIPTION OF THE PROBLEM :
With an editable JComboBox, if you add an input verifier to the editor component of the box, like:
JTextField jtf = (JTextField)myCbox.getEditor().getEditorComponent();
jtf.setInputVerifier( new InputVerifier() ....
The verifier will fire every time the selected item in the list changes, but the value of the component when it fires will be the last selected item. It's only when the focus actually leaves the JComboBox that the verifier fires with the correct, or current value of the field.
NOTE: the bug also exists if you have a non-editable JComboBox and you place the InputVerifier on the JComboBox directly.
A user on the forums board, Kleopatra, suggests this as a hint to the cause:
No idea how to fix it, but the reason for it seems to be a very old artefact introduced by BasicListUI.MouseHandler. A code comment there:
/* Request focus before updating the list selection. This implies
* that the current focus owner will see a focusLost() event
* before the lists selection is updated IF requestFocus() is
* synchronous (it is on Windows). See bug 4122345
*/
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the sample code.
Select the value 'Dog' from the list. The value shown in the input verifier will be the starting value of the combobox. With Dog Selected, select 'Pig'. The input verifier will fire and show the value as 'Dog'.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The input verifier should either only fire when focus leaves the JComboBox, or if it is going to fire on list selections, it should show the current value, not the previous.
ACTUAL -
The values in the input verifier are always one step behind the actual selected value. It is correct only when focus leaves the JComboBox.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
[code]
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class CBoxInputVerifierTest
{
public static void main(String[] args)
{
JFrame f = new JFrame("ComboBox Text");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
JComboBox cBox = new JComboBox (petStrings);
cBox.setEditable(true);
// set an InputVerifier on the focusable component to perform the validation
JTextField jtf = (JTextField) cBox.getEditor().getEditorComponent();
jtf.setInputVerifier(
new InputVerifier()
{
public boolean verify(JComponent input)
{
JTextField temp = (JTextField) input;
System.out.println("verifying value->" + temp.getText());
return true;
}
});
f.getContentPane().add(cBox, BorderLayout.NORTH);
f.getContentPane().add(new JTextField("A Field"), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
[/code]
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
http://forum.java.sun.com/thread.jsp?forum=57&thread=523832&start=0&range=30#2510318
From the forums, Kleopatra suggests:
private static void adjustList(JComboBox box) {
// ask the accessibleContext for the popup
JComponent comp = (JComponent) box.getUI().getAccessibleChild(box, 0);
// use your favourite method to find a list child of the popup
JList list = KleoUtilities.findListChild(comp);
if (list != null) {
// hint to client code for not calling requestFocus
list.setRequestFocusEnabled(false);
}
}
(Incident Review ID: 270537)
======================================================================