United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6363528 REGRESSION: Stacked modal dialogs causing system to hang
6363528 : REGRESSION: Stacked modal dialogs causing system to hang

Details
Type:
Bug
Submit Date:
2005-12-15
Status:
Resolved
Updated Date:
2010-04-03
Project Name:
JDK
Resolved Date:
2006-02-25
Component:
client-libs
OS:
windows_2000
Sub-Component:
java.awt
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
5.0,5.0u3
Fixed Versions:
5.0u7

Related Reports
Duplicate:

Sub Tasks

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
EVALUATION

Since the escalation is against this bug, I am reopening it. The fix is available.
                                     
2006-01-27
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
                                     
2006-01-27



Hardware and Software, Engineered to Work Together