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