Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I requestFocus on component in JOptionPane.showConfirmDialog?

Tags:

java

focus

swing

Using the JOptionPane.showConfirmDialog with a customized component (JPanel), I like to have focus on a specific component (JPasswordField) as it opens. How can this be achieved?

Code example: The JPasswordField pf should have focus when dialogs open...

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;


public class JTestOptionDialog {

  public static void main(String[] args) {  
    JFrame frame = new JFrame("Test showConfirmDialog");
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(new JPanel());
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    JLabel label = new JLabel("<html><body>To access insert <b>password</b></body></html>");
    JPasswordField pf = new JPasswordField();
    JPanel panel = new JPanel(new GridBagLayout());
    panel.add(label,new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
    panel.add(pf,new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
    pf.requestFocus(); //THIS IS WHAT I LIKE TO HAVE FOCOUS WHEN DIALOG OPENS
    int retVal = JOptionPane.showConfirmDialog(frame,panel,"Impostazioni",JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
    System.out.println(retVal);
  }
}

Is it possible in someway to request focus on my desired JPasswordField pf or do I need to "To create and use an JOptionPane directly"?

As a note I have tried with (what seemed logical)

pf.addComponentListener(new ComponentAdapter(){
  public void componentShown(ComponentEvent ce){
    pf.requestFocus(); //pf.requestFocusInWindow();
  }
});

But no luck with this either...

like image 222
Petter Friberg Avatar asked Dec 01 '15 13:12

Petter Friberg


2 Answers

I found a way by adding and removing a listener but I don't really like it. I am open to better solutions.

pf.addAncestorListener(new AncestorListener() {     

    public void ancestorRemoved(AncestorEvent event) {}

    public void ancestorMoved(AncestorEvent event) {}            

    public void ancestorAdded(final AncestorEvent event) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                event.getComponent().requestFocusInWindow();
                event.getComponent().removeAncestorListener(this);
            }
        });
    }
});
like image 111
Petter Friberg Avatar answered Sep 22 '22 04:09

Petter Friberg


You are very close to the solution with your own answer. You are right though that adding/removing is messy. This is a bit neater.

Try this:

pf.addAncestorListener(new AncestorListener() {
    @Override
    public void ancestorRemoved(AncestorEvent event) {}

    @Override
    public void ancestorMoved(AncestorEvent event) {}

    @Override
    public void ancestorAdded(AncestorEvent event) {
        event.getComponent().requestFocusInWindow();
    }
});

And make sure you put that code before you call JOptionPane.showConfirmDialog()

I found the answer here if you want more information Setting component focus in JOptionPane.showOptionDialog()

like image 26
Redtama Avatar answered Sep 22 '22 04:09

Redtama