JDK-4917166 : PIT: Ctrl+ F is not working properly in JInternalFrame
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0,5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2003-09-04
  • Updated: 2005-05-02
  • Resolved: 2004-09-03
Related Reports
Duplicate :  
Description
Ctrl+ F is not working properly in JInternalFrame. 

Steps to reproduce:
--------------------
1) Run SwingSet2. 
2) Go to Internal Frame demo. 
3) Select any InternalFrame say 'Frame 0'. 
4) Now press Ctlr + F6. Focus will go to 'Frame 4'.
5) Now press ctrl + F6 again, focus will be transfered to 'Frame3' . 
6) Now again Press ctrl + F6, focus will again go back to 'Frame 4' and this will continue like this. Focus will never go out of these two frames.
7) Now press ctrl+F5, supposing that the focus was on 'Frame 4'. this will close this frame. ctrl + F6, it will not work, after this.   also ctrl+F5 will not work after this.
 For both of these key bindings to work we have to click on some other frame. But the above behavior can be reproduced again. 

This is happening on win 2k Prof and Solaris for Ocean LAF. I have not tried this on Linux. This is behaving correctly on Tiger Build 17, infact till last PIT request it is behaving properly , but not in the current PIT request. 

The java version for the current pit is :
 
java version "swing-jcg-sparc-01-2003-08-29-int.tiger"
Java(TM) 2 Runtime Environment, Standard Edition (build swing-jcg-sparc-01-2003-08-29-int.tiger)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b17, mixed mode)

Correction: ctrl+F4 closes a frame, not ctrl+F5
###@###.### 2005-04-28 04:22:35 GMT

Comments
EVALUATION This is only one particular test case in testing this keyboard action. Due to problems in focus there are other ways of causing the keyboard actions to fail due to lack of a focus owner. More complete test cases need to be made to cover all these cases. ###@###.### 2003-09-04 This is a duplicate of 4878528. ###@###.### 2004-09-03 -------------------------------------------------------------------- Problem: Focus is lost when a JInternalFrame is closed, either by pressing cntrl+F4, or by clicking the close button on the titlepane. The focus should automatically move to the next JInternalFrame. But the dispose of the closed JInternalFrame is causing the focus to be lost for the next JInternalFrame which just got automatically activated. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/share/classes/javax/swing/JInternalFrame.java public void doDefaultCloseAction() { ... firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE); dispose(); ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The above firePropertyChange causes the following requestFocus via activateNextFrame, which is good: at java.awt.Component.requestFocusHelper(Unknown Source) at java.awt.Component.requestFocus(Unknown Source) at javax.swing.JComponent.requestFocus(JComponent.java:1506) at javax.swing.JInternalFrame.restoreSubcomponentFocus(Unknown Source) at javax.swing.JInternalFrame.setSelected(Unknown Source) at javax.swing.DefaultDesktopManager.activateNextFrame(Unknown Source) at javax.swing.DefaultDesktopManager.closeFrame(Unknown Source) at javax.swing.plaf.basic.BasicInternalFrameUI.closeFrame(BasicInternalF rameUI.java:496) at javax.swing.plaf.basic.BasicInternalFrameUI$Handler.propertyChange(Ba sicInternalFrameUI.java:1526) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSup port.java:333) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSup port.java:270) at java.awt.Component.firePropertyChange(Unknown Source) at javax.swing.JInternalFrame.doDefaultCloseAction(Unknown Source) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The above dispose causes the following clearGlobalFocusOwner, which is bad, because it clears (loses) the focus set by requestFocus above: at java.awt.KeyboardFocusManager.clearGlobalFocusOwner(Unknown Sourc at java.awt.Component.doAutoTransfer(Unknown Source) at java.awt.Component.autoTransferFocus(Unknown Source) at java.awt.Component.autoTransferFocus(Unknown Source) at java.awt.Component.hide(Unknown Source) at javax.swing.JInternalFrame.hide(Unknown Source) at java.awt.Component.show(Unknown Source) at java.awt.Component.setVisible(Unknown Source) at javax.swing.JComponent.setVisible(JComponent.java:2625) at javax.swing.JInternalFrame.dispose(Unknown Source) at javax.swing.JInternalFrame.doDefaultCloseAction(Unknown Source) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ As a debug verification, I added the line below to prevent KeyboardFocusManager.clearGlobalFocusOwner() from executing. This one change eliminates bug 4917166. src/share/classes/java/awt/KeyboardFocusManager.java ------- KeyboardFocusManager.java ------- *** /tmp/sccs.PfwUKh 2005-04-27 21:12:48.000000000 -0700 --- KeyboardFocusManager.java 2005-04-27 20:55:50.000000000 -0700 *************** *** 538,543 **** --- 538,544 ---- * @see java.awt.event.FocusEvent#FOCUS_LOST */ public void clearGlobalFocusOwner() { + if (true) return; if (!GraphicsEnvironment.isHeadless()) { // Toolkit must be fully initialized, otherwise // _clearGlobalFocusOwner will crash or throw an exception ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Summary: When a JInternalFrame is closed, either by pressing cntrl+F4, or by clicking the close button on the titlepane, the firePropertyChange causes the next JInternalFrame to be automatically activated and its focus requested. But then the dispose of the closed JInternalFrame causes clearGlobalFocusOwner to clear (lose) the focus of the next JInternalFrame which just got automatically activated by the firePropertyChange. The dispose of a JInternalFrame should not clear (lose) the focus of the next JInternalFrame which just got automatically activated by the firePropertyChange. In the trace above it looks like java.awt.Component.autoTransferFocus should be transferring the focus to the next JInternalFrame. Denis, Is there a bug in java.awt.Component.autoTransferFocus? Is the call to clearGlobalFocusOwner really necessary? It looks like the dispose should be moved to a better location, before the activation of the next JInternalFrame. Or the dispose could be moved from doDefaultCloseAction to closeFrame, between the calls to c.remove(f) and activateNextFrame. Here are the diffs for a workaround fix: ---------------------------------------------------------------------------- ------- JInternalFrame.java ------- *** /tmp/sccs.UElqN0 2005-04-28 16:45:28.000000000 -0700 --- JInternalFrame.java 2005-04-28 15:45:01.000000000 -0700 *************** *** 1550,1556 **** isClosed = true; firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE); - dispose(); } catch (PropertyVetoException pve) {} break; default: --- 1550,1555 ---- ------- DefaultDesktopManager.java ------- *** /tmp/sccs.2vOSP6 2005-04-28 16:46:20.000000000 -0700 --- DefaultDesktopManager.java 2005-04-27 22:44:05.000000000 -0700 *************** *** 82,87 **** --- 82,88 ---- f.setNormalBounds(null); if(wasIcon(f)) setWasIcon(f, null); + f.dispose(); if (findNext) activateNextFrame(c); } ---------------------------------------------------------------------------- The following is a better fix. This fixes the case when a JInternalFrame is closed, and the focus is not transferred to the next JInternalFrame. This was caused by the dispose clearing the focus after it was set by the firePropertyChange. Calling setVisible(false) before firePropertyChange and dispose fixes this. This fix was included in the fix for 4878528 which Josh made this bug a duplicate of. ------- JInternalFrame.java ------- *** /tmp/sccs.302z8i 2005-05-02 14:15:09.000000000 -0700 --- ./src/share/classes/javax/swing/JInternalFrame.java 2005-05-02 13:21:42.000000000 -0700 *************** *** 804,809 **** --- 804,812 ---- } fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue); isClosed = b; + if (isClosed) { + setVisible(false); + } firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue); if (isClosed) { dispose(); *************** *** 1548,1553 **** --- 1551,1557 ---- fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE); isClosed = true; + setVisible(false); firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE); dispose(); ###@###.### 2005-05-02 23:57:56 GMT ###@###.### 2005-05-02 23:59:57 GMT
02-05-2005