2012-04-07 75 views
1

這是一個奇怪的問題。我有一個解決方案,但我不知道爲什麼問題首先發生。請注意以下代碼:添加JFileChooser沒有動作會導致面板不能渲染

// VERSION 1 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 
     mainFrame.setVisible(true); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 
    } 
} 

它按預期工作。該按鈕什麼都不做,但它呈現正確。現在,我添加一個JFileChooser(我打算稍後做一些事情,但現在我只是在實例化它)。

// VERSION 2 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 
     mainFrame.setVisible(true); 

     JFileChooser inputFileChooser = new JFileChooser(); // NEW LINE 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 
    } 
} 

突然我的按鈕不再呈現。爲什麼?我知道有兩種方法可以讓它再次起作用,但對我來說這兩種方式都沒有100%的意義。解決它的方法之一:

// VERSION 3 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 
     mainFrame.setVisible(true); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 

     JFileChooser inputFileChooser = new JFileChooser(); // MOVE LINE TO END 
    } 
} 

所以把該行的端允許按鈕重新渲染,但仍是沒有意義的我什麼實例化的JFileChooser與未連接的按鈕做。另一種辦法可以解決這個問題:

// VERSION 4 

public class test { 

    public static void main(String[] args) { 
     JFrame mainFrame = new JFrame("Test"); 
     JPanel inputPanel = new JPanel(); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.getContentPane().add(BorderLayout.CENTER, inputPanel); 
     mainFrame.setBounds(100, 50, 200, 100); 

     JFileChooser inputFileChooser = new JFileChooser(); 

     JButton inputFileButton = new JButton("BROWSE"); 
     inputPanel.add(inputFileButton); 

     mainFrame.setVisible(true); // MOVE *THIS* LINE TO THE END    
    } 
} 

它種是有道理的,爲什麼上面的版本修復了問題......顯然講講JFileChoose實例正在我的按鈕不可見的,但這種調用setVisible()方法之後帶來它回到了光明中。但是,這仍然沒有告訴我爲什麼它首先隱藏起來。

有人能幫我找出我失蹤的東西嗎?謝謝!

+3

1)總是在EDT上創建並更新GUI。 2)不要調用'setBounds()'或'setSize()',而是調用'pack()'。 3)順序很重要。 a)添加組件b)'pack()'c)'setLocationRelativeTo()'(如果需要)d)'setVisible(true)' – 2012-04-07 07:39:43

回答

5

您正在使mainFrame可見,然後添加按鈕。看看this SO question你需要採取哪些步驟來確保你的按鈕是可見的。

它在你的第一個例子中起作用的原因可能是純粹的運氣。在美國東部時間顯示您的組件之前,您將添加該按鈕。

注意:請在EDT上執行Swing操作

+0

謝謝。我是EDT概念的新手,但是從我做的一些快速研究來看,這聽起來像我只需要明確提及EDT,如果我處於不同的線程。我上面的任何例子都不是「在EDT上執行Swing操作?」我現在明白了我應該遵循的順序,謝謝你和安德魯的回答,只是要確保我沒有忽視關於美國東部時間的其他事情。 – The111 2012-04-07 07:55:45

+1

您的主要方法運行在不同的線程上,因此EDT上沒有執行Swing操作。您應該在主要方法中使用'SwingUtilities.invokeLater'調用來構建您的UI。必讀的教程是[This one](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – Robin 2012-04-07 07:58:08