Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4380809
Votes 0
Synopsis Focus disappears after deiconifying frame
Category java:classes_awt
Reported Against merlin
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4048742
Submit Date 19-OCT-2000
Description





Run the program below and pass focus to the button.
Minimize the frame and then restore it. The button
now is not focused.

---------------------------------------------
import javax.swing.*;

public class Test extends JFrame {

    public Test() {
        JButton button = new JButton("focused");
        getContentPane().add(button);
    }

    public static void main(String args[]) {
        Test frame = new Test();
        frame.pack();
        frame.setVisible(true);
    }
}
---------------------------------------------

This bug cannot be reproduced on Solaris using window
managers with focus-follows-mouse policy. It can be
easily reproduced on Windows, however.

This bug appeared in Merlin after focus changes.
It didn't exist in 1.3 or 1.2.2.

======================================================================
Work Around
N/A
Evaluation
As bug appeared after focus changes, reassigning to awt.
 xxxxx@xxxxx  2000-10-23

Commit to fix in Merlin (regression).  
 xxxxx@xxxxx  2000-11-08

the problem is as follows:
on Windows, when we retore window it receives three events:
WM_ACTIVATE(nState=WA_ACTIVE, fMinimize=TRUE)  
WM_SETFOCUS(focus was set to this window)
WM_ACTIVATE(nState=WA_ACTIVE, fMinimize=FALSE)
     
So, all work about focus management is performed after first
WM_ACTIVATE, after WM_SETFOCUS we set focus to frame, and for
second WM_ACTIVATE in AwtFrame::WmActivate we set focus to NULL.
     
In fact, java event WINDOW_ACTIVATED is eqvuivalent to
WM_ACTIVATE(nState=WA_ACTIVE, fMinimize=FALSE). And our focus
code assume that we receive WM_SETFOCUS after WM_ACTIVATE.
     
So, to fix this problem we must skip any WM_ACTIVATE(WA_ACTIVE, TRUE).
And skip WM_SETFOCUS and WM_KILLFOCUS untill we receive
WM_ACTIVATE(fMinimized=FALSE).

 xxxxx@xxxxx  2000-12-14


Here the fix is described with Win32 way of implementation:

From my understanding on Windows messages and Java equivalents:
1. When a window(Frame) is minimized
   WM_SIZE:SIZE_MINIMIZED == windowIconified
   WM_KILLFOCUS:component-in-focus == focusLost:temporary
   WM_ACTIVATE:WA_INACTIVE == windowDeactivated

2. When a window(Frame) is restored
   WM_ACTIVATE:WA_ACTIVE/WA_CLICKACTIVE == windowActivated
   WM_SIZE:SIZE_RESTORED == windowDeiconified
   WM_SETFOCUS:top-app-window == focusGained:permanent

Since the java.awt.Window.dispatchEventImpl() method always makes that particular instance as the current focus owner, the actual component is not gaining the focus.

I remember in Windows programming, WM_ACTIVATE (restoring) will put the active window into focus. In this Windows window, WM_SETFOCUS handler is expected to SetFocus() on the required component. In case of Windows dialog, the component's focus would be received automatically.

During the WM_KILLFOCUS, the previous focus owner is saved. This can be reused during the WM_SETFOCUS to restore the focus on the previous component. For this, the Java Window.dispatchEventImpl() has to accommodate the changes to allow the previous component restoration. There is no over-riding dispatchEventImpl method in Java Frame class.

In the fix to Window.dispatchEventImpl():FOCUS_GAINED, the previous focus owner is not overwritten in case of Frame. Incidentally, Component.dispatchEventImpl() also does similar to this but for Window instances.

Since in the earlier version, the main window (Java Frame) is setting itself to the focus owner the WM_SETFOCUS was redundant and required code to skip one.

 xxxxx@xxxxx  2004-09-21
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang