Search code examples
javaswingjpanelcontentpane

JPanel does not appear when i try to add it to ContentPane


I'm having a problem trying to change JPanels by using buttons. I have a JFrame with 2 panels, 1 of them is for the buttons, which i want them to always be showed. The other one is the one that i will be switching everytime i press one ot the buttons of the other panel. The problem is that everytime i press them nothing really ever displays, i keep my buttons but the other panel that i call does not appear.

Code for one of the buttons is as follows

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        ReparacaoPanel r = new ReparacaoPanel(this, this.jPanel1);
        this.getContentPane().remove(this.jPanel1);
        this.getContentPane().add(r);
        //this.setContentPane(r);
        this.visiblePanel.setVisible(false);
        this.visiblePanel = r;
        this.pack();
        this.setVisible(true);

        r.setLocation(200, 200);
        this.getContentPane().revalidate();
        this.repaint();
    }

If i try to use "this.setContentPane(r);" (it sets the frame to only show the panel) the panel shows. But when i try to call it as i'm trying to do in the code above nothing is showed apart from the panel that has the buttons.

I have no idea what i'm doing wrong, it does not seem to be a problem with the JPanel that i'm trying to call as it shows if used alone.

Anyone can help me out?


Solution

  • Consider this working example for switching manually between panels. Which produces this output.

    enter image description here enter image description here.........

    Some tiny NumberPanel

    Every new instance shows another number in the center.

    import javax.swing.JPanel;
    public class NumberPanel extends JPanel {
        private static int counter = 0;
        public NumberPanel() {
            setLayout(new BorderLayout(0, 0));
            JLabel lblNewLabel = new JLabel("" + counter++);
            lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
            add(lblNewLabel);
        }
    }
    

    Setting up a frame

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        JPanel panel = new JPanel();
        frame.getContentPane().add(panel, BorderLayout.SOUTH);
    
        JButton btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                frame.getContentPane().remove(numberPanel);
                numberPanel = new NumberPanel();
                frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
                frame.pack();
            }
        });
        panel.add(btnNewButton);
    
        numberPanel = new NumberPanel();
        frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
        frame.pack();
    }
    

    Testprogram

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    public class TestPanelSwitch {
        private JFrame frame;
        private NumberPanel numberPanel;
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        TestPanelSwitch window = new TestPanelSwitch();
                        window.frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        public TestPanelSwitch() {
            initialize();
        }
        private void initialize() {
            // see above
        }
    }
    

    Back to the Question

    I think you only need to pack your frame, like in the anonymous ActionListener.

    frame.getContentPane().remove(numberPanel);
    numberPanel = new NumberPanel();
    frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
    frame.pack();
    

    EDIT

    As leonidas mentioned it is also possible to revalidate the frame. This requires only to replace the upper call to pack by theese.

    frame.invalidate();
    frame.validate();