2014-03-05 3 views
1

Я пытаюсь добавить JPanel в свой JFrame в методе actionListener, но он появляется только после второго нажатия кнопки. Это часть моего кода, где panCours является JPanel и ConstituerData целевой JFrame:Добавить JPanel в contentPane в actionListener

addCours.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      panCours.setBounds(215, 2, 480, 400); 
      panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours")); 
      ConstituerData.this.getContentPane().add(panCours); 
     } 
    }); 

Я не понимаю, почему он не появляется, как только я нажимаю на кнопку. Любое объяснение и помощь в том, как это исправить?

+0

Посмотрите, разрешает ли ваша проблема вызов 'pack' на' JFrame' в конце 'actionPerformed'. –

+0

Этот вызов решает проблему, но создает еще одну: он устанавливает каждый из размеров моего 'JFrame' в 0. – sk001

+0

@HugoSousa. Он использует нулевой макет по внешнему виду вещей, так что это не поможет. Попробуйте переписать на JFrame или JPanel. –

ответ

2

Чтобы получить сообщение JPanel, вам необходимо добавить звонок repaint(); (а также, возможно, revalidate();). Основной пример, демонстрирующий вашу проблему (и решение) ниже;

public class Test { 

    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLayout(null); 

     JButton button = new JButton("Test");      
     button.setBounds(20, 30, 100, 40); 
     button.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       JPanel panel = new JPanel(); 
       panel.setBackground(Color.red); 
       panel.setBounds(215, 2, 480, 480); 
       frame.add(panel); 
       frame.revalidate(); // Repaint here!! Removing these calls 
       frame.repaint(); // demonstrates the problem you are having. 

      } 
     }); 

     frame.add(button); 
     frame.setSize(695, 482); 
     frame.setVisible(true);    

    } 
} 

сказанного выше, (как это было предложено другими) это только справедливо, что я рекомендую против использования null макета в будущем. Макеты разворота немного неудобны для начала, но они помогут вам в долгосрочной перспективе.

+3

Пожалуйста, не предлагайте людям использовать «нулевые» макеты ... это просто замалчивание плохих советов и введение дополнительных проблем. – MadProgrammer

+0

Спасибо, @RudiKershaw. Теперь это правильно, если у меня есть только один JPanel. Но я хочу переключиться между многими «JPanel» в соответствии с выбором кнопки. Используя это решение, показанный «JPanel» не соответствует клику «JButton». Как я могу сделать ? – sk001

+0

@MadProgrammer - Совершенно верно, я уточню свой ответ, чтобы предложить макет. Но, как правило, когда-то кто-то превращается в проект, который они не хотят менять. Предложить использовать диспетчер компоновки поможет им в будущем, но это им не помогает прямо сейчас. –

2

ответ может быть найден в следующем фрагменте: вам необходимо revalidate() contentPane, а не перерисовать рамку. вы можете добавить любую панель, которую хотите разместить в виде содержимого. если вы объявляете contentPane как частное поле, вам не нужен ваш звонок getContentPane(). contentPane является глобальным, поэтому его можно перенаправить непосредственно из любого места в классе. будьте осторожны относительно NullPointerExeptions, которые могут быть выброшены, если вы обратитесь к нему перед инициализацией.

public class testframe extends JFrame { 

private JPanel contentPane; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       testframe frame = new testframe(); 
       frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

/** 
* Create the frame. 
*/ 
public testframe() { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    contentPane = new JPanel(); 
    setContentPane(contentPane); 

    JButton btnNewButton = new JButton("New button"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      JPanel a = new JPanel(); 
      contentPane.add(a); 
      contentPane.revalidate(); 
     } 
    }); 
    contentPane.add(btnNewButton); 
} 

} 
+0

http://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint - Чтобы быть абсолютно безопасным, возможно, повторная проверка и перекраска в порядке. Но certinaly не * просто * revalidating. –

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