Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Adding and displaying a new JPanel -- not working as expected

843806Aug 19 2007 — edited Aug 19 2007
I'm starting my own new thread that is based on a problem discussed in another person's thread that can be found here in the New to Java forum titled "ActionListener:

http://forum.java.sun.com/thread.jspa?threadID=5207301

What I want to do: press a button which adds a new panel into another panel (the parentPane), and display the changes. The Actionlistener-derived class (AddPaneAction) for the button is in it's own file (it's not an internal class), and I pass a reference to the parentPane in the AddPaneAction's constructor as a parameter argument.

What works: After the button is clicked the AddPaneAction's actionPerformed method is called without problem.

What doesn't work: The new JPanel (called bluePanel) is not displayed as I thought it would be after I call
        parentPane.revalidate();  // this doesn't work
        parentPane.repaint();  
What also doesn't work: So I obtained a reference to the main app's JFrame (I called it myFrame) by recursively calling component.getParent( ), no problem there, and then tried (and failed to show the bluePanel with) this:
        myFrame.invalidate();  // I tried this with and without calling this method here
        myFrame.validate();  // I tried this with and without calling this method here
        myFrame.repaint();
What finally works but confuses me: I got it to work but only after calling this:
        myFrame.pack();  
        myFrame.repaint();
But I didn't think that I needed to call pack to display the panel. So, what am I doing wrong? Why are my expectations not correct? Here's my complete code/SSCCE below. Many thanks in advance.

Pete

The ParentPane class:
import java.awt.BorderLayout;
import java.awt.Color;
 
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class ParentPane extends JPanel
{
    private JButton addPaneBtn = new JButton("Add new Pane");
    
    public ParentPane()
    {
        super();
        setLayout(new BorderLayout());
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setBackground(Color.yellow);
        JPanel northPane = new JPanel();
        northPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        northPane.setBackground(Color.yellow);
        northPane.add(addPaneBtn);
        add(northPane, BorderLayout.NORTH);
        
        // add our actionlistener object and pass it a reference
        // to the main class which happens to be a JPanel (this)
        addPaneBtn.addActionListener(new AddPaneAction(this));
    }
    
    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("test add panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new ParentPane());
        frame.pack();
        frame.setVisible(true);
        
    }
 
}
the AddPaneAction class:
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
 
public class AddPaneAction implements ActionListener
{
    private JPanel parentPane;
    private JFrame myFrame;
 
    public AddPaneAction(JPanel parentPane) 
    {
        this.parentPane = parentPane;
    }
    
    /**
     * recursively get the JFrame that holds the parentPane panel.
     */
    private JFrame getJFrame(Component comp)
    {
        Component parentComponent = comp.getParent();
        if (parentComponent instanceof JFrame)
        {
            return (JFrame)parentComponent;
        }
        else
        {
            return getJFrame(parentComponent);
        }
    }
 
    public void actionPerformed(ActionEvent arg0)
    {
        JPanel bluePanel = new JPanel(new BorderLayout());
        bluePanel.setBackground(Color.blue);
        bluePanel.setPreferredSize(new Dimension(400, 300));
        JLabel myLabel = new JLabel("blue panel label");
        myLabel.setForeground(Color.LIGHT_GRAY);
        myLabel.setVerticalAlignment(SwingConstants.CENTER);
        myLabel.setHorizontalAlignment(SwingConstants.CENTER);
        bluePanel.add(myLabel, BorderLayout.CENTER);
        parentPane.add(bluePanel);
        myFrame = getJFrame(parentPane); 
        
        //parentPane.revalidate();  // this doesn't work
        //parentPane.repaint();  
        
        //myFrame.invalidate(); // and also this doesn't work
        //myFrame.validate();
        //myFrame.repaint();
        
        myFrame.pack();  // but this does!?
        myFrame.repaint();
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 16 2007
Added on Aug 19 2007
5 comments
1,987 views