United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6596544 JComboBox editor stays visible after popup gone
JDK-6596544 : JComboBox editor stays visible after popup gone

Details
Type:
Bug
Submit Date:
2007-08-23
Status:
Closed
Updated Date:
2011-05-18
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
client-libs
OS:
linux,windows_xp
Sub-Component:
javax.swing
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
This appears to be a regression issue in 1.6 almost exactly similar to a bug
previously reported and marked closed as of 1.3:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4143929,
This bug appears to have resurfaced in 1.6. The problem is that the combobox
cell editor does not disappear properly when the same value as is currently
selected in the combo box is selected again from the combobox's popup.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Compile and run the program given below under jdk 1.6
2) Click the cell and select a value. Note that the editor disappears.
3) Click the cell and select a different value. Note that the editor disappears.
4) Click the cell and select the same value. Note that the editor does not
disappear. This is the regression bug. It did disappear in 1.4.2 and 1.5.
5) Click the cell, then click the body of the table outside the popup. Note that
the editor disappears. This seems like it is the correct behavior, but it is a
regression issue, as under 1.4.2 and 1.5, the editor does _not_ disappear.

You can compile the program with 1.4.2 javac and run the program with the
java from 1.4.2, 1.5 and 1.6 to see the differing behavior, or you can compile
with the javac from each version -- the differing behavior remains.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the program to work the same under 1.6 as it does under 1.5 and
1.4.2, that is, the editor would disappear when the same value was selected.
ACTUAL -
The program does not work the same under 1.6 as it does under 1.4.2 and 1.5.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import javax.swing.*;
import java.awt.*;

public class ComboBoxEditorBug {
	public ComboBoxEditorBug() {
		MyFrame mf = new MyFrame();
		mf.setSize( 200, 200 );
		mf.setVisible( true );
	}

	public static void main( String args[] ) {
		SwingUtilities.invokeLater( new Runnable() {
			public void run() { new ComboBoxEditorBug(); }
		} );
	}

	public class MyFrame extends JFrame {
		public MyFrame() {
			setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			JPanel contentPane = (JPanel) getContentPane();
			contentPane.setLayout( new BorderLayout() );

			final JTable table = new JTable( 1, 1 );
			JComboBox combo = new JComboBox();
			combo.addItem( "Item 1" );
			combo.addItem( "Item 2" );
			combo.addItem( "Item 3" );
			combo.addItem( "Item 4" );

// Uncomment this code for the workaround
//			combo.addPopupMenuListener( new PopupMenuListener() {
//				public void popupMenuWillBecomeVisible( PopupMenuEvent e ) {}
//				public void popupMenuWillBecomeInvisible( PopupMenuEvent e ) {
//				TableCellEditor editor = table.getCellEditor();
//				if ( editor != null )
//					editor.stopCellEditing();
//				}
//				public void popupMenuCanceled( PopupMenuEvent e ) {}
//			});


			table.getColumnModel().getColumn( 0 ).setCellEditor( new DefaultCellEditor( combo ) );

			contentPane.add( "Center", table );
		}

	}
}

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

CUSTOMER SUBMITTED WORKAROUND :
Adding a popup menu listener which stops editing; this is the commented
code in the example. This causes the editor to not be displayed in step 4
when running java 1.6. It also causes the editor to not be displayed in step
5 under 1.4.2 and 1.5.

Release Regression From : 5.0u12
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

                                    

Comments
EVALUATION

It is a regression of the fix for 6428549. Now in BasicComboPopup.Handler.mouseReleased() the comboBox.setSelectedIndex() method isn't called if the same value is selected from the popup. Consequently, an ActionEvent isn't fired and the editor stays visible.
                                     
2007-08-28
SUGGESTED FIX

The idea of the fix is always to call comboBox.setSelectedIndex() in BasicComboPopup.Handler.mouseReleased() exactly as it was before the regression.
                                     
2007-08-29
SUGGESTED FIX

Webrevs: http://sa.sfbay.sun.com/projects/swing_data/7/6596544/

+++ BasicComboPopup.java        Wed Aug 29 18:11:58 2007
@@ -826,15 +826,14 @@
 
         public void mouseReleased(MouseEvent e) {
             if (e.getSource() == list) {
                 if (list.getModel().getSize() > 0) {
                     // JList mouse listener
-                    if (comboBox.getSelectedIndex() != list.getSelectedIndex()) {
-                        comboBox.setSelectedIndex( list.getSelectedIndex() );
-                    } else {
-                        comboBox.getEditor().setItem( list.getSelectedValue() );
+                    if (comboBox.getSelectedIndex() == list.getSelectedIndex()) {
+                        comboBox.getEditor().setItem(list.getSelectedValue());
                     }
+                    comboBox.setSelectedIndex(list.getSelectedIndex());
                 }
                 comboBox.setPopupVisible(false);
                 // workaround for cancelling an edited item (bug 4530953)
                 if (comboBox.isEditable() && comboBox.getEditor() != null) {
                     comboBox.configureEditor(comboBox.getEditor(), 
@@ -850,15 +849,14 @@
                 MouseEvent newEvent = convertMouseEvent( e );
                 Point location = newEvent.getPoint();
                 Rectangle r = new Rectangle();
                 list.computeVisibleRect( r );
                 if ( r.contains( location ) ) {
-                    if (comboBox.getSelectedIndex() != list.getSelectedIndex()) {
-                        comboBox.setSelectedIndex( list.getSelectedIndex() );
-                    } else {
-                        comboBox.getEditor().setItem( list.getSelectedValue() );
+                    if (comboBox.getSelectedIndex() == list.getSelectedIndex()) {
+                        comboBox.getEditor().setItem(list.getSelectedValue());
                     }
+                    comboBox.setSelectedIndex(list.getSelectedIndex());
                 }
                 comboBox.setPopupVisible(false);
             }
             hasEntered = false;
             stopAutoScrolling();
                                     
2007-09-03
WORK AROUND

Add to the combo box the following listener:

combo.addPopupMenuListener(new PopupMenuListener() {
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        TableCellEditor editor = table.getCellEditor();
        if (editor != null)
            editor.stopCellEditing();
    }

    public void popupMenuCanceled(PopupMenuEvent e) {
    }
});
                                     
2007-09-03
WORK AROUND

Taken from the SDN comments for the bug.
URL: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6596544
The Work around mentioned only works assuming that in every instance that the popup is losing visibility is an event where stopCellEditing() would be called.  What if the user has cancelled editing and the popup is going away?  In many cases it isn't appropriate to assume stopCellEditing() is the desired result and there is no way to determine based on the popup events why the popup is being hidden.
                                     
2008-04-14



Hardware and Software, Engineered to Work Together