Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8013611

Modal dialog fails to obtain keyboard focus

    XMLWordPrintable

Details

    • b105
    • generic
    • windows
    • Verified

    Backports

      Description

        FULL PRODUCT VERSION :
        java version " 1.7.0_13 "
        Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
        Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Windows 7 Enterprise Service Pack 1

        A DESCRIPTION OF THE PROBLEM :
        If a modal dialog is displayed from a focus listener and at the same time some modifications to focus are done in the frame in background then the dialog will fail to obtain focus. Both calls to requestFocusInWindow and use of FocusTraversalPolicy seems to provoke this bug.

        Stepping in the debugger it looks like the dialog is processing focusing events not related to the dialog but instead related to the frame in background which makes the focus state broken.

        REGRESSION. Last worked in version 6u31

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        The following steps will produce the problem

        - Add a focus listener to a JTextField
        - In the focusLost() method display an modal dialog
        - In the next component that will receive focus add a focus listener and in the focusGained() method call requestFocusInWindow() for any other component in the same frame

        When focus is lost on the text field the dialog fails to gain focus and the focus is instead given to the component called for requestFocusInWindow()

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Focus placed on the default component inside the modal dialog
        ACTUAL -
        Focus is placed in the frame in the background, from the keyboard it's possible to tab around in the frame in the background and also to activate buttons by pressing enter on keyboard.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.BorderLayout;
        import java.awt.Dimension;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import java.awt.event.FocusAdapter;
        import java.awt.event.FocusEvent;
        import javax.swing.JButton;
        import javax.swing.JFrame;
        import javax.swing.JOptionPane;
        import javax.swing.JPanel;
        import javax.swing.JTextField;
        import javax.swing.UIManager;
        import javax.swing.UnsupportedLookAndFeelException;

        /**
         *
         * @author jonas
         */
        public class SwingFocusBug extends JFrame {

            JTextField textField = new JTextField( " Press <tab> on keyboard " );
            JButton button1 = new JButton( " 1 " );
            JButton button2 = new JButton( " 2 " );

            public SwingFocusBug() {
                initComponents();

                textField.addFocusListener(new FocusAdapter() {
                    @Override
                    public void focusLost(FocusEvent e) {
                        JOptionPane.showMessageDialog(SwingFocusBug.this,
                                 " Focus is now in frame behind and not in the dialog! " );
                    }
                });

                button1.addFocusListener(new FocusAdapter() {
                    @Override
                    public void focusGained(FocusEvent e) {
                        button2.requestFocusInWindow();
                    }
                });

                button2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        button2.setText( " Button 2 pressed! " );
                    }
                });
            }

            private void initComponents() {
                JPanel panel = new JPanel();
                panel.setLayout(new BorderLayout());
                panel.add(textField, BorderLayout.CENTER);
                panel.add(button1, BorderLayout.EAST);
                panel.add(button2, BorderLayout.SOUTH);

                add(panel);

                setSize(new Dimension(500, 200));

            }

            public static void main(String[] args) throws ClassNotFoundException,
                    InstantiationException, IllegalAccessException,
                    UnsupportedLookAndFeelException {

                UIManager.setLookAndFeel( " com.sun.java.swing.plaf.windows.WindowsLookAndFeel " );

                SwingFocusBug frame = new SwingFocusBug();
                frame.setVisible(true);


            }
        }

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

        CUSTOMER SUBMITTED WORKAROUND :
        In the focus listener displaying the dialog, make sure all events related to focus changes in the parent frame are dispatch by the event queue by wrapping the code in at least two SwingUtils.invokeLater blocks:

            private FocusListener fieldFocusListener = new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            SwingUtilities.invokeLater(new Runnable() {
                                @Override
                                public void run() {
                                    // code that will display a dialog
                                }
                            });
                        }
                    });
                }
            };

        Attachments

          Issue Links

            Activity

              People

                ant Anton Tarasov (Inactive)
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                12 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: