0

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.

almightyGOSU
  • 3,731
  • 6
  • 31
  • 41
  • 1
    `public void actionPerformed(ActionEvent arg0) { JFrame j = new JFrame();` That suggests that the app. is using multiple frames. See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Jul 08 '15 at 02:15
  • 1
    "*`this.setVisible(true); .. this.add(mainPanel);`"* should be "*`..this.add(mainPanel); this.pack(); this.setVisible(true);`"*. That is likely the root of the problem. – Andrew Thompson Jul 08 '15 at 02:17
  • @AndrewThompson: indeed. He also has a never-ending while loop. – Hovercraft Full Of Eels Jul 08 '15 at 02:36

1 Answers1

6

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();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I have to admit. that was silly of me BUT it isn't the problem. I had been switching between GridLayout() and GridBagLayout() and was not getting either to work. I had forgotten to add in the constraints. but good catch! – Kyle Keberlein Jul 08 '15 at 02:09
  • Thanks! Great way to lay that out! I like how you are adding to just the contentPane(). – Kyle Keberlein Jul 09 '15 at 01:31