2017-10-05 181 views
2

我运行的应用程序具有与下面测试用例类似的行为。Java 8 - 切换窗口后丢失所有键盘输入或焦点

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

回答

2

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

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

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

这将允许由该对话框之前看到的文本字段获得正确聚焦。

+0

是的,谢谢。不过,我发现这令人不安,这已经改变了7到8之间的行为。 –