В основном мой графический интерфейс выглядит так:
Фрейм, содержащий свободно разработанный макет JPanel, называемый mainPanel.
Внутри mainPanel находятся две другие панели:
А) панель инструментов макета BoxLayout
Б) раскладка gamePanel из GridLayout
Это значимые биты кода:
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);
}
Проблема в том, что когда я увеличиваю количество столбцов, ширина либо gamePanel, либо mainPanel увеличивается, но ширина фрейма не увеличивается.
Пример:
Как изменить размер рамки, чтобы изменить ее размер в зависимости от размеров панели?
Бонусный вопрос: как мне сделать каждую кнопку квадратной? Как видите, я попытался сделать его квадратным, написав b.setPreferredSize(new Dimension(20, 20));, но каждая получившаяся кнопка по-прежнему остается прямоугольником!
Кроме того, я знаю, что код грязный. Раньше я разделял эту функцию на отдельные функции, но теперь я решил поместить все это в одну функцию, просто чтобы проверить ее должным образом.
Я попытался добавить:
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);
Но это не сработало, так как размер кадра не изменился!
Меня в первую очередь беспокоит то, что initComponents делает. Вам следует избегать расширения напрямую из контейнеров верхнего уровня, таких как JFrame, это может вызвать «другие» проблемы.
Почему вы удалили свой последний вопрос? Вы все еще не ответили, указав, помогли ли предложения или нет. Смотрите: Что мне делать, когда кто-то отвечает на мой вопрос




Фрейм, содержащий макет JPanel Free Designed, называемый mainPanel
Кажется, это говорит о том, что mainPanel может использовать макет null, который вызовет у вас проблемы, но это всего лишь предположение.
JFrame#pack должен оборачивать рамку вокруг содержимого на основе подсказок содержимого «предпочтительный размер», предоставляемых через последующие менеджеры компоновки, что заставляет меня задаться вопросом, какие менеджеры компоновки (если таковые имеются) участвуют в вашем дизайне.
Например...
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);
}
}
}
Дизайн квадратных кнопок взят из Создание квадратных кнопок в Swing
В качестве примечания - я бы посоветовал вам НЕ использовать конструкторы форм, они, как правило, очень быстро запутываются, и их трудно диагностировать и поддерживать (ИМХО).
Фрейм, содержащий макет Free Designed JPanel — не нужен. Вероятно, использует нулевой макет, который не будет работать. По умолчанию фрейм использует BorderLayout. Таким образом, вы просто добавляете свою "toolPanel" во фрейм с помощью BorderLayout.PAGE_START и "gamePanel" с помощью BorderLayout.CENTER. Затем вы
pack()кадр, прежде чем сделать его видимым. Вы решили другую свою проблему: stackoverflow.com/q/74246638/131872? Похоже на это, так как я вижу изображения бомбы. Так почему же вы не прокомментировали вопрос о том, что проблема решена?