0

Basically my GUI is like this:

A frame that contains a free designed layout JPanel called mainPanel

Inside mainPanel are two other panels:

A) toolPanel of layout BoxLayout

B) gamePanelof layout GridLayout

These are the significant bits of the code:

public Normalv3() {
    initComponents();
    importBombs();
}

public void importBombs() {

    rows = Minesweeper.rows;
    columns = Minesweeper.columns;
    total = rows*columns;
    bombsIndexes = new ArrayList<Integer>(Minesweeper.totalBombs);

    // Creating a new grid layout and putting
    // it inside the old layout
    gamePanel.setLayout(new java.awt.GridLayout(rows, columns));


    ////
    Random ran = new Random();
    int low = 1;
    int high = rows*columns;
    int ranValue;
    for (int i = 0; i< Minesweeper.totalBombs; i++) {
        ranValue = ran.nextInt(high - low) + low;

        if(bombsIndexes.contains(ranValue)) {
            i--;
            continue;
        }

        bombsIndexes.add(ranValue);
    }
    ////

    for (int i = 1; i <= total; i++) {
        btnMines b = new btnMines(i);
        if(bombsIndexes.contains(i)) {
            b.isBomb = true;
            b.setIcon(new javax.swing.ImageIcon(
                getClass().getResource(
                    "/minesweeper/resources/bomb.png")));
        }
        b.setPreferredSize(new Dimension(20, 20));

        gamePanel.add(b);
    }
    this.setResizable(false);
    this.setTitle("Minesweeper");
    this.pack(); // Sizes frame so that all components
                 // are at their preferred sizes
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.validate(); // Recalculate layout
    this.setVisible(true);
}

The problem is when I increase the number of columns, the width of either the gamePanel or mainPanel increases, but the width of the frame does not.

Example:

Enter image description here

How do I change the size of the frame to resize itself based on the panel sizes?

Note: btnMines is basically just a JButton with some variables attached to it.

Bonus question: how would I go about making each button into squares? As you can see, I tried making it square by writing b.setPreferredSize(new Dimension(20, 20));, but each resulting button is still a rectangle!

Also, I know the code is messy. I used to separate that function into separate functions, but now I decided to put it all in one function just to test it out properly.

I tried adding:

this.setResizable(false);
this.setTitle("Minesweeper");
this.pack(); // Sizes frame so that all components
             // are at their preferred sizes
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.validate(); // Recalculate layout
this.setVisible(true);

But it didn’t work since the frame didn’t resize!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sami
  • 15
  • 5
  • *Frame that contains a Free Designed layout JPanel* - not needed. Probably uses a null layout which won't work. By default, a frame uses a BorderLayout. So, you just add your "toolPanel" to the frame using BorderLayout.PAGE_START and the "gamePanel" using BorderLayout.CENTER. Then you `pack()` the frame before making it visible. Did you solve your other problem: https://stackoverflow.com/q/74246638/131872? Looks like it since I see images of the bomb. So why haven't you comment on the question indicating the problem has been solved? – camickr Oct 29 '22 at 23:00
  • My first concern is what `initComponents` is doing. You should avoid extending directly from top level containers like `JFrame`, this could be causing "other" issues – MadProgrammer Oct 29 '22 at 23:00
  • 1
    Why did you delete your last question? You still didn't respond indicating if the suggestions helped or not. See: [What should I do when someone answers my question](https://stackoverflow.com/help/someone-answers) – camickr Oct 30 '22 at 14:01

1 Answers1

2

Frame that contains a Free Designed layout JPanel called mainPanel

This seems to suggest that mainPanel might be using a null layout, which is going to cause you issues, but this is just a guess.

JFrame#pack should be wrapping the frame around the content based on the contents "preferred size" hints, provided via the subsequent layout managers, which is leads me to question what layout managers (if any) are involved in your design.

For example...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new Normalv3(10, 10));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Normalv3 extends JPanel {

        public Normalv3(int cols, int rows) {
            setLayout(new BorderLayout());
            add(makeControlsPane(), BorderLayout.NORTH);
            add(makeGamePane(cols, rows));
        }

        protected JPanel makeControlsPane() {
            JPanel pane = new JPanel(new FlowLayout(FlowLayout.LEADING));
            pane.add(new JButton("Back to Menu"));
            pane.add(new JButton("Reset"));
            return pane;
        }

        protected JPanel makeGamePane(int cols, int rows) {
            JPanel pane = new JPanel(new GridLayout(rows, cols));
            for (int index = 0; index < (cols * rows); index++) {
                JButton btn = new SquareButton("*");
                pane.add(btn);
            }
            return pane;
        }
    }

    class SquareButton extends JButton {

        SquareButton(String s) {
            super(s);
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();
            int s = (int) (d.getWidth() < d.getHeight() ? d.getHeight() : d.getWidth());
            return new Dimension(s, s);
        }
    }
}

Square button design take from Creating Square Buttons in Swing

As a side note - I'd encourage you NOT to make use of form designers, they tend to become messy very quickly and are difficult to diagnose and maintain (IMHO)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366