JDK-4604625 : windowLostFocus & windowDeactivated events are not triggered for Frame.dispose()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2001-12-13
  • Updated: 2003-01-14
  • Resolved: 2002-04-04
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
1.4.1 hopperFixed
Related Reports
Relates :  
Description
windowLostFocus & windowDeactivated events are not triggered when Frame.dispose() is called in build 89. This is regression from build 86 since these events are triggered.

java -version
java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b89)
Java HotSpot(TM) Client VM (build 1.4.0-rc-b89, mixed mode)

How to reproduce:

1. Compile the disposeTest.java program attached.
2. Run this using appletviewer disposeTest.java with build 89.
3. The following messages are displayed:
**** Window Activated ****
**** Window Gained Focus ****
**** Window Opened **** 

******Disposing the frame ********

**** Window Closed ****
Assretion Fails: windowLostFocus Event is Not triggered
Assretion Fails: windowDeactivated Event is Not triggered

4. Run the same program (using appletviewer disposeTest.java) with build 86.
5. The following messages are displayed:
**** Window Opened ****
**** Window Activated ****
**** Window Gained Focus ****

******Disposing the frame ********

**** Window Closed ****
**** Window Lost Focus ****
**** Window De-Activated ****
Assretion Pass: Triggered windowLostFocus Event
Assretion Pass: Triggered windowDeactivated Event


Only window clsoed event is triggered in build 89. This happens on Win32 and solaris/sparc with build 89.





Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: hopper FIXED IN: hopper INTEGRATED IN: hopper VERIFIED IN: hopper
24-08-2004

EVALUATION A regression. Should fix for Merlin. ###@###.### 2001-12-13 Unless we are willing to hold up shipment of Merlin, this bug will have to be addressed post-Merlin. ###@###.### 2001-12-13 I'm not a focus expert, but even if this test is valid, the bug doesn't sound important to me. I wouldn't expect that people would count on being able to respond to WindowEvents after they have deliberately disposed the Window. ###@###.### 2001-12-13 Name: dmR10075 Date: 12/17/2001 First, Window.dispose removes the original WINDOW_LOST_FOCUS and WINDOW_DEACTIVATED events from event queue by the calls to EventQueue.removeSourceEvents from removeNotify. We planned to change this in Hopper/Tiger. Second, it looks like after b86 we probably introduced some code which may have changed the behavior. When WINDOW_GAINED_FOCUS arrives we may generate lost WINDOW_LOST_FOCUS, but at that time current focused window is already null and thus we don't know whom to send it and we skip it. The same with active window. I don't know what caused this. It may appear that it is just thread race though. However it wouldn't be correct to expect that all events from native code arrive if you destroy peer (by call to removeNotify). Thus calling dispose and expecting events to arrive would also be incorrect. More preferable way is to call hide on Window, wait for events and, in a listener, call dispose(). However I think that developers who have existing application relying on these events will be disappointed so we need to find the cause of the problem and don't fix it only if it is very dangerous. ###@###.### 12-17-2001 ====================================================================== Name: dmR10075 Date: 12/18/2001 I found that on Win2000 the bug is reproducible on some of the previous builds (b85, b86, b88) so it is doubtly the specially implemented regression but rather the timing condition which became visible in b89. It is reproducible if we run the application with only one frame (originally there are two frames - Applet viewer and testing frame). The situation is as following: When we call Window.dispose it creates Runnable and executes it on EventDispathThread. Among other things it calls setVisible(false) on Window which makes WM to generate WINDOW_LOST_FOCUS and WINDOW_DEACTIVATEd. However, this runnable also call EventQueue.removeSourceEvents which removes the mentioned events from event queue. If we have one frame, it means that these events are finally lost and the test will fail. However, if we have more than one frame, then when other frame will become active focus manager will generate lost WINDOW_LOST_FOCUS and WINDOW_DEACTIVATED events. If it happens on another event queue (as in case of Applet viewer) then there is a chance that this event will be generated before other window is disposed. It is still unclear though why these events are dispatched as there are the checks in our code which will fail if window is already disposed and thus event will not be dispatched. ###@###.### 2001-12-18 ====================================================================== Name: osR10079 Date: 03/21/2002 ###@###.### This bug will be fixed by fix for 4511021 (Revisit how KeyboardFocusManager clears its fields). ======================================================================
24-08-2004

SUGGESTED FIX Name: dmR10075 Date: 12/18/2001 We can move call to setVisible(false) from dispose Runnable as it doesn't require any synchronization. *** /cygdrive/n/TEMP\geta1460 Tue Dec 18 23:05:54 2001 --- Window.java Tue Dec 18 23:05:53 2001 *************** *** 517,523 **** } } } - setVisible(false); removeNotify(); synchronized (inputContextLock) { if (inputContext != null) { --- 517,522 ---- *************** *** 529,534 **** --- 528,534 ---- } } + setVisible(false); DisposeAction action = new DisposeAction(); if (EventQueue.isDispatchThread()) { action.run(); ###@###.### 2001-12-18 ======================================================================
18-12-2001

WORK AROUND Name: dmR10075 Date: 12/18/2001 Call Window.hide before Window.dispose or Call hide, and in listener of windowDeactivated call dispose ###@###.### 2001-12-18 ======================================================================
18-12-2001