2015-09-07 38 views
2

我正在更改我的JFrame的内容窗格,并且只想将JTextField集中在新面板中。所以我这样做:当我使用setVisible(false)setVisible(true),而不是重新确认和重新粉刷我的相框更改JFrame内容窗格后的焦点组件

JPanel pNew = new JPanel(); 
frame.setContentPane(pNew); 
frame.revalidate(); 
frame.repaint(); 

public JPanel() { 
    ... 
    tf.requestFocusInWindow(); 
} 

,我让我的希望的效果,但是这不是我想这样做的方式。

setVisible()还会发生什么,但重新验证和重新绘制?

+3

1.我们都会好得多,如果你将创建说明您的问题对我们来说,一个[MCVE]一个非常小的演示程序。 2.为什么不通过CardLayout交换JPanel?这种情况特别适用于这种情况。 –

回答

1

我简单地通过将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; 
    } 

} 
+0

非常感谢!这和camickr的提示使它工作,对我来说是可以理解的:) – Froxx

2

A CardLayout通常用于交换面板。

但是,即使默认实现CardLayout在交换时也不会在面板上设置焦点。但是,您可以查看Card Layout Focus,这将允许您在面板切换时请求对焦。

requestFocusInWindow()方法仅适用于显示在可见框架中的组件。所以你不能在类的构造函数中调用该方法。

您可以使用Dialog Focus中的RequestFocsListener。它将等到面板添加到可见的GUI之后才生成事件。

+0

我认为CardLayout不是这里的解决方案。在我的新面板中,我想显示数据,具体取决于所选按钮和来自旧面板的其他数据。所以我只想在点击按钮后创建我的面板。在CardLayout中,我将在框架创建中创建所有面板。但感谢与可见帧的提示。这只是另一个问题:我怎样才能设置文本框的焦点后面板的结构,而不使文本字段的对象属性? – Froxx

+0

@Froxx,这是我的第二个建议。 – camickr

+0

哦,我明白了。我非常重视你的第一个。非常感谢! – Froxx