JDK-4886881 : Unpredictable focus transfer (requestFocus + setEnabled(false))
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-07-07
  • Updated: 2007-02-12
  • Resolved: 2007-02-12
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Name: jk109818			Date: 07/07/2003


FULL PRODUCT VERSION :
jdk 1.4.0, jdk 1.4.1, jdk 1.4.2

FULL OS VERSION :
Windows 2000

A DESCRIPTION OF THE PROBLEM :
A form uses 3 JTextFields: t1, t2, t3.
After pressing enter in t1 I want transfer focus to t3 and disable t1 (and sometimes t2 too).

The result of the simple test application inluded is:

After pressing return in t1, t2 receives focus.
When I disable t2 too, focus get completely lost.

bug is new in all 1.4.x, 1.3.x produced the right results.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
control with call of requestFocsus (t3) should receive focus.
ACTUAL -
focus in wrong control or completely lost

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JFrame
{
    private JTextField t1 = new JTextField(5),
                       t2 = new JTextField(5),
                       t3 = new JTextField(5);

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

    public Test()
    {
        Container c = getContentPane();
        c.setLayout(new GridLayout(1,3,5,5));
        c.add(t1);
        c.add(t2);
        c.add(t3);
        pack();

        t1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                t3.requestFocus();
                t1.setEnabled(false);
                // uncomment the following line and focus
                // will be nowhere
                // t2.setEnabled(false);
            }});
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
switch order of setEnabled / requestFocus calls.

It seems that the new logic of automatic focus transfer when disabling the current focus owner causes the problem. It' doesn't recognize that there was a requestFocus call to a different control before.

It looks like the requestFocus call doesn't immediately transfer focus (like Win32-API SetFocus) but uses some kind of asynchronous notificaton. Otherwise Swing wouldn't still recognize t1 as focus owner.
(Review ID: 189643) 
======================================================================

Comments
EVALUATION the problem is not reproducible with jdk 6. I think it was fixed as part of 6180261.
12-02-2007

WORK AROUND Name: osR10079 Date: 07/09/2003 switch order of setEnabled / requestFocus calls. ======================================================================
22-09-2004

EVALUATION Name: osR10079 Date: 07/09/2003 The customer is right, the cause of this problem is asynchronous nature of requestFocus(). It always was so for heavyweight components and after focus rework (made in 1.4) it's also true for lightweight. This feature is documented in requestFocus() javadoc and Focus spec. I'm not sure if we should do somthing with this (I would say we should, but it's unclear what). Anyway, customer submitted workaround is absolutely correct. ###@###.### 2003-07-09 ====================================================================== ###@###.### 2004-09-20
09-07-2003