Kyle Keberlein
Kyle Keberlein

Reputation: 1

Filling Frame with Buttons Using GridBagLayout

I am trying to build a matching game with icons attached to each button. Although, this isn't close to being finished, I have a problem with filling the panel with buttons.

With this code I get a grey colored frame. If i comment out the 3 methods i use under "//execution" the panel will be all black (which is how i am testing to see if the buttons are filling the space or not.)

For some reaso,n my buttons aren't being populated onto the panel.
I need some help!!! Where am I going wrong?

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MemoryMainFrame extends JFrame implements ActionListener {

    JButton button[] = new JButton[16];
    private static final int SIXTEEN_BUTTONS = 16;
    JPanel mainPanel = new JPanel();
    double dim = Math.sqrt(SIXTEEN_BUTTONS);
    int numOfColumns = (int) (dim);
    int numOfRows = (int) (dim);

    public static void main(String[] args) {
        new MemoryMainFrame();
    }

    public MemoryMainFrame() {

        this.setTitle("MemoryGame!!!");
        this.setSize(400, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);

        mainPanel.setBackground(Color.BLACK);
        mainPanel.setLayout(new GridBagLayout());

        // execution
        FillButtonArray(SIXTEEN_BUTTONS);
        AddButtonListener(SIXTEEN_BUTTONS);
        ButtonToPanel(SIXTEEN_BUTTONS);

        this.add(mainPanel);
    }

    public void FillButtonArray(int numOfButtons) {
        int i = 0;

        while (i < numOfButtons) {
            button[i] = new JButton("asdf");
        }
    }

    public void AddButtonListener(int numOfButtons) {
        int i = 0;

        while (i < numOfButtons) {
            button[i].addActionListener(this);
        }
    }

    public void ButtonToPanel(int numOfButtons) {
        int n = 0;
        GridBagConstraints gbc = new GridBagConstraints();

        for (int i = 0; i < numOfColumns; i++) {
            for (int j = 0; j < numOfRows; j++) {

                gbc.gridx = i;
                gbc.gridy = j;
                n++;

                button[n].setBorder(BorderFactory.createLineBorder(
                        Color.DARK_GRAY, 2));
                mainPanel.add(button[n]);
            }
        }
    }

    public void actionPerformed(ActionEvent arg0) {

        JFrame j = new JFrame();
        j.setSize(300, 300);
        j.setVisible(true);
    }
}

I use the "asdf" as a test to see if the buttons work as well.

also, the actionperformed was a test as well. That part of the code is irrelevant.

Upvotes: 0

Views: 483

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

You're creating your GridBagConstraints but you're not using them.

Change this:

mainPanel.add(button[n]);

to this:

// passes both the component and the GBC into the container
mainPanel.add(button[n], gbc); 

Edit
You've also got a never-ending loop here:

  while (i < numOfButtons) {
     button[i] = new JButton("asdf");
  }

and likewise for the AddButtonListener(...) method.

You'll want to fix this by using either a for loop or else changing i within the loop.

Also per Andrew Thompson's comment, you're setting the JFrame visible too early, before all components have been added.

Also your use of Math.sqrt then casting the result to int is very risky and risks getting unexpected results. Just declare the side length to 8 and square the int if you need to.

For an example of GridBagLayout, please check out:

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")  // avoid extending JFrame if possible
public class MemoryMainPanel extends JPanel {
   private static final int ROWS = 8;
   private static final Color BACKGROUND = Color.black;
   private static final int I_GAP = 5;
   private static final Insets BTN_INSETS = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
   private JButton[][] buttons = new JButton[ROWS][ROWS];


   public MemoryMainPanel() {
      setBackground(BACKGROUND);
      setLayout(new GridBagLayout());
      for (int row = 0; row < buttons.length; row++) {
         for (int col = 0; col < buttons[row].length; col++) {
            JButton btn = new JButton(new ButtonAction(row, col));
            add(btn, createGbc(row, col));
            buttons[row][col] = btn;
         }
      }
   }

   private GridBagConstraints createGbc(int y, int x) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.insets = BTN_INSETS;
      return gbc;
   }

   private class ButtonAction extends AbstractAction {
      private int row;
      private int col;

      public ButtonAction(int row, int col) {
         super("asdf");
         this.row = row;
         this.col = col;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         String text = String.format("Column, Row: [%d, %d]", col + 1, row + 1);
         Component parentComponent = MemoryMainPanel.this;
         String message = text;
         String title = "Button Pressed";
         int messageType = JOptionPane.PLAIN_MESSAGE;
         Icon icon = null;
         JOptionPane.showMessageDialog(parentComponent, message, title, messageType, icon);
      }
   }

   private static void createAndShowGui() {
      MemoryMainPanel mainPanel = new MemoryMainPanel();

      JFrame frame = new JFrame("MemoryMainPanel");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Upvotes: 6

Related Questions