Java 关注JTextField的问题

Java 关注JTextField的问题,java,ubuntu,dialog,focus,Java,Ubuntu,Dialog,Focus,(这个问题只在Ubuntu中出现。在Windows中可以正常工作。我不知道在其他Linux环境中如何工作) 我已经使用ComponentListener的方法在对话框中调用JTextField中的焦点,但是对于这种情况,我不知道为什么它不起作用。它在文本字段中显示焦点,并快速更改按钮。运行并查看: import java.awt.Component; import java.awt.GridLayout; import java.awt.event.ComponentAdapter; impor

(这个问题只在Ubuntu中出现。在Windows中可以正常工作。我不知道在其他Linux环境中如何工作)

我已经使用ComponentListener的方法在对话框中调用JTextField中的焦点,但是对于这种情况,我不知道为什么它不起作用。它在文本字段中显示焦点,并快速更改按钮。运行并查看:

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();
        }
    });
    }

}
你知道怎么解决这个问题吗

--更新

现在所有东西都在EDT上运行。可悲的是,我也有同样的行为

顺便说一句,使用JOptionPane构造函数的最后一个参数(Object initialValue)都不起作用。

也许这个解决方案可以在Ubuntu上运行(我无法测试它)

它在文本字段中显示焦点 快速切换到按钮

或者您可以尝试将requestFocusInWindow()方法调用包装在SwingUtilities.invokeLater()中,将您的requestest放在EDT的末尾。

也许这个解决方案可以在Ubuntu上运行(我无法测试它)

它在文本字段中显示焦点 快速切换到按钮


或者您可以尝试将requestFocusInWindow()方法调用包装在SwingUtilities.invokeLater()中,以将您的Requirest放在EDT的末尾。

我记得有一个类似的问题,我使用了本页底部的解决方案:


我记得有一个类似的问题,我使用了本页底部的解决方案:

来自:

窗口获得焦点的确切方式取决于窗口系统。在所有平台上,都没有万无一失的方法来确保窗口获得焦点

此外,来自:

将尽一切努力履行这一要求;然而,在某些情况下,这样做可能是不可能的。在该组件收到焦点事件之前,开发人员决不能假定该组件是焦点所有者

在调用
requestFocusInWindow
之前,可能无法实现组件。您是否尝试过放置
dialog.pack()设置可见(真)

之前的代码>来自:

窗口获得焦点的确切方式取决于窗口系统。在所有平台上,都没有万无一失的方法来确保窗口获得焦点

此外,来自:

将尽一切努力履行这一要求;然而,在某些情况下,这样做可能是不可能的。在该组件收到焦点事件之前,开发人员决不能假定该组件是焦点所有者


在调用
requestFocusInWindow
之前,可能无法实现组件。您是否尝试过放置
dialog.pack()
setVisible(true)

之前,感谢您发布code+1,createDialog(String)方法未找到:-)@ringbearer,javadocs注意到该方法是“自1.6”,我猜您使用的JRE比该方法旧:)正确的。我在RHEL上使用JDK1.5。然而,我的最佳选择是JOPtionPane有一个内部FocusManager,它导致Tom的设置被覆盖。JOptionPane可能不是启动具有此行为的对话框的好方法。这是另一个计时问题吗?使用EDT@汤姆·霍丁-铲球线没有区别。试试看。感谢您发布代码+1,找不到createDialog(String)方法:-)@ringbearer,javadocs注意到该方法是“自1.6”,我猜您使用的JRE比它旧?:)正确的。我在RHEL上使用JDK1.5。然而,我的最佳选择是JOPtionPane有一个内部FocusManager,它导致Tom的设置被覆盖。JOptionPane可能不是启动具有此行为的对话框的好方法。这是另一个计时问题吗?使用EDT@汤姆·霍丁-铲球线没有区别。试试看。dialog.pack()没什么区别。dialog.pack()没什么区别。看来计时器是唯一的解决办法。Sad不是一个一致的解决方案(可能在一台计算机中工作,但在另一台计算机中不工作,并且可能取决于计算机速度)。无论如何,谢谢你的链接。我正在使用windowActivated方法中的计时器。不确定是否在任何地方都有效,但目前看来是最好的答案。看来计时器是唯一有效的解决方法。Sad不是一个一致的解决方案(可能在一台计算机中工作,但在另一台计算机中不工作,并且可能取决于计算机速度)。无论如何,谢谢你的链接。我正在使用windowActivated方法中的计时器。不确定是否在任何地方都有效,但看起来是目前最好的答案。所以你是说这个解决方案在你的环境中不起作用?很高兴知道,如果上面的链接不能在所有环境下运行,我可以更新它。如果我的解决方案没有按照发布的方式工作,那么下一步就是将焦点代码包装在Swing utilities.invokeLater()中,这样它就会被添加到EDT的末尾,并可能在将焦点重置到第一个字段的代码之后执行。那么你是说这个解决方案在你的环境中不工作?很高兴知道,如果上面的链接不能在所有环境下运行,我可以更新它。如果我的解决方案没有按发布的方式工作,那么下一步将是将焦点代码包装在Swing utilities.invokeLater()中,这样它将被添加到EDT的末尾,并可能在将焦点重置为第一个字段的代码之后执行。