chrixm
chrixm

Reputation: 1024

JPasswordField Focus in JOptionPane on MacOS

The concept of using a JOptionPane within a JDialog to show a JPasswordField is something which has been asked and answered before, but for some reason I can't get the focus on the JPasswordField on Mac OS under Java 7 (Oracle). The following code works on Windows and uses a ComponentListener to set the focus to the JPasswordField on componentShown. I have even tried wrapping it in invokeLater, although I don't think this is required as I am executing this on the EDT.

private String passwordPrompt(String p) {
  String thePassword = null;
  final JPasswordField pf = new JPasswordField();
  JOptionPane op = new JOptionPane(pf, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
  JDialog d = op.createDialog(p);
  d.addComponentListener(new ComponentListener() {
    @Override
    public void componentShown(ComponentEvent e) {
      SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
          pf.requestFocusInWindow();
        }
      });
    }
    @Override
    public void componentHidden(ComponentEvent e) {}

    @Override
    public void componentResized(ComponentEvent e) {}

    @Override
    public void componentMoved(ComponentEvent e) {}
  });

  if (uIcon != null) {
    d.setIconImage(new ImageIcon(uIcon).getImage());
  }
  d.setLocationRelativeTo(T);
  d.setVisible(true);

  if (op.getValue() == JOptionPane.OK_OPTION) {
    thePassword = new String(pf.getPassword());
  }
  if ((thePassword == null) || thePassword.isEmpty()) {
    thePassword = null;
  }

  d.dispose();
  return thePassword;
}

The function basically prompts the user for a password, but I would like the focus on the JPasswordField when the dialog is shown. Am I doing something wrong or am I hitting one of the quirks with Mac OS?

Upvotes: 0

Views: 176

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

Using a WindowFocusListener, this seems to work under Windows and Mac OS (Mavericks 10.9.5/Java 8)

    final JPasswordField pf = new JPasswordField(10);
    JOptionPane op = new JOptionPane(pf, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
    JDialog d = op.createDialog("Test");
    d.addWindowFocusListener(new WindowAdapter() {
        @Override
        public void windowGainedFocus(WindowEvent e) {
            pf.requestFocusInWindow();
        }
    });
    d.pack();
    d.setLocationRelativeTo(null);
    d.setVisible(true);

Upvotes: 1

camickr
camickr

Reputation: 324098

Check out Dialog Focus. It uses a HierarchyListener which might work for you.

Upvotes: 0

Related Questions