Swing中requestFocusInWindow()和grabFocus()之间的区别

我想知道requestFocusInWindow()grabFocus()方法之间的区别。 他们两个都很适合在这个程序中抓住我的焦点。 因此,我无法理解其中的差异。

 import javax.swing.*; import java.awt.*; import java.awt.event.*; class Focus extends JFrame { JButton jb; public Focus() { createAndShowGUI(); } private void createAndShowGUI() { setTitle("grabFocus() vs requestFocusInWindow()"); setLayout(new FlowLayout()); setSize(400,400); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jb=new JButton("Open Dialog"); jb.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent ae) { showDialog(); } }); add(jb); } private void showDialog() { JDialog jd=new JDialog(); jd.setLayout(new GridLayout(2,2)); jd.setVisible(true); JLabel l1=new JLabel("Label 1"); JLabel l2=new JLabel("Label 2"); JTextField jt1=new JTextField(20); JTextField jt2=new JTextField(20); jd.add(l1); jd.add(jt1); jd.add(l2); jd.add(jt2); // Both of them are doing the thing //jt2.grabFocus(); jt2.requestFocus(); jd.pack(); } public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable(){ public void run() { new Focus(); } }); } } 

答案很简单,无论顶级祖先是否是聚焦窗口, 抓取焦点都会抓住焦点。 如果窗口未激活,则使其处于活动状态以使组件获得焦点。

然而, requestFocusInWindow() 在其顶级祖先是焦点窗口时才获取调用它的组件的焦点。

在您的示例中, JDialog是顶级祖先,它在单击JButton时自动获得焦点。 所以requestFocusInWindow()grabFocus()没有什么区别。

我重新编写了程序,以便用务实的方法更好地理解差异。

 import javax.swing.*; import java.awt.*; import java.awt.event.*; class Focus extends JFrame { JButton jb; JTextField jt; public Focus() { createAndShowGUI(); } private void createAndShowGUI() { setTitle("grabFocus() vs requestFocusInWindow()"); setLayout(new FlowLayout()); setSize(400,400); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jb=new JButton("Open Dialog"); jb.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent ae) { showDialog(); } }); add(jb); jt=new JTextField(20); add(jt); } private void showDialog() { JDialog jd=new JDialog(); jd.setLayout(new GridLayout(2,2)); jd.setVisible(true); JLabel l1=new JLabel("Label 1"); JLabel l2=new JLabel("Label 2"); JTextField jt1=new JTextField(20); JTextField jt2=new JTextField(20); jd.add(l1); jd.add(jt1); jd.add(l2); jd.add(jt2); jt.requestFocusInWindow(); //jt.grabFocus(); jd.pack(); } public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable(){ public void run() { new Focus(); } }); } } 

这里,在jt上调用requestFocusInWindow()并且它不起作用(即jt没有获得焦点),因为当单击JButton并且JDialog JTextField获得焦点时, JDialog被激活。

接下来, grabFocus()可以工作。 单击JButton ,将显示JDialog ,但不会处于活动状态。 因为在调用grabFocus()JFrame立即成为活动的顶级祖先,并且jt 被迫获得焦点。