1

I would like to add different JPanel to my JFrame when the user clicks on a JButton.

The Panel must change according to the button clicked by the user. Here is a portion of my code :

addCours.addActionListener(new ActionListener() {

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

    addLocal.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            panLocal.setBounds(215, 2, 480, 400);
            panLocal.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le local"));
            ConstituerData.this.getContentPane().add(panLocal);
            ConstituerData.this.revalidate();
            ConstituerData.this.repaint();
        }
    });

How can I fix this ?

sk001
  • 561
  • 6
  • 27
  • this should help you [CLICK HERE](http://stackoverflow.com/questions/14011397/how-to-add-jpanel-by-clicking-jbutton) – PrR3 Mar 06 '14 at 10:35

3 Answers3

2

"How can I fix this ?"

  1. That region of setBounds(215, 2, 480, 400) where you seem to be trying to add new components, consider using a CardLayout for that region. Just add a JPanel with CardLayout as the main container for that region. Then you can either:

    • Create the child panels on the fly, add it the containing panel, then show it, or
    • Create all the inside panels ahead of time, add them to the containing panel, and just use the show method of the CardLayout to show which panel you want to show.
  2. For the future, I would suggest to use layout managers. Null layouts may become difficult to manage and cause many problems, not just for the developer, but for the application. Swing was designed to be used with layout managers, so use them :)

See more at How to use Cardlayout and see an example here

Also see Laying out Components Within a Container for more on how to use the different layout managers.

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • +1 for the card layout suggestion. Suggesting that he immediately stop using the null layout for his current application probably isn't helpful for them though. Better to just suggest he uses proper layouts in future. – Rudi Kershaw Mar 06 '14 at 10:52
  • 1
    @RudiKershaw fixed my wording. – Paul Samsotha Mar 06 '14 at 10:55
1

First I would like to go on record in saying that peeskillet's solution is more elegant than the one I am about to detail and that you really should be using a proper layoutManager. CardLayout really is perfect for this particular situation.

However, if you want a quick hack to fix your current predicament you can just add the following to the beginning of each of your ActionListeners actionPerformed() overrides.

For addCours's ActionListener add the following to first line;

ConstituerData.this.remove(panLocal);

For AddLocal's ActionListener add the following to first line;

ConstituerData.this.remove(panCours);

Basically, you are not removing the last JPanel when you are putting the new one in, which is why it appears not to change.

When I replicated your problem and solved it I used a for loop to loop through the frame's contents and remove all JPanels first in each action listener, like so;

@Override
public void actionPerformed(ActionEvent e) {
        for(Component c : frame.getContentPane().getComponents()){
            if(c instanceof JPanel){
                frame.remove(c);
            }
        }
        JPanel panel = new JPanel();
        panel.setBackground(Color.RED);
        panel.setBounds(215, 2, 480, 480);
        frame.add(panel);
        frame.revalidate(); 
        frame.repaint(); 

    }
Rudi Kershaw
  • 12,332
  • 7
  • 52
  • 77
1

Thanks everybody. I've proceeded by creating a method like this :

public void supprElements(JPanel jP) {
    for(Component c : this.getContentPane().getComponents()) {
        if(c instanceof JPanel) {
            if(!c.equals(jP)) {
                this.getContentPane().remove(c);
            }
        }
    }
}

And I call this method in each ActionListener interface's implementation :

addCours.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            supprElements(panCours);
            ConstituerData.this.getContentPane().add(panAdd);
            panCours.setBounds(215, 2, 480, 400);
            panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours"));
            ConstituerData.this.getContentPane().add(panCours);
            ConstituerData.this.revalidate();
            ConstituerData.this.repaint();
            current = 1;
        }
    });

And now, it works as expected. Hoping to manage correctly my layout soon. Thanks again.

sk001
  • 561
  • 6
  • 27