2012-04-07 1 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 (который я планирую сделать с более поздним, но пока все, что я делаю, это его экземпляр).

Внезапно моя кнопка больше не делает. Зачем? Я знаю два способа заставить его работать снова, но и не составляет 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) Всегда создавать и обновлять GUI на EDT. 2) Не вызывайте 'setBounds()' или 'setSize()', вместо этого вызывайте 'pack()'. 3) Порядок важен. a) Добавить компоненты b) 'pack()' c) 'setLocationRelativeTo()' (если необходимо) d) 'setVisible (true)' –

ответ

5

Вы делаете свой mainFrame видимым и добавляете кнопку после этого. Посмотрите на this SO question о том, какие шаги нужно предпринять, чтобы убедиться, что ваша кнопка видна.

Причина, по которой это работает в вашем первом примере, вероятно, является чистой удачей. Ваш звонок для добавления кнопки будет выполнен до того, как EDT покажет ваш компонент.

Примечание: Пожалуйста, выполните операции Качели на EDT

+0

Спасибо. Я новичок в концепции EDT, но из некоторых быстрых исследований, которые я сделал, кажется, что мне нужно просто указывать EDT, если я в другом потоке. Был ли какой-либо из моих примеров выше НЕ «выполнять операции Swing на EDT?» Теперь я лучше понимаю последовательность, которой я должен следовать, благодаря вашим и ответам Эндрю, просто убедившись, что я не буду забывать что-то еще об EDT. – The111

+1

Ваш основной метод работает в другом потоке, поэтому ни одна из операций Swing не выполняется на EDT. Вы должны использовать вызов 'SwingUtilities.invokeLater' в вашем основном методе для создания вашего пользовательского интерфейса. Учебное пособие по обязательному чтению - [этот] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – Robin

Смежные вопросы