Relates :
|
|
Relates :
|
|
Relates :
|
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.
|