5

This may seem trivial, but I can't figure out how to give the password box in this dialog focus.

import javax.swing.JOptionPane;
import javax.swing.JPasswordField;

public class PasswordBox {
    @SuppressWarnings("unused")
    public String prompt() {
        JPasswordField pass = new JPasswordField(10);
        int action = JOptionPane.showConfirmDialog(null, pass,"Enter Password",JOptionPane.OK_CANCEL_OPTION); 
        return new String(pass.getPassword());
    }
}

I invoke it from other classes like this: String tmpPASS = new PasswordBox().prompt();

For some reason, when the dialog shows up, the "OK" button gets focus.

stacktrace (see Eng.Fouad's answer):

at javax.swing.JComponent.addNotify(Unknown Source)
at PasswordBox$1.addNotify(PasswordBox.java:14)
at java.awt.Container.addNotify(Unknown Source)
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • http://stackoverflow.com/questions/6251665/setting-component-focus-in-joptionpane-showoptiondialog/21426340# – Frank M. Jan 29 '14 at 09:03

4 Answers4

7

Check out the solution presented in Dialog Focus.

Edit:

Using the approach suggested by Eng Fouad I believe the code should be:

JPasswordField pass = new JPasswordField(10)         
{
    public void addNotify()             
    {                 
        super.addNotify();
        requestFocusInWindow();             
    }         
}; 

Edit2:

The link in the "Dialog Focus" blog entry has a comment with a suggestion that works on Linux.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I tried this solution with AncestorListener. Unfortunately the callbacks are not called at all, so the code does not work. What's wrong? – AlexR Jul 13 '11 at 14:24
  • I've tested it on JDK6_7 on XP. Maybe it is a version/platform issue? One of the comments suggested using a HierarchyListener. Try that and see what happens. – camickr Jul 13 '11 at 14:27
  • The solution presented in the Dialog Focus link worked for me! :) – Shervin Asgari Jul 16 '12 at 08:50
  • 2
    Use the Dialog Focus link he has at the top of this answer, that worked for me. – Richard Dec 19 '14 at 23:40
1
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;

public JOptionPane pane;

public class PasswordBox
{
    @SuppressWarnings("unused")
    public String prompt()
    {
        pane = new JOptionPane();
        JPasswordField pass = new JPasswordField(10)
        {
            public void addNotify()
            {
                pane.addNotify();
                requestFocus();
            }
        };
        int action = pane.showConfirmDialog(null, pass,"Enter Password",JOptionPane.OK_CANCEL_OPTION);
        return new String(pass.getPassword());
     }
}

or here is another way to do it:

JPanel panel = new JPanel();
JPasswordField pass = new JPasswordField(10)
{
    public void addNotify()
    {
        panel.addNotify();
        requestFocus();
    }
};
panel.add(pass);
JOptionPane pane = new JOptionPane();
JButton btnOK = new JButton("OK");
JButton btnCancel = new JButton("Cancel");
Object[] options = {btnOK, btnCancel};
pane.showOptionDialog(null, panel, "Enter the password", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, null);

Edit (by camickr, feel free to remove if this is not correct). I believe the code should be:

JPasswordField pass = new JPasswordField(10)         
{
    public void addNotify()             
    {                 
        super.addNotify();
        requestFocusInWindow();             
    }         
}; 
camickr
  • 321,443
  • 19
  • 166
  • 288
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • Had to add "final" to pane's declaration, but it still doesn't work. Thanks for your help though, it is appreciated :) –  Jul 13 '11 at 15:07
  • @MaxMackie no need for `final`, just make it as class field, see the update – Eng.Fouad Jul 13 '11 at 15:09
  • I still can't get the first solution working, but the second solution gives me a stacktrace. I'll add it to my question. –  Jul 13 '11 at 15:40
0

here is a working solution with focus in password field and working buttons

https://stackoverflow.com/a/21426340/2110961

Community
  • 1
  • 1
Frank M.
  • 997
  • 1
  • 10
  • 19
0

The problem is that JOptionPane is completely self contained, and seems to offer no way to specify which GUI component gets the initial focus. One solution would be to write your own subclass of Dialog - that will let you control the layout exactly and set the focus appropriately.

You might also try a javax.swing.SwingWorker. You could create one of these and start it BEFORE showing the password dialog. In the doInBackground() method, sleep for a short time, in the done() method use SwingUtilties.invokeLater() and within that Runnable, issue pass.requestFocusInWindow().

Mitch
  • 989
  • 1
  • 9
  • 25