JDK-4878528 : Keyboard focus problem
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version:
    1.3.1_01,1.4.0,1.4.1,1.4.2,1.4.2_07,5.0 1.3.1_01,1.4.0,1.4.1,1.4.2,1.4.2_07,5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,solaris_8,windows_nt,windows_2000,windows_xp generic,solaris_8,windows_nt,windows_2000,windows_xp
  • CPU: generic,x86,sparc
  • Submitted: 2003-06-13
  • Updated: 2005-05-11
  • Resolved: 2005-05-11
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.
JDK 6
6 b36Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Name: rmT116609			Date: 06/13/2003


FULL PRODUCT VERSION :
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b19)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b19, mixed mode)

FULL OS VERSION :
Microsoft Windows XP [verzi^?sz��m: 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The keyboard focus disappeard with the closed internal frame. See the test code.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test code.
1. Selected the Internal frame(click on the header of it or ...)
2. Selected the Menu/Close menuitem, which close the internal frame
3. The keyboard focus has been lost. Check the debug lines on the output where is the focus.

ACTUAL -
The keyboard focus has been disappeard with closed internal frame.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * FocusTest.java
 *
 * Created on 2003. jM-^Tnius 13., 12:38
 */

package TEST;

import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class FocusTest extends javax.swing.JFrame {
    
    private JInternalFrame jInternalFrame1;
    /** Creates new form FocusTest */
    public FocusTest() {
        initComponents();
        jInternalFrame1 = new JInternalFrame();
        jInternalFrame1.setVisible(true);
        jInternalFrame1.setBounds(0, 0, 270, 240);
        jInternalFrame1.getContentPane().addFocusListener( new FocusListener() {
            
            public void focusGained(FocusEvent e) {
                System.out.println("contentpane of internal frame GAINED the focus");
            }
            
            public void focusLost(FocusEvent e) {
                System.out.println("contentpane of internal frame LOST the focus");
            }
        });
        
        jDesktopPane1.add(jInternalFrame1, javax.swing.JLayeredPane.DEFAULT_LAYER);
        
        Timer timer = new Timer(1500, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
                if (comp == null)
                    System.out.println("Focus on NULL");
                else {
                    Component temp = comp.getParent();
                    while (temp != null &&  !(temp instanceof JInternalFrame) && !(temp instanceof JFrame))
                        temp = temp.getParent();
                    System.out.println("Focus on "+comp.getClass()+" Parent: "+(temp == null ? "null" : temp.getClass().toString()));
                }
            }
        });
        timer.start();
        setSize(400, 300);
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        jDesktopPane1 = new javax.swing.JDesktopPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        getContentPane().add(jDesktopPane1, java.awt.BorderLayout.CENTER);

        jMenu1.setText("Menu");
        jMenuItem1.setText("Close frame");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });

        jMenu1.add(jMenuItem1);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        pack();
    }

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
        // Add your handling code here:
        jInternalFrame1.setVisible(false);
        jInternalFrame1.dispose();
        jInternalFrame1 = null;
        System.out.println("ClosED the internal frame");
    }
    
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new FocusTest().show();
    }
    
    
    // Variables declaration - do not modify
    private javax.swing.JDesktopPane jDesktopPane1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenu jMenu1;
    // End of variables declaration
 }

---------- END SOURCE ----------
(Review ID: 187979) 
======================================================================

Comments
EVALUATION This is already a known issue and we have a number of bugs already covering the focus issues with internal frames. I will close this as duplicate once I find the matching bug ID. As a side note, I am already working on a fix for this. ###@###.### 2003-06-16 This is the older of the two issues and will be used as the tracking bug for it. Closing 4917166 as a duplicate of this. ###@###.### 2004-09-03 The test program uses the wrong entry point for closing the InternalFrame it should call jInternalFrame1.setClosed(true); instead of jInternalFrame1.setVisible(false); The attached test case FocusTest has this fix. The bug is reproducible in build 1.6.0-ea-b33. In Bug 4878528, there is only one JInternalFrame, and when it is closed the focus is lost, because there is not a "next frame" to activate. After the one JInternalFrame is closed, the call to KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() returns the JPanel of the closed JInternalFrame, which is wrong. This fixes the case when the last JInternalFrame is closed. The focus was lost because there was no next frame and so nothing was done. Calling requestFocus on the container of the JInternalFrame fixes this. ------- DefaultDesktopManager.java ------- *** /tmp/sccs.xAqaYY 2005-05-02 14:08:50.000000000 -0700 --- ./src/share/classes/javax/swing/DefaultDesktopManager.java 2005-05-02 13:31 :06.000000000 -0700 *************** *** 194,200 **** catch (PropertyVetoException e2) { } nextFrame.moveToFront(); } ! } /** --- 194,202 ---- catch (PropertyVetoException e2) { } nextFrame.moveToFront(); } ! else { ! c.requestFocus(); ! } } ###@###.### 2005-05-02 23:50:51 GMT
02-05-2005