Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6714829

REGRESSION: Wrong modal dialog activated after child closed, causes freeze

XMLWordPrintable

    • b38
    • 6
    • x86
    • windows_xp

        FULL PRODUCT VERSION :
        java version "1.6.0_06"
        Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
        Java HotSpot(TM) Client VM (build 10.0-b22, mixed mode, sharing)

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

        A DESCRIPTION OF THE PROBLEM :
        I have a simple AWT app that creates a series of modal dialogs, all with the same JFrame as parent (different JFrames do not exhibit this problem). Often when closing one of these dialogs, the wrong dialog comes to the front (i.e. not the one that was at the front when the child was opened), and it is impossible to close the dialogs - looks like the modality event fitlering got broken in Java 6. This works fine in Java 5.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run this simple AWT app that creates a series of modal dialogs, all with the same JFrame as parent (different JFrames do not exhibit this problem).

        Repeatedly open child dialogs by pressing space bar and close them by pressing escape.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        When window 'n' is closed, window 'n-1' should be activated (i.e. the window that was at the front when window n was opened)
        ACTUAL -
        Sometimes, when window 'n' is closed, a window much further up the hierarchy gets activated. When this happens, the activated window appears at the front but its controls are disabled; the window that should have been activated cannot be activated by clicking the title bar, etc., but its controls respond to mouse clicks.

        Looks to the user like a complete freeze.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Activated: 2
        Window 1 should be active again
        Activated: 1
        Activated: 1
        Window 1 opening 2
        Activated: 2
        Window 2 opening 3
        Activated: 3
        Window 3 opening 4
        Activated: 4
        Activated: 2
        ERROR: expected 3 to be activated now, not 2
        at WindowTest$3.windowActivated(WindowTest.java:94)
        at java.awt.Window.processWindowEvent(Window.java:1839)
        at java.awt.Window.processEvent(Window.java:1785)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Window.dispatchEventImpl(Window.java:2440)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)Window 3 should be active again
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:882)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:403)
        at java.awt.Component.dispatchEventImpl(Component.java:4285)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Window.dispatchEventImpl(Window.java:2440)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.SentEvent.dispatch(SentEvent.java:55)
        at java.awt.DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent.dispatch(DefaultKeyboardFocusManager.java:177)
        at java.awt.DefaultKeyboardFocusManager.sendMessage(DefaultKeyboardFocusManager.java:204)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:280)
        at java.awt.Component.dispatchEventImpl(Component.java:4285)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Window.dispatchEventImpl(Window.java:2440)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.SequencedEvent.dispatch(SequencedEvent.java:98)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:177)
        at java.awt.Dialog$1.run(Dialog.java:1045)
        at java.awt.Dialog$3.run(Dialog.java:1097)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1095)
        at java.awt.Component.show(Component.java:1422)
        at java.awt.Component.setVisible(Component.java:1375)
        at java.awt.Window.setVisible(Window.java:806)
        at java.awt.Dialog.setVisible(Dialog.java:985)
        at WindowTest$1.actionPerformed(WindowTest.java:62)
        at java.awt.Button.processActionEvent(Button.java:392)
        at java.awt.Button.processEvent(Button.java:360)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:177)
        at java.awt.Dialog$1.run(Dialog.java:1045)
        at java.awt.Dialog$3.run(Dialog.java:1097)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1095)
        at java.awt.Component.show(Component.java:1422)
        at java.awt.Component.setVisible(Component.java:1375)
        at java.awt.Window.setVisible(Window.java:806)
        at java.awt.Dialog.setVisible(Dialog.java:985)
        at WindowTest$1.actionPerformed(WindowTest.java:62)
        at java.awt.Button.processActionEvent(Button.java:392)
        at java.awt.Button.processEvent(Button.java:360)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:177)
        at java.awt.Dialog$1.run(Dialog.java:1045)
        at java.awt.Dialog$3.run(Dialog.java:1097)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Dialog.show(Dialog.java:1095)
        at java.awt.Component.show(Component.java:1422)
        at java.awt.Component.setVisible(Component.java:1375)
        at java.awt.Window.setVisible(Window.java:806)
        at java.awt.Dialog.setVisible(Dialog.java:985)
        at WindowTest$4$1.actionPerformed(WindowTest.java:122)
        at java.awt.Button.processActionEvent(Button.java:392)
        at java.awt.Button.processEvent(Button.java:360)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


        I looked at this stack in a debugger, and it looks like its the event filtering where we get confused and decide to activate window 3 not window 7:

        EventDispatchThread.pumpEventsForFilter(int id, Conditional cond, EventFilter filter)
        id = -1
        cond = Dialog ( ... WindowTest[Window 7,88,88,300x100,layout=java.awt.BorderLayout,TOOLKIT_MODAL,title=Window 7,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,4,23,292x73,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] WindowTest 58 )
        filter = java.awt.ModalEventFilter$ToolkitModalEventFilter@17748d3( modalDialog = Window7 )

        calls
        pumpOneEventForFilters(-1)

        calls EventQueue.dispatchEvent():

        arg0 java.awt.SequencedEvent[] on Window 3 SequencedEvent 55
        appContext sun.awt.AppContext[threadGroup=system] AppContext 276
        bdata null null
        consumed false boolean
        disposed false boolean
        focusManagerIsDispatching false boolean
        id 1006 int
        isPosted true boolean
        nested java.awt.event.WindowEvent[WINDOW_GAINED_FOCUS,opposite=WindowTest[Window 8,110,110,300x100,hidden,layout=java.awt.BorderLayout,TOOLKIT_MODAL,title=Window 8,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,4,23,292x73,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true],oldState=0,newState=0] on Window 3 WindowEvent 326
        source WindowTest[Window 3,22,22,300x100,layout=java.awt.BorderLayout,TOOLKIT_MODAL,title=Window 3,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,4,23,292x73,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] WindowTest 51


        REPRODUCIBILITY :
        This bug can be reproduced often.

        ---------- BEGIN SOURCE ----------
        import java.awt.Button;
        import java.awt.Dialog;
        import java.awt.Frame;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import java.awt.event.KeyAdapter;
        import java.awt.event.KeyEvent;
        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        import java.util.HashMap;
        import java.util.Map;
        import javax.swing.SwingUtilities;

        public class WindowTest extends Dialog
        {
        static Frame frame;
        final static Map<Integer, WindowTest> windows = new HashMap<Integer, WindowTest>();

        static int lastCreated;
        static int lastShown = 1;
        final int i;
        static boolean hasFailed = false;

        public WindowTest(Dialog parent)
        {
        super(parent);
        i = ++lastCreated;
        init();
        }
        public WindowTest(Frame parent)
        {
        super(parent);
        i = ++lastCreated;
        init();
        }
        private void init()
        {
        setTitle("Window "+i);
        setName(getTitle());
        setModal(true);
        Button b = new Button("New");
        add(b);
        setSize(300, 100);
        setLocation(100+i*50, 100+i*50);
        b.addActionListener(new ActionListener()
        {
        public void actionPerformed(ActionEvent e)
        {
        WindowTest w = windows.get(i+1);
        if (w == null)
        // create new dialog with frame as its parent
        windows.put(i+1, w = new WindowTest(frame));

        System.out.println(getTitle()+" opening "+(i+1));
        lastShown = i+1;
        w.setVisible(true);
        lastShown = i;
        System.out.println(getTitle()+" should be active again");

        // these checks alway pass
        assert isActive();
        assert isFocused();
        }
        });

        b.addKeyListener(new KeyAdapter()
        {
        @Override
        public void keyPressed(KeyEvent e)
        {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE && i >= 1 && !hasFailed)
        setVisible(false);
        }

        });

        addWindowListener(new WindowAdapter()
        {
        @Override
        public void windowActivated(WindowEvent e)
        {
        System.out.println("Activated: "+i);
        if (i != lastShown)
        {
        // when this happens, a modal-blocked window comes to the top, and it is impossible to switch to the window that should have been activated
        System.out.println("ERROR: expected "+lastShown+" to be activated now, not "+i);
        hasFailed = true;
        throw new RuntimeException("ERROR: expected "+lastShown+" to be activated now, not "+i);
        }
        }
        });
        }

        public static void main(String[] args) throws Exception
            {
        SwingUtilities.invokeAndWait(new Runnable()
        {

        public void run()
        {
        frame = new Frame("Parent Frame");
        frame.setName("Parent Frame");
        Button b = new Button("Open Dialog...");
        frame.add(b);
        frame.setSize(300, 100);
        frame.setLocation(100, 100);

        b.addActionListener(new ActionListener()
        {
        public void actionPerformed(ActionEvent e)
        {
        WindowTest w = windows.get(1);
        if (w == null)
        windows.put(1, w = new WindowTest(frame));

        w.setVisible(true);
        }
        });
        frame.setVisible(true);
        //frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }

        });

            }
        }

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

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

              dcherepanov Dmitry Cherepanov
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: