Francois51
Francois51

Reputation: 401

How to update components listening a button in java

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

Answers (2)

Frakcool
Frakcool

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

Erwin
Erwin

Reputation: 470

this works,

public void update() {
    buttons.remove(button);
    buttons.remove(button2);
    buttons.add(button3);
    this.revalidate();
    this.repaint();
}

Upvotes: 0

Related Questions