JDK-6363528 : REGRESSION: Stacked modal dialogs causing system to hang
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0,5.0u3
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2005-12-15
  • Updated: 2010-04-03
  • Resolved: 2006-02-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0u7 b02Fixed
Related Reports
Duplicate :  
Description
This bug is similar to bug 6276419.  Our application uses stacked modal dialogs on top of each other.  When the top level modal dialog is hidden using the call setVisible(false), the dialog goes away, but the control is not restored to the underlying dialog.  This hangs the entire application and only way to close the application is to kill the process.

This problem only occurs with JDK 1.5.0_03 or higher versions.  It works without any issue using JDK 1.5.0_02.

Here is the code to reproduce the problem:

*****************************************************
package test;

 
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.UIManager;

class ModalDialogTest extends JFrame {
	
	public static void main(String[] args) {
		try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Throwable ex) { }
		new ModalDialogTest().setVisible(true);
	}
	
	ModalDialogTest() {
		super("Frame1");
		
		final Dialog1  dlg = new Dialog1();
		
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		
		
		JButton btn1 = new JButton();
		btn1.setText("go on");
		btn1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dlg.initFields();
				dlg.setVisible(true);
			}
		});
		this.getContentPane().add(btn1);
		pack();
	}
	
	class Dialog1 extends JDialog {
		
		private Dialog2 dlg2;
		
		Dialog1() {
			super(ModalDialogTest.this, "Dialog1", true);
			JButton btn1 = new JButton();
			btn1.setText("go on");
			btn1.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(ActionEvent e) {
					dlg2.initFields();
					dlg2.setVisible(true);
				}
			});
			JButton btn2 = new JButton();
			btn2.setText("minimize");
			btn2.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(ActionEvent e) {
					btn2_actionPerformed();
				}
			});
			getContentPane().add(btn1, BorderLayout.EAST);
			getContentPane().add(btn2,  BorderLayout.WEST);
			pack();
			this.setLocation(50, 20);
		}
		
		private void btn2_actionPerformed() {
		 
			this.setVisible(false);//JOptionPane.showMessageDialog(ModalDialogTest.this, "last message before system hangs", "JOptionPane", JOptionPane.WARNING_MESSAGE);
		}
		
		void initFields() {
			if (dlg2 == null)
				dlg2 = new Dialog2();
		}
		
	}
	
	class Dialog2 extends JDialog {
		
		
		JDialog dlg3 ;
		
		Dialog2() {
			super(ModalDialogTest.this, "Dialog2", true);
			
			JButton btn1 = new JButton();
			btn1.setText("go on");
			btn1.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					dlg3 = new Dialog3();
					dlg3.setVisible(true);
				}
			});
			JButton btn2 = new JButton();
			btn2.setText("minimize");
			btn2.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(ActionEvent e) {
					btn2_actionPerformed();
				}
			});
			getContentPane().add(btn1, BorderLayout.EAST);
			getContentPane().add(btn2,  BorderLayout.WEST);
			pack();
			this.setLocation(80, 40);
		}
		
		private void btn2_actionPerformed() {
			 
			this.setVisible(false);
		}
		
		void initFields() {
			if (dlg3 == null)
				dlg3 = new Dialog3();
		}
		
	}
	
	class Dialog3 extends JDialog {
		
		
		
		Dialog3() {
			super(ModalDialogTest.this, "Dialog3", true);
			
			JButton btn2 = new JButton();
			btn2.setText("minimize");
			btn2.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(ActionEvent e) {
					btn2_actionPerformed();
				}
			});
			
			getContentPane().add(btn2,  BorderLayout.WEST);
			pack();
			this.setLocation(50, 20);
		}
		
		private void btn2_actionPerformed() {
			 
			this.setVisible(false);
		}
		
		
	}
	
}


******************************

Steps to reproduce the problem:

1) Run the above test case.
2) Press "Go on" button to open dialog 2.
3) Press "Go on" button to open dialog 3.
4) Press "Go on" button to open dialog 4.
5) Press "Minimize" button in dialog 4.

Now dialog 4 is hidden, but control is not restored to dialog 3.

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

Comments
SUGGESTED FIX Explicitly set disabled level of the dialog being shown to 0: *** /tmp/geta23174.s23177 Wed Jun 1 14:18:14 2005 --- awt_Dialog.cpp Wed Jun 1 14:18:13 2005 *************** *** 166,171 **** --- 166,174 ---- DASSERT(AwtModalityNestCounter >= 0 && AwtModalityNestCounter <= 1000); // sanity check AwtModalityNestCounter++; #endif + if (hWndDlg != NULL) { + SetDisabledLevel(hWndDlg, 0); + } ::EnumThreadWindows(AwtToolkit::MainThread(), (WNDENUMPROC)DisableTopLevelsCallback,(LPARAM)hWndDlg) ; } ###@###.### 2005-06-01 10:22:44 GMT
27-01-2006

EVALUATION Since the escalation is against this bug, I am reopening it. The fix is available.
27-01-2006