views:

237

answers:

3

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); \\ <------------
        }
    );
}

So, my code update the "old" JPanel and them it makes the whole JPanel invisible. It was the idea. 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 do 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 as a safe solution. First, I "change" and "add to" the elements of the JFrame from another thread. Is it OK? Then I am not sure that it is OK to add a new JPanel to a JFrame, after I have already "packed" the JFrame and made it visible.

A: 
partnerSelectionPanel.setVisible(false); \\ <------------

This line is actualy out the method run.

You probably want something like this:

public void run() {
   label.setText(i + " seconds left.");
   try {
      Thread.sleep (i * 1000);
   } catch (InterruptedException e) {
      handleException (e);
   }
   partnerSelectionPanel.setVisible(false);
}
Roman
+1  A: 

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.

Russ Hayward
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
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).
Roman
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.
Russ Hayward
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.
Wintermute
+1  A: 

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.)

Wintermute