JDK-6924233 : JOptionPane inside JCheckBox itemListener causes setSelected(false)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u18,6u20
  • Priority: P2
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2010-02-08
  • Updated: 2011-02-16
  • Resolved: 2010-05-12
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing)

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

A DESCRIPTION OF THE PROBLEM :
Instantiating a JOptionPane inside of an ItemListener callback for a JCheckBox causes focusSystem to generate a second itemStateChanged() event with selected=false.

Checkbox will always appear unselected.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the code fragment provided and click the checkbox.
Checkbox will always appear unselected.

It actually appears checked just for an instant before the JOptionPane is rendered and then it clears.




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When selecting the checkbox expected that only a single itemStateChanged callback with selected=true

After the JOptionPane is done executing the checkbox should have selected=true.
Checkbox should appear selected.

ACTUAL -
When selecting the checkbox two callbacks are generated, the first with selected=true and then when the JOptionPane is instantiated a second callback with selected=false is generated by the focus subsystem when the JOptionPane gains focus.

After the JOptionPane is done executing the checkbox has incorrect selected=false.
Checkbox never appears selected.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
JCheckbox checkBox = new JCheckBox("hitme");

checkbox.addItemListener(new ItemListener()
   {
        public void itemStateChanged(ItemEvent ie)
        {
    	      int retval = JOptionPane.showConfirmDialog(null, "message", "title", JOptionPane.OK_CANCEL_OPTION);
         }
   });


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

CUSTOMER SUBMITTED WORKAROUND :
// invoke the JOption Pane and all post processing using InvokeLater.
public void itemStateChanged(ItemEvent ie)
 {
           SwingUtilities.invokeLater(new Runnable()
          {
               public void run()
               {
                   int retval = JOptionPane.showConfirmDialog(null, "message", "title", JOptionPane.OK_CANCEL_OPTION);
               }
          });
  }

Comments
EVALUATION The provided testcase blocks the event processing with the modal dialog, in this case lots of undesirable effects may happen. A modal dialog blocks the listeners notification in the middle of the event processing and a components stucks in an invalide state. This code works under 6u16 for pure accident and most likely it will fail being tested several times or on another OS. To show a modal dialog from a listener without a problem one should use SwingUtilities.invokeLater just like it is illustrated in the described workaround
2010-05-12