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

Request focus causes KeyEvents to be lost if Modal dialog displayed

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Reproducible on Window and Linux in Java 8

      A DESCRIPTION OF THE PROBLEM :
      Requesting focus when a button is pressed and and window is closed seems to cause issues with the focus system. Specifically buttons are calling actions listeners on a MousePressed instead of MouseReleased and if a modal dialog is displayed as part of the button click it becomes impossible to type into the dialog.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run provided source code, right click in the window. While the "Suprise" popup is visible click the Add button. While the dialog is opened click in the "Firstname" input followed the "Lastname" input.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The add button opens the dialog until the button is released and able to enter data in the firstname or lastname text inputs.
      ACTUAL -
      The add button open the dialog on MousePressed and unable to enter data in the firstname or lastname text inputs.

      ---------- BEGIN SOURCE ----------
      import java.awt.AWTEvent;
      import java.awt.BorderLayout;
      import java.awt.Toolkit;
      import java.awt.event.AWTEventListener;
      import java.awt.event.ActionEvent;
      import java.awt.event.MouseAdapter;
      import java.awt.event.MouseEvent;
      import java.util.logging.ConsoleHandler;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import java.util.logging.SimpleFormatter;

      import javax.swing.AbstractAction;
      import javax.swing.GroupLayout;
      import javax.swing.JButton;
      import javax.swing.JDialog;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JTextField;
      import javax.swing.JWindow;
      import javax.swing.SwingUtilities;
      import javax.swing.WindowConstants;

      public class RequestFocus {

          private static ConsoleHandler consoleHandler = new ConsoleHandler();
          static {
              consoleHandler.setFormatter(new SimpleFormatter());
              consoleHandler.setLevel(Level.ALL);
          }

          public static void main(final String[] args) {
              Logger.getLogger("").setLevel(Level.ALL);

              final Logger log = Logger.getLogger("java.awt.focus");
              log.setLevel(Level.FINEST);
              log.addHandler(consoleHandler);


              SwingUtilities.invokeLater(() -> {

                  final JFrame frame = new JFrame("Request Focus");
                  frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

                  final JPanel popupPanel = new JPanel();

                  popupPanel.addMouseListener(new MouseAdapter() {
                      @Override
                      public void mousePressed(final MouseEvent e) {
                          final JTextField popup = new JTextField("Suprise!!!");

                          final JWindow window = new JWindow(frame);
                          window.getContentPane().add(popup);


                          final AWTEventListener awtEventListener = new AWTEventListener() {

                              @Override
                              public void eventDispatched(final AWTEvent event) {
                                  if(event instanceof MouseEvent) {
                                      final MouseEvent mouseEvent = (MouseEvent) event;
                                      if(mouseEvent.getID() == MouseEvent.MOUSE_PRESSED) {
                                          popupPanel.requestFocus();
                                          Toolkit.getDefaultToolkit().removeAWTEventListener(this);
                                      }
                                  }

                              }
                          };

                          Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, AWTEvent.MOUSE_EVENT_MASK);

                          window.pack();
                          window.setLocation(e.getXOnScreen(), e.getYOnScreen());
                          window.setVisible(true);

                          popup.requestFocus();
                      }
                  });

                  frame.add(popupPanel, BorderLayout.CENTER);
                  frame.add(new JButton(new AbstractAction("Add") {

                      private static final long serialVersionUID = 1L;

                      @Override
                      public void actionPerformed(final ActionEvent e) {
                          final JDialog addDialog = new JDialog(frame, "Add", true);
                          addDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

                          final JLabel firstnameLabel = new JLabel("First name");
                          final JLabel lastnameLabel = new JLabel("Last name");

                          final JTextField firstnameInput = new JTextField(20);
                          final JTextField lastnameInput = new JTextField(20);

                          final JPanel edidNamePanel = new JPanel();

                          final GroupLayout editNameLayout = new GroupLayout(edidNamePanel);
                          edidNamePanel.setLayout(editNameLayout);
                          editNameLayout.setAutoCreateContainerGaps(true);

                          final GroupLayout.SequentialGroup hGroup = editNameLayout.createSequentialGroup();
                          hGroup.addGroup(editNameLayout.createParallelGroup().addComponent(firstnameLabel).addComponent(lastnameLabel));

                          hGroup.addGroup(editNameLayout.createParallelGroup().addComponent(firstnameInput).addComponent(lastnameInput));

                          editNameLayout.setHorizontalGroup(hGroup);

                          final GroupLayout.SequentialGroup vGroup = editNameLayout.createSequentialGroup();
                          vGroup.addGroup(editNameLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                  .addComponent(firstnameLabel)
                                  .addComponent(firstnameInput));
                          vGroup.addGroup(editNameLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                  .addComponent(lastnameLabel)
                                  .addComponent(lastnameInput));
                          editNameLayout.setVerticalGroup(vGroup);

                          addDialog.add(edidNamePanel);

                          addDialog.pack();
                          addDialog.setLocationRelativeTo(popupPanel);
                          addDialog.setVisible(true);
                      }
                  }), BorderLayout.SOUTH);


                  frame.setSize(500, 500);
                  frame.setVisible(true);


              });
          }

      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            bvaidya Balchandra Vaidya
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: