Jump to content

JFrame.removeAll gives unexpected behaviour

- - - - -

  • Please log in to reply
2 replies to this topic

#1
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
I want to update a JFrame by the click of a button. Upon clicking everything in the JFrame should be removed and new content will be added. However, upon clicking the button it stays in the pressed state, and nothing more happens. Nothing gets added and if I try resizing the frame it doesn't repaint.

I think it's because the button gets removed while there are still methods on it that are not finished, such as fireActionPerformed. So it makes sense. But I have looked it up and using removeAll is mentioned a lot of places and seems to cause no problems like mine. So even though removeAll removed everything, including the root pane, it should still work if I am to believe several other forum posts regarding updating a JFrame.

So hopefully someone can shed some light on this. Yes, I COULD just add the button to a JPanel and then just remove that, but given that this should work, I'm interested in solving this problem or figuring out why it doesn't work when others have had no problems with using that method, and not in working around it.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class TestFrame extends JFrame {
    public TestFrame() {
        JButton ok = new JButton("OK");
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                replace();
            }
        });
        add(ok);
        pack();
        setVisible(true);
    }
    
    public void replace() {
        this.removeAll();
        add(new JTextField("Hey"));
    }
    
    public static void main(String[] args) {
        new TestFrame();
    }
}


#2
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP

    public TestFrame() {

        JButton ok = new JButton("OK");

        ok.addActionListener(new ActionListener() {


			@Override

			public void actionPerformed(ActionEvent arg0) {

				// TODO Auto-generated method stub

				replace();

			}

        });

        

        add(ok);

        pack();

        setVisible(true);

    }

    

    public void replace() {

    	[COLOR="#008000"]getContentPane().removeAll();[/COLOR]

        

    	add(new JTextField("Hey"));

        [COLOR="#008000"]getContentPane().revalidate();[/COLOR]

    }

Quote from java tutorials @ oracle

Quote

As a convenience, the add method and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary. This means you can write

frame.add(child);

and the child will be added to the contentPane.

Note that only these three methods do this.
When you're adding components to the jframe they are "secretly" being added to the JFrame's content pane.
removeAll is NOT one of the methods that secrets effects the content pane.

Therefore we must call JFrame's getContentPane().removeAll() method.

Quote from the removeAll() method section in the api (Container (Java Platform SE 7 )

Quote

...If the container has already been displayed, the hierarchy must be validated thereafter in order to reflect the changes.

This is why you need to revalidate() the content pane.

#3
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
Thanks, that worked perfectly!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users