Search code examples
javaswingjpanel

Custom JPanel with JButtons displays them one on top of another in JFrame


Basically, when i run the following code, instead of a panel containing three buttons next to each other i get a tiny panel that (i'm assuming) has all the buttons on top of each other. What's weird is that when i put all the code inside Main() it seems to work just fine, i can even add more buttons to myTopLeftPanel from main and they are displayed correctly, but when i split it into classes it starts acting weird. What's the cause of this? How can i fix it?

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

public class Main extends JFrame {
    int height = 500;
    int width = (int)Math.round(height*1.61803);
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Main());
    }
    public Main() {
        this.setLayout(new BorderLayout());
        MyTopLeftPanel myTopLeftPanel = new MyTopLeftPanel();
        JPanel top = addPanel(new BorderLayout());
        top.add(myTopLeftPanel, BorderLayout.WEST);
        this.add(top, BorderLayout.NORTH);
        setup();
    }
    void setup(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(width, height);
        this.setVisible(true);
    }
    JPanel addPanel(LayoutManager layout){
        JPanel temp = new JPanel();
        temp.setLayout(layout);
        return temp;
    }
}
class MyButtonPanel extends JPanel{
    JButton[] tab;
    public MyButtonPanel(int numOfButtons, LayoutManager layout) {
        this.tab = new JButton[numOfButtons];
        Arrays.fill(tab, new JButton());
        this.setLayout(layout);
    }
}
class MyTopLeftPanel extends MyButtonPanel{
    public MyTopLeftPanel(){
        super(3, new FlowLayout());
        tab[0].setBackground(Color.RED);
        tab[0].setText("R");
        tab[1].setBackground(Color.GREEN);
        tab[1].setText("G");
        tab[2].setBackground(Color.BLUE);
        tab[2].setText("B");
        this.setLayout(new FlowLayout());
        this.add(tab[0], FlowLayout.LEFT);
        this.add(tab[1], FlowLayout.LEFT);
        this.add(tab[2], FlowLayout.LEFT);
    }
}

Solution

  • The problem is Arrays.fill(tab, new JButton());.

    It creates only one instance of JButton which is assigned to each position of the array.

    This should fix it:

    class MyButtonPanel extends JPanel{
        JButton[] tab;
        public MyButtonPanel(int numOfButtons, LayoutManager layout) {
            this.tab = new JButton[numOfButtons];
            for (int i = 0; i < numOfButtons; i++) {
                tab[i] = new JButton();
            }
            this.setLayout(layout);
        }
    }