【问题标题】:Java 8 - Losing all keyboard input or focus after switching windowsJava 8 - 切换窗口后丢失所有键盘输入或焦点
【发布时间】:2017-10-05 00:43:41
【问题描述】:

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

问题在于,当您通过单击将焦点切换到另一个窗口并保持下面的应用程序框架处于视图中,然后使用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;
    }
}

【问题讨论】:

    标签: java swing java-8 keyboard focus


    【解决方案1】:

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

    @Override
    public void focusGained(FocusEvent e)
    {
        noFocus.requestFocusInWindow();
    
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                    createDialog().setVisible(true);
            }
        });
    }
    

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

    【讨论】:

    • 是的,谢谢。不过,我发现这在 7 和 8 之间改变了行为,这让我感到不安。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多