How do I remove an old JPanel and add a new one?

25,418

Solution 1

setVisible(false), even in the correct place, will not actually remove the panel from the container. If you want to replace the panel do this:

frame.getContentPane().remove(partnerSelectionPanel);
frame.add(new JPanel());
frame.getContentPane().invalidate();
frame.getContentPane().validate();

Note that frame.getContentPane().add(Component) is the same as frame.add(Component) - the components are actually contained within the content pane.

Solution 2

Don't forget or overlook the approach of using the Layout, namely the CardLayout as the Frames Layout, to allow this type of behavior (This is a good strategy for a "Wizard" for example). One advantage to this is it doesn't cause any weird flash or draw effects as that is what this Layout is meant to do--Allow a panels to be swapped out, assuming they have exclusive "real estate" or can share the same areas (i.e. "Wizard" like behavior.)

Solution 3

You can use

  Frame.setContentPane(jPanel);
Share:
25,418
Roman
Author by

Roman

Updated on September 27, 2020

Comments

  • Roman
    Roman over 3 years

    I would like to remove an old JPanel from the Window (JFrame) and add a new one. How should I do it?

    I tried the following:

    public static void showGUI() {
        JFrame frame = new JFrame("Colored Trails");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        frame.add(partnerSelectionPanel);
        frame.setSize(600,400);
        frame.setVisible(true);
    }
    
    private static void updateGUI(final int i, final JLabel label, final JPanel partnerSelectionPanel) {
        SwingUtilities.invokeLater( 
            new Runnable() {
                public void run() {
                    label.setText(i + " seconds left.");
                }
                partnerSelectionPanel.setVisible(false); \\ <------------
            }
        );
    }
    

    My code updates the "old" JPanel and then it makes the whole JPanel invisible, but it does not work. The compiler complains about the line indicated with <------------. It writes: <identifier> expected, illegal start of type.

    ADDED:

    I have managed to do what I needed and I did it in the following way:

    public static void showGUI() {
        frame = new JFrame("Colored Trails");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        frame.add(partnerSelectionPanel);
        //frame.add(selectionFinishedPanel);
        frame.setSize(600,400);
        frame.setVisible(true);
    }
    
    public static Thread counter = new Thread() {
        public void run() {
            for (int i=4; i>0; i=i-1) {
                updateGUI(i,label);
                try {Thread.sleep(1000);} catch(InterruptedException e) {};
            }
            partnerSelectionPanel.setVisible(false);
            frame.add(selectionFinishedPanel);
        }
    };
    

    It works but it does not look to me like a safe solution for the following reasons:

    1. I change and add elements to the JFrame from another thread.
    2. I add a new JPanel to a JFrame, after I have already "packed" the JFrame and made it visible.

    Should I be doing that?

  • Roman
    Roman about 14 years
    Russ Hayward, Is it OK to remove and add JPanels after the JFrame is already packed and set visible? Should I add and remove JPanels in the events dispatch thread?
  • Roman
    Roman about 14 years
    After I have replaced the partnerSelectionPanel.setVisible(false); by the frame.getContentPane().remove(partnerSelectionPanel);, my program stopped to remove the old frame (even if I use invalidate in the end).
  • Russ Hayward
    Russ Hayward about 14 years
    Yes adding, removing and creating components should happen on the EDT. I missed off a validate call - I never remember those! Should work if you add the invalidate and the validate.
  • Wintermut3
    Wintermut3 about 14 years
    Just keep in mind as to the Visible accessors that those are useful to cause the user from seeing a "shuffle" or a lot of flashing as any particular component is updated not only that but updating certain components while they are setVisible(false) can dramatically improve performance--really the usefulness and even success of this strategy seem to vary per component or even between different versions of the JDK, Also don't forget you can re-"pack" the frame after you have swapped the panels.