How do I hide the current JPanel and show a new one with a button in Java?

14,472

Solution 1

After removing components from a container, it goes into the invalidate state. To bring it back to the valid state you have to revalidate and repaint that. In your case you are directly adding/removing components from JFrame so depending on the Java version you can do this :

frame.revalidate(); // For Java 1.7 or above
frame.getContentPane().validate(); // For Java 1.6 or below
frame.repaint();

Here is one working example for your help :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Assignment
{
    private JFrame frame;
    private JPanel firstPanel;
    private JPanel secondPanel;

    private JButton forwardButton;
    private JButton backButton;

    private void displayGUI()
    {
        frame = new JFrame("Assignment");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        firstPanel = new JPanel();
        firstPanel.setOpaque(true);
        firstPanel.setBackground(Color.BLUE);

        secondPanel = new JPanel();
        secondPanel.setOpaque(true);
        secondPanel.setBackground(Color.RED);

        forwardButton = new JButton("Forward");
        forwardButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                frame.remove(firstPanel);
                frame.add(secondPanel);
                frame.revalidate(); // For Java 1.7 or above.
                // frame.getContentPane().validate(); // For Java 1.6 or below.
                frame.repaint();
            }
        });

        backButton = new JButton("Back");
        backButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                frame.remove(secondPanel);
                frame.add(firstPanel);
                frame.revalidate(); // For Java 1.7 or above.
                // frame.getContentPane().validate(); // For Java 1.6 or below.
                frame.repaint();
            }
        });

        firstPanel.add(forwardButton);
        secondPanel.add(backButton);

        frame.add(firstPanel);
        frame.setSize(300, 300);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new Assignment().displayGUI();
            }
        });
    }
}

Solution 2

  1. correct way could be (only) by using CardLayout

  2. otherwise have to remove JPanel from container and to call (as last code line and call only one times after all changes for container are done)

.

myJPanelsContainer#revalidate(); // in Java6 for JFrame validate()
myJPanelsContainer#repaint();
Share:
14,472
allocate
Author by

allocate

VP of Engineering @ Penn Interactive

Updated on June 27, 2022

Comments

  • allocate
    allocate almost 2 years

    I unfortunately have to use multiple windows in this program and I don't think CardLayout is going to work because I can't have any buttons constant between the different layouts. So I'm trying to code a button to hide the present JPanel (thePanel) and show a new one (thePlacebo).

    I'm trying to hide thePanel in an ActionListener like this:

    frame.getContentPane().remove(thePanel);
    

    I thought this would work, but it just freezes my program as soon as I hit the button.

    Here's a chunk of the code for context:

    public class Reflexology1 extends JFrame{
    JButton button1, button2;
    JButton movingButton;
    JTextArea textArea1;
    int buttonAClicked, buttonDClicked;
    private long _openTime = 0;
    private long _closeTime = 0;
    JPanel thePanel = new JPanel();
    JPanel thePlacebo = new JPanel();
    final JFrame frame = new JFrame("Reflexology");
    
    public static void main(String[] args){
        new Reflexology1();
    }
    
    public Reflexology1(){
    
    
        frame.setSize(600, 475);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Reflexology 1.0");
        frame.setResizable(false);
    
    
        button1 = new JButton("Accept");
        button2 = new JButton("Decline");
        movingButton = new JButton("Click Me");
    
        ListenForAcceptButton lForAButton = new ListenForAcceptButton();
        ListenForDeclineButton lForDButton = new ListenForDeclineButton();
        button1.addActionListener(lForAButton);
        button2.addActionListener(lForDButton);
        //movingButton.addActionListener(lForMButton);
    
        JTextArea textArea1 = new JTextArea(24, 50);
    
        textArea1.setText("Tracking Events\n");
        textArea1.setLineWrap(true);
        textArea1.setWrapStyleWord(true);
        textArea1.setSize(15, 50);
    
        FileReader reader = null;
        try {
            reader = new FileReader("EULA.txt");
            textArea1.read(reader, "EULA.txt");
        } catch (IOException exception) {
            System.err.println("Problem loading file");
            exception.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException exception) {
                    System.err.println("Error closing reader");
                    exception.printStackTrace();
                }
            }
        }
    
        JScrollPane scrollBar1 = new JScrollPane(textArea1, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        AdjustmentListener listener = new MyAdjustmentListener();
    
        thePanel.add(scrollBar1);
        thePanel.add(button1);
        thePanel.add(button2);
        thePlacebo.add(movingButton);
    
        frame.add(thePanel);
    
        ListenForWindow lForWindow = new ListenForWindow();
        frame.addWindowListener(lForWindow);
        frame.setVisible(true);
    
    }
    // Implement listeners
    
    private class ListenForAcceptButton implements ActionListener{
        public void actionPerformed(ActionEvent e){
            if (e.getSource() == button1){
                Calendar ClCDateTime = Calendar.getInstance();
                System.out.println(ClCDateTime.getTimeInMillis() - _openTime);
                _closeTime = ClCDateTime.getTimeInMillis() - _openTime;
                frame.getContentPane().remove(thePanel);
            }
        }
    }
    

    Does anybody know what I might be doing wrong?