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:
How do I change the size of the frame to resize itself based on the panel sizes?
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!
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...
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)