2015-09-07 39 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