Student
Student

Reputation: 28345

Problem to focus JTextField

(Problem occur in Ubuntu only. Works fine in Windows. I don't know in other Linux environments)

I have used the approach of the ComponentListener to call focus in JTextField within a dialog, but for this case is just not working, I don't know why. It shows the focus in the text field and fast change to the button. Run and see:

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class User {

    private String username = "";
    private String password = "";

    public User() {
    // default constructor
    }

    public User(String username, String password) {
    this.username = username;
    this.password = password;
    }

    /** Create a panel containing the componet and tha label. */
    public JPanel createLabeledComponent(JLabel label, Component comp) {
    GridLayout layout = new GridLayout(2, 1);
    JPanel panel = new JPanel(layout);
    panel.add(label);
    panel.add(comp);
    label.setLabelFor(comp);
    return panel;
    }

    public void showEditDialog() {

    JLabel usernameLbl = new JLabel(username);
    final JTextField usernameField = new JTextField();
    usernameField.setText(username);
    JPanel usernamePnl = createLabeledComponent(usernameLbl, usernameField);

    JLabel passwordLbl = new JLabel(password);
    JPasswordField passwordField = new JPasswordField(password);
    JPanel passwordPnl = createLabeledComponent(passwordLbl, passwordField);

    Object[] fields = { "User:", usernamePnl, "Password:", passwordPnl };

    JOptionPane optionPane = new JOptionPane(fields, JOptionPane.PLAIN_MESSAGE,
        JOptionPane.OK_CANCEL_OPTION, null, null);
    JDialog dialog = optionPane.createDialog("User Data");

    dialog.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentShown(ComponentEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
            usernameField.requestFocusInWindow();
            }
        });
        }
    });

    dialog.setVisible(true);
    }

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
        new User().showEditDialog();
        }
    });
    }

}

Any idea how to solve this?

--update

Everything running on EDT now. Sadly with the same behavior.

By the way, either using the last argument (Object initialValue) of the JOptionPane constructor doesn't work.

Upvotes: 1

Views: 3137

Answers (3)

eaolson
eaolson

Reputation: 15094

From How to Use the Focus Subsytem:

Exactly how a window gains the focus depends on the windowing system. There is no foolproof way, across all platforms, to ensure that a window gains the focus.

Furthermore, from Component.requestFocusInWindow:

Every effort will be made to honor the request; however, in some cases it may be impossible to do so. Developers must never assume that this Component is the focus owner until this Component receives a FOCUS_GAINED event.

Your components may not be realized before you are calling requestFocusInWindow. Have you tried putting a dialog.pack(); before the setVisible(true)?

Upvotes: 0

darri
darri

Reputation: 562

I remember having a similar problem, I used the solution found at the bottom of this page:

https://bugs.java.com/bugdatabase/view_bug?bug_id=5018574

Upvotes: 1

camickr
camickr

Reputation: 324118

Maybe this Dialog Focus solution will work on Ubuntu (I can't test it).

It shows the focus in the text field and fast change to the button.

Or you could try wrapping the requestFocusInWindow() method call in a SwingUtilities.invokeLater() to place your requrest on the end of the EDT.

Upvotes: 0

Related Questions