JDK-6928341 : JToggleButton resets the value if focus is lost during processMouseEvent
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u18
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2010-02-22
  • Updated: 2011-02-16
  • Resolved: 2010-05-05
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 :
ver XP

A DESCRIPTION OF THE PROBLEM :
if a checkbox loses the focus (for example: show a messagebox) during the (Component).processEvent(AWTEvent)

You only have to run this source and toggle the checkbox, the value of the 
checkbox never changes and the message is shown twice.

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

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


public class BugsMain
    extends JPanel
    implements ItemListener {
    /**
     * 
     */
    private static final long serialVersionUID = -6338903941263200678L;
    JCheckBox                 checkBox;
 
    public BugsMain() {
        super( new BorderLayout() );
 
        checkBox = new JCheckBox( "Checkbox" );
        checkBox.setSelected( true );
 
        checkBox.addItemListener( this );
 
        final JPanel checkPanel = new JPanel( new GridLayout( 0, 1 ) );
        checkPanel.add( checkBox );
 
        add( checkPanel, BorderLayout.LINE_START );
        setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
    }
 
    public void itemStateChanged( final ItemEvent e ) {
        final Object source = e.getItemSelectable();
        if ( source == checkBox ) {
            JOptionPane.showMessageDialog( null, "Test", "Test Titel", 
JOptionPane.OK_CANCEL_OPTION );
        }
    }
 
    public static void main( final String[] args ) {
        javax.swing.SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                final JFrame frame = new JFrame( "BugsMain" );
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
 
                final JComponent newContentPane = new BugsMain();
                newContentPane.setOpaque( true );
                frame.setContentPane( newContentPane );
 
                frame.pack();
                frame.setVisible( true );
            }
        } );
    }
}


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

REPRODUCIBILITY :
This bug can be reproduced always.

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

Comments
WORK AROUND To show a modal dialog from a listener without a problem one should use SwingUtilities.invokeLater which allows Swing to correctly complete the event processing: public void itemStateChanged(final ItemEvent e) { final Object source = e.getItemSelectable(); if (source == checkBox) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Test", "Test Titel", JOptionPane.OK_CANCEL_OPTION); } }); } }
05-05-2010

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 which allows Swing to correctly complete the event processing: public void itemStateChanged(final ItemEvent e) { final Object source = e.getItemSelectable(); if (source == checkBox) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Test", "Test Titel", JOptionPane.OK_CANCEL_OPTION); } }); } }
05-05-2010