-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0
-
b32
-
x86
-
windows_2000
Name: sv35042 Date: 10/08/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Not applicable
A DESCRIPTION OF THE PROBLEM :
A JComboBox with an empty item list generates a spurious
ActionEvent when the focus is lost. I think this occurs
because:
a) getItem() in BasicComboBoxEditor will never return
null, as can be seen from the following lines 61-81:
public Object getItem() {
Object newValue = editor.getText();
if (oldValue != null && !(oldValue instanceof
String)) {
// The original value is not a string. Should
return the value in it's
// original type.
if (newValue.equals(oldValue.toString())) {
return oldValue;
} else {
// Must take the value from the editor and
get the value and cast it to the new type.
Class cls = oldValue.getClass();
try {
Method method = cls.getMethod
("valueOf", new Class[]{String.class});
newValue = method.invoke(oldValue, new
Object[] { editor.getText()});
} catch (Exception ex) {
// Fail silently and return the
newValue (a String object)
}
}
}
return newValue;
}
b) focusLost in EditorFocusListener in BasicComboBoxUI
only ducks out for the above returning null, or the
currently selection item equaling the Editor item, as can
be seen from lines 1559-1569 of the code:
public void focusLost( FocusEvent e ) {
ComboBoxEditor editor = comboBox.getEditor();
Object item = editor.getItem();
if (!e.isTemporary() && item != null &&
!item.equals( comboBox.getSelectedItem())) {
comboBox.actionPerformed
(new ActionEvent(editor, 0, "",
EventQueue.getMostRecentEventTime(), 0));
}
}
Seeing as the item returned by the editor is never null,
while the selected item from an empty list is null, the
optout condition is not met, and a spurious event is
generated.
The following code demos this. Compile and run it, click
in the combo, then click in the text area. An event is
generated the first time this is attempted, because the
item list is still empty. On subsequent trials, the list
now has one spurious blank entry generated by the first try
bug, and the optout condition then works as it is
comparing two blank strings.
I think the Editor should return a null where no input has
ever been received. This would avoid the problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See full description
EXPECTED VERSUS ACTUAL BEHAVIOR :
See full description
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ComboBoxDemo extends JFrame
{
public static void main( String args[] )
{
JFrame frame = new ComboBoxDemo("JComboBox Bug Demo");
}
public ComboBoxDemo( String aTitle )
{
super( aTitle );
addWindowListener(
new WindowAdapter()
{
public void
windowClosing( WindowEvent e )
{
System.exit(0);
}
}
);
MyComboBox theComboBox = new MyComboBox();
getContentPane().setLayout( new BorderLayout() );
getContentPane().add( new JTextArea( "Something that can
receive focus ..." ), BorderLayout.CENTER );
getContentPane().add( theComboBox, BorderLayout.SOUTH );
pack();
theComboBox.requestFocus();
setVisible(true);
}
protected class MyComboBox extends JComboBox
{
protected MyComboBox()
{
super();
setEditable( true );
addActionListener (
new
ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
System.out.println( "ActionEvent:" + ae );
String input = getInput();
System.out.println( "Input: " + input );
}
}
);
} // protected MyComboBox()
protected String getInput()
{
String theInput = (String)getEditor().getItem();
insertItemAt( theInput, 0 );
for( int i = 1; i < getItemCount(); i++ )
if( theInput.equalsIgnoreCase( (String)getItemAt
(i) ) )
removeItemAt( i-- );
while( getItemCount() > PREVIOUSCOMMANDS )
removeItemAt( PREVIOUSCOMMANDS );
setSelectedIndex(0);
getEditor().selectAll();
return theInput;
}
// The maximum number of previous commands to remember
private final int PREVIOUSCOMMANDS = 10;
} // protected class MyComboBox extends JComboBox
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
It's trivial if you don't mind having at least one item in
the list from the start, but if you do, then there's no
easy workaround.
I tried extending BasicComboBoxEditor to override getItem
(), but was screwed by the fact that oldValue is private
access ( it's the sort of value that should be protected,
not private )
(Review ID: 143279)
======================================================================
- relates to
-
JDK-6246463 JComboBox triggers ActionEvent which clicking inside the empty drop-down
-
- Closed
-