Problem to focus JTextField

2019-08-14 05:12发布

(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.

3条回答
女痞
2楼-- · 2019-08-14 05:26

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

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5018574

查看更多
虎瘦雄心在
3楼-- · 2019-08-14 05:34

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)?

查看更多
Lonely孤独者°
4楼-- · 2019-08-14 05:36

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.

查看更多
登录 后发表回答