Search code examples
javaswingjpanelawtjlabel

Add a new component to a JPanel created in another class


I have a JFrame with a grid of JPanels (using Borderlayout). Each JPanel holds a JButton (that expands to full size because is inside a Borderlayout). So I have something like a minesweeper.

Those buttons have a listener, with the constructor Listener(panel), so i can use the panel from the listener.

If I do panel.removeAll(); in the listener then the button disappears, but the JPanel remains, so i get a free space.

I do panel.setBackground(Color.pink); and it works, but if i want to add a component, such another button or a JLabel, it doesn't work. It works in the same class but not apart, or in a method of the class.

Thank you. Hope you can understand!

Here it is my listener class:

public class ListenerCasillas implements ActionListener {

    JPanel panel;

    ListenerCasillas(JPanel panel){

    this.panel = panel;

    }

    @Override
    public void actionPerformed(ActionEvent e) {

        panel.removeAll();//works
        panel.setBackground(Color.green);//works
        panel.add(new JLabel("1"));//doesn't work
        panel.repaint();//works

    }

}

And here it is the class that creates the grid:

public class Game extends JFrame {
    Game(){
        super("MineSweeper 0.0");
        setLocation(300, 300);
        setResizable(false);

        setLayout(new GridLayout(mainclass.rows, mainclass.cols));

        Dimension d = new Dimension(30, 30);

        for(int i = 0; i < mainclass.rows; i++){
            for(int j = 0; j < mainclass.cols; j++){
                JPanel panel = new JPanel();
                panel.setLayout(new BorderLayout());
                panel.setPreferredSize(d);

                add(panel);

                JButton boton = new JButton();

                boton.addActionListener(new ListenerCasillas(panel));
                panel.add(boton);
            }
        }

        setVisible(true);
        pack();
    }
}

Full java project (if you want to test): https://drive.google.com/file/d/0B0WNwgY4eOjvNmNHM0E5U0FxVGc/view?usp=sharing


Solution

  • The solution is to call revalidate() in your ListenerCasillass actionPerformed() method

    public class ListenerCasillas implements ActionListener {
        JPanel panel;
    
        ListenerCasillas(JPanel panel){
            this.panel = panel;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            panel.removeAll();
            panel.setBackground(Color.green);
            panel.add(new JLabel("1"));
            panel.revalidate();
            panel.repaint();
        }
    }
    

    For more information on repaint() and revalidate() check out this brilliant answer on SO.