Java 8 - 切换窗口后丢失所有键盘输入或焦点

标签 java swing java-8 keyboard focus

我正在运行一个与下面的测试用例具有类似行为的应用程序。

问题是,当您通过单击将焦点切换到另一个窗口并保持下面的应用程序框架在 View 中,然后直接单击带有 focusGained 监听器的文本字段时,关闭对话框然后所有键输入将丢失到应用程序中的所有文本字段。

如果您首先单击应用程序中的任意位置或任务栏中的图标以重新获得焦点,则不会发生这种情况。

这是特定于 Java 8 的——在 Java 7 中它不会失去焦点,不确定 Java 9 但这不是一个选项

下面的测试用例演示了这种行为。

public class FocusTest extends JFrame
{
    JTextField noFocus;

    public static void main(String[] args)
    {
         FocusTest ft = new FocusTest();
         ft.setVisible(true);
    }

    public FocusTest()
    {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(100,100,300,150);
        setLayout(new GridLayout(3,1, 2, 2));
        setTitle("Losing keyboard...");
        noFocus = new JTextField();
        add(noFocus);

        JTextField jft = new JTextField();
        jft.addFocusListener(new FocusAdapter()
        {
            @Override
            public void focusGained(FocusEvent e)
            {
                createDialog().setVisible(true);
                noFocus.requestFocusInWindow();
            }
        });
        add(jft);

        JButton jb = new JButton("OPEN");
        jb.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if(e.getActionCommand().equals("OPEN"))
                    createDialog().setVisible(true);
            }
        });
        add(jb);
    }

    private JDialog createDialog()
    {
        final JDialog jd = new JDialog(this, true);
        jd.setLocationRelativeTo(this);
        jd.setLayout(new BorderLayout());
        jd.getContentPane().add(new JTextField(), BorderLayout.CENTER);
        JButton jb = new JButton("Close");
        jb.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if(e.getActionCommand().equals("Close"))
                    jd.dispose();
            }
        });
        jd.getContentPane().add(jb, BorderLayout.SOUTH);
        jd.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        jd.pack();
        return jd;
    }
}

最佳答案

不确定发生了什么,但一种解决方案是使用 SwingUtilities.invokeLater():

@Override
public void focusGained(FocusEvent e)
{
    noFocus.requestFocusInWindow();

    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
                createDialog().setVisible(true);
        }
    });
}

这将允许文本字段在对话框可见之前正确获得焦点。

关于Java 8 - 切换窗口后丢失所有键盘输入或焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46576220/

相关文章:

java - 在集群运行时更新更改

java - 连接两个数组 Stream 时出现 ArrayStoreException

java - 我无法从另一个类设置 JLabel 的文本

java - Graphics2D - 在 Graphics2D 对象上旋转形状

java - 如何在 GridBagLayout 中将 JLabel 与 JTextField 对齐

dictionary - 如何使用Java 8中的方法引用进行Map合并?

java - 何时使用 Optional.orElse() 而不是 Optional.orElseGet()

java - 如何使用 ImageJ-Plugin 水平翻转图像?

java - 按顺序使用 REST API,多线程环境中每次调用之间至少间隔 100 毫秒。 (带 RestTemplate)

java null/empty-list 返回与代码中抛出异常重新思考其余世界的最佳实践