Reputation: 401
I am a bit sorry to ask this question, since it seems to be a bit obvious, but I can't find my solution alone.
I am coding a little app in Java, and I encounter some issues "redrawing" my swing components. Basically, I want my JFrame
to update when an event occurs. I managed to reproduced the issue in the code below. This code is supposed to display two buttons (which it does), and replace them with a third button when you click on the first button (which it doesn't).
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame implements ActionListener {
private JButton button = new JButton("Button 1");
private JButton button2 = new JButton("Button 2");
private JButton button3 = new JButton("Button 3");
private JPanel buttons = new JPanel();
public void init() {
this.setVisible(true);
this.setSize(500,500);
buttons.add(button);
buttons.add(button2);
this.add(buttons);
this.button.addActionListener(this);
}
public void update() {
this.removeAll();
buttons.add(button3);
this.revalidate();
}
public static void main(String[] args) {
Example ex = new Example();
ex.init();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
update();
}
}
}
I am pretty sure that I am doing something wrong in the update()
method. I actually have a lot of trouble to understand how works removeAll()
, revalidate()
, repaint()
etc, and I guess that is the problem. I tried to call the same methods on the buttons
panel, it almost worked but I still have a graphic bug, and I would like to do it for all the container. I also tried to call these methods on this.getContentPane()
, but it doesn't work.
Can anyone try to help me with it?
Upvotes: 1
Views: 1266
Reputation: 11153
You're removing all components from this
(which in this case is the JFrame
(as you're extending it, which isn't needed, and instead you should create an instance from it rather than inherit from it, as you're not changing the behavior of the JFrame
so it's better to just create an instance of it). See: Extends JFrame vs. creating it inside the program
In this case you're adding your components in this way:
JFrame > buttons (JPanel) > JButtons
And you're trying to remove
JFrame > everything
That includes the contentPane, instead you should call.
buttons.removeAll()
Inside the update()
method.
And also call this.repaint()
so your update()
method should become:
public void update() {
buttons.removeAll();
buttons.add(button3);
this.revalidate();
this.repaint();
}
Or the best approach is to use CardLayout
as recommended by @AndrewThompson in the comment below. This way you don't have to handle removing / repainting for each component, as CardLayout will do it for you. For example
Upvotes: 3
Reputation: 470
this works,
public void update() {
buttons.remove(button);
buttons.remove(button2);
buttons.add(button3);
this.revalidate();
this.repaint();
}
Upvotes: 0