JDK-6382144 : REGRESSION: InputVerifier and JOptionPane
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2006-02-07
  • Updated: 2011-02-16
  • Resolved: 2006-04-15
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 JDK 6
5.0u10Fixed 6 b81Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Suse Linux 9.3
Linux xitx00ha 2.6.8-24.16-smp #1 SMP Thu Jun 2 12:09:57 UTC 2005 i686 i686 i386 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
This Bug did not occur on one of our windows test systems, only on the linux test systems

Try a focus change with tab. It leads to an endless loop. regardless of using verify or shouldYieldFocus.

public class TestInputVerifyOptionPaneBug {

    public static void main(String[] pArgs) throws Exception {

        final JTextField t1 = new JTextField();
        t1.setInputVerifier(new InputVerifier() {
            public boolean verify(JComponent input) {
                JOptionPane.showMessageDialog(input, "test");
                return true;
            }
        });
        final JTextField t2 = new JTextField();


        JFrame frame = new JFrame();
        frame.getContentPane().add(t1, BorderLayout.NORTH);
        frame.getContentPane().add(t2, BorderLayout.SOUTH);
        frame.setVisible(true);
    }
}

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
see description

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a focus change to the second textfield

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.JTextField;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import java.awt.BorderLayout;

/public class TestInputVerifyOptionPaneBug {

    public static void main(String[] pArgs) throws Exception {

        final JTextField t1 = new JTextField();
        t1.setInputVerifier(new InputVerifier() {
            public boolean verify(JComponent input) {
                JOptionPane.showMessageDialog(input, "test");
                return true;
            }
        });
        final JTextField t2 = new JTextField();


        JFrame frame = new JFrame();
        frame.getContentPane().add(t1, BorderLayout.NORTH);
        frame.getContentPane().add(t2, BorderLayout.SOUTH);
        frame.setVisible(true);
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
no workaround

Comments
SUGGESTED FIX we should not call InputVerifier in during toplevel activation
03-04-2006

EVALUATION will fix it alone with 6378278 in mustang (in update release it should be fixed by Swing)
20-03-2006

EVALUATION It looks like this is regression from fix for 6210088 (The fix for 4774166 need to be changed) inter=grated in mustang and 5.0u4. In this fix the following code was added to JComponent.runInputVerifier(): + if (focusOwner == null) { + // If we are moving focus from another window, we should detect + // what element was in focus in the window that will be focused now. + // To do this, static package private method + // KeyboardFocusManager.getMostRecentFocusOwner() will be called. + // We will use AccessController.doPrivileged() to make package + // private method accessible. + Window window = SwingUtilities.getWindowAncestor(this); + if (window != null) { + try { + Method accessibleMethod = + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction<Method>() { + public Method run() throws Exception { + Method method = + KeyboardFocusManager.class.getDeclaredMethod( + "getMostRecentFocusOwner", Window.class); + method.setAccessible(true); + return method; + } + } + ); + focusOwner = (Component)(accessibleMethod.invoke(null, + window)); + } + catch (Exception e) { + focusOwner = null; + } + } + } + but it doesn't work well in case when most recent focus owner has been chandged while the window was unfocused. In this case DefaultKeyboardFocusManager does two focus requests: first to component which received temporary focus lost (when we activate another toplevel) and second to current most recent focus owner (the last component in the toplevel we requested focus). So, in our case: 1. Tab causes request focus on second text field (tf2) 2. InputVerifier shows dialog, the first text field (tf1) receives temporary focus lost (it also is most recent focus owner for the frame) 3. user closes the dialog and we call requestFocus() on tf2 (after this call tf2 is most recent focus owner for the frame). 4. DKFM receives WIDNOW_GAINED_FOCUS and requests focus on tf1 (as the component which has received temporary focus lost) and tf2 (as most recent focus owner for the frame). 5. During the latter requestFocusInWindow() (on tf2) the most recent focus owner is tf1 (again) because of former focus request. Thus runInputVerifier() runs InputVerifier for tf1. So, it looks like Swing needs to invent more complecated scheme to correct runInputVerifier() :(
21-02-2006

EVALUATION I can reproduce this with 1.5.0_06-b05. I cannot reproduce it with Mustang. However, note that in Mustang InputVerifier is broken already for TAB traversal. As such, use the mouse to change focus when testing in Mustang. I think this is an AWT issue. Here's the series of events: - Try to change focus with TAB or Mouse - InputVerifier is queried and dialog is shown - When the dialog is dismissed, super.requestFocus() should be called to allow the focus transfer to the second component - Instead, dismissing the window is causing a requestFocusInWindow() to occur, triggering another check with the InputVerifier. I'm not sure what the reason is for this requestFocusInWindow(0), but suspect an AWT change.
13-02-2006

EVALUATION I'm able to reproduce it on Linux and Windows both with JDK6.0b34. On linux it behaves the same with XAWT and with Motif. It's not reproducible with JDK5.0b64 and JDK6.0b65 so I think it's just appeared in the middle of mustang and then eliminated. We possibly need to fix it in update release also. As this seems not a platform specific and it's not possible to make the test on AWT then I'm about to return it back to swing.
13-02-2006

EVALUATION Platform specific - likely AWT.
10-02-2006