我正在更改JFrame
的内容窗格,并且只想在新面板中聚焦JTextField
。我这样写:
JPanel pNew = new JPanel();
frame.setContentPane(pNew);
frame.revalidate();
frame.repaint();
public JPanel() {
...
tf.requestFocusInWindow();
}
当我使用setVisible(false)
和setVisible(true)
而不是重新验证和重新绘制框架时,我得到了我想要的效果,但这不是我想要的方式。
在setVisible()
中除了重新验证和重新绘制还会发生什么?
CardLayout通常用于交换面板。
然而,即使CardLayout
的默认实现也不会在交换面板时设置焦点。然而,你可以检查Card Layout Focus,这将允许你在面板切换时请求对其进行聚焦。
requestFocusInWindow()
方法只对显示在可见框架中的组件有效。因此,您不能在类的构造函数中调用该方法。
您可以使用对话框焦点中的RequestFocsListener
。在生成事件之前,它将等待面板添加到一个可见的GUI中。
我通过将requestFocusInWindow()
调用放在按钮的操作侦听器中使其工作。正如camickr提到的,调用需要在构造函数之后进行。下面是一个示例程序,展示了我是如何使用它的。希望能有所帮助!
public class PanelRevalidate {
public JFrame frame;
public MyPanel panel1, panel2;
public PanelRevalidate() {
frame = new JFrame();
panel1 = new MyPanel(1);
panel2 = new MyPanel(2);
frame.setContentPane(panel1);
panel1.getSwap().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
frame.setContentPane(panel2);
frame.revalidate();
panel2.getTextField().requestFocusInWindow();
}
});
panel2.getSwap().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
frame.setContentPane(panel1);
frame.revalidate();
panel1.getTextField().requestFocusInWindow();
}
});
frame.setVisible(true);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
new PanelRevalidate();
}
});
}
}
和MyPanel类:
public class MyPanel extends JPanel {
public JTextField tf;
public JButton swap;
public JLabel panel_label;
public MyPanel(int n) {
tf = new JTextField(25);
swap = new JButton("Swap");
panel_label = new JLabel("panel " + n);
add(tf);
add(swap);
add(panel_label);
}
public JButton getSwap() {
return swap;
}
public JTextField getTextField() {
return tf;
}
}