Reputation: 1343
I unfortunately have to use multiple windows in this program and I don't think CardLayout is going to work because I can't have any buttons constant between the different layouts. So I'm trying to code a button to hide the present JPanel (thePanel) and show a new one (thePlacebo).
I'm trying to hide thePanel in an ActionListener like this:
frame.getContentPane().remove(thePanel);
I thought this would work, but it just freezes my program as soon as I hit the button.
Here's a chunk of the code for context:
public class Reflexology1 extends JFrame{
JButton button1, button2;
JButton movingButton;
JTextArea textArea1;
int buttonAClicked, buttonDClicked;
private long _openTime = 0;
private long _closeTime = 0;
JPanel thePanel = new JPanel();
JPanel thePlacebo = new JPanel();
final JFrame frame = new JFrame("Reflexology");
public static void main(String[] args){
new Reflexology1();
}
public Reflexology1(){
frame.setSize(600, 475);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Reflexology 1.0");
frame.setResizable(false);
button1 = new JButton("Accept");
button2 = new JButton("Decline");
movingButton = new JButton("Click Me");
ListenForAcceptButton lForAButton = new ListenForAcceptButton();
ListenForDeclineButton lForDButton = new ListenForDeclineButton();
button1.addActionListener(lForAButton);
button2.addActionListener(lForDButton);
//movingButton.addActionListener(lForMButton);
JTextArea textArea1 = new JTextArea(24, 50);
textArea1.setText("Tracking Events\n");
textArea1.setLineWrap(true);
textArea1.setWrapStyleWord(true);
textArea1.setSize(15, 50);
FileReader reader = null;
try {
reader = new FileReader("EULA.txt");
textArea1.read(reader, "EULA.txt");
} catch (IOException exception) {
System.err.println("Problem loading file");
exception.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException exception) {
System.err.println("Error closing reader");
exception.printStackTrace();
}
}
}
JScrollPane scrollBar1 = new JScrollPane(textArea1, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
AdjustmentListener listener = new MyAdjustmentListener();
thePanel.add(scrollBar1);
thePanel.add(button1);
thePanel.add(button2);
thePlacebo.add(movingButton);
frame.add(thePanel);
ListenForWindow lForWindow = new ListenForWindow();
frame.addWindowListener(lForWindow);
frame.setVisible(true);
}
// Implement listeners
private class ListenForAcceptButton implements ActionListener{
public void actionPerformed(ActionEvent e){
if (e.getSource() == button1){
Calendar ClCDateTime = Calendar.getInstance();
System.out.println(ClCDateTime.getTimeInMillis() - _openTime);
_closeTime = ClCDateTime.getTimeInMillis() - _openTime;
frame.getContentPane().remove(thePanel);
}
}
}
Does anybody know what I might be doing wrong?
Upvotes: 3
Views: 15126
Reputation: 24616
After removing components from a container, it goes into the invalidate
state. To bring it back to the valid
state you have to revalidate
and repaint
that. In your case you are directly adding/removing components from JFrame
so depending on the Java version you can do this :
frame.revalidate(); // For Java 1.7 or above
frame.getContentPane().validate(); // For Java 1.6 or below
frame.repaint();
Here is one working example for your help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Assignment
{
private JFrame frame;
private JPanel firstPanel;
private JPanel secondPanel;
private JButton forwardButton;
private JButton backButton;
private void displayGUI()
{
frame = new JFrame("Assignment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.setOpaque(true);
firstPanel.setBackground(Color.BLUE);
secondPanel = new JPanel();
secondPanel.setOpaque(true);
secondPanel.setBackground(Color.RED);
forwardButton = new JButton("Forward");
forwardButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
frame.remove(firstPanel);
frame.add(secondPanel);
frame.revalidate(); // For Java 1.7 or above.
// frame.getContentPane().validate(); // For Java 1.6 or below.
frame.repaint();
}
});
backButton = new JButton("Back");
backButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
frame.remove(secondPanel);
frame.add(firstPanel);
frame.revalidate(); // For Java 1.7 or above.
// frame.getContentPane().validate(); // For Java 1.6 or below.
frame.repaint();
}
});
firstPanel.add(forwardButton);
secondPanel.add(backButton);
frame.add(firstPanel);
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new Assignment().displayGUI();
}
});
}
}
Upvotes: 6
Reputation: 109815
correct way could be (only) by using CardLayout
otherwise have to remove JPanel from container and to call (as last code line and call only one times after all changes for container are done)
.
myJPanelsContainer#revalidate(); // in Java6 for JFrame validate()
myJPanelsContainer#repaint();
Upvotes: 4