Hello, 

I reported this issue one year ago but seems that it has been removed
from the public bug database and is still not fixed so I try now to
speak directly with you to see if this really is a bug or not.

The problem that I see is that a child window already disposed is
re-disposed when the owner frame is disposed, multiplying the
WINDOW_CLOSED events.

I guess that it could be fixed by testing if the child window is
displayable before disposing it in the Window dispose action. (May be
better in the dispose method itself).

I attach patch over last jdk8 repository and a test case for the issue.

Thanks, 

Best Regards.


-- Jose Luis Martin

package info.joseluismartin.ui;

import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

/**
 * Test that JDialogs multiplies the WINDOW_CLOSED event.
 * 
 * @author Jose Luis Martin.
 */
@RunWith(BlockJUnit4ClassRunner.class)
public class DialogTest {

	private static int N_LOOPS = 10;
	private static int N_DIALOGS = 2;

	@Test
	public void TesWithFrame() throws Exception {
		System.out.println("Run with owner Frame");
		doTest(true);
	}

	@Test
	public void testWithoutFrame() throws Exception  {
		System.out.println("Run without owner Frame");
		doTest(false);
	}

	private void doTest(final boolean useFrame) throws InterruptedException {
		final Listener l  = new Listener();
		final JFrame f = new JFrame();

		for (int i = 0; i < N_LOOPS; i++) {

			SwingUtilities.invokeLater(new Runnable() {

				public void run() {
					JDialog[] dialogs = new JDialog[N_DIALOGS];
					for (int i = 0; i < N_DIALOGS; i++) {
						if (useFrame) {
							dialogs[i]= new JDialog(f);
						}
						else {
							dialogs[i] = new JDialog();
						}

						dialogs[i].addWindowListener(l);
					}
					
					// Dipose all
					for (JDialog d : dialogs)
						d.dispose();
					
					f.dispose();
				}
			});
		}
		
		

		// Wait until events are dispatched
		while (Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent() != null)
			Thread.sleep(100);

		System.out.println("Expected events: " + N_DIALOGS * N_LOOPS);
		System.out.println("Received events: " + l.getCount());
		Assert.assertEquals(N_DIALOGS * N_LOOPS, l.getCount());
	}
}

class Listener extends WindowAdapter {

	private int count = 0;

	public void windowClosed(WindowEvent e) {
		count++;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}
}
# HG changeset patch
# User Jose Luis Martin <[email protected]>
# Date 1367825872 -7200
# Node ID 7f9f64c07ab6fc12c64fa3d413d4660a121b1cd5
# Parent  1daef88acff2818a3e24101c02fb413c2db1a9eb
Fix Bug 7168064 - SwingUtilities.sharedOwnerFrame multiplies window close events

diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java
--- a/src/share/classes/java/awt/Window.java
+++ b/src/share/classes/java/awt/Window.java
@@ -1181,7 +1181,7 @@
                 for (int i = 0; i < ownedWindowArray.length; i++) {
                     Window child = (Window) (((WeakReference)
                                    (ownedWindowArray[i])).get());
-                    if (child != null) {
+                    if (child != null && child.isDisplayable()) {
                         child.disposeImpl();
                     }
                 }

Reply via email to