2017-10-05 45 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之間的行爲。 –