更改JFrame的内容窗格后的焦点组件



我正在更改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;
    }
}

最新更新