Проблема заключается в том, что GridLayout гарантирует, что все компоненты имеют одинаковый размер. Это означает, что ширина и высота панели (p1) должны быть кратными 20, чтобы компоненты достигли края. Вы можете либо убедиться, что панель фиксированный размер, как это (в конце конструктора):
setResizable(false);
p1.setPreferredSize(new Dimension(400, 400));
add(p1);
pack();
Ваш вызов frame.setSize (...) не делал панель 400 на 400, потому что размер кадра включает границу вокруг кадра.
В качестве альтернативы вы можете использовать собственный менеджер макетов, который не гарантирует, что все кнопки имеют одинаковый размер. Этот пример заставит кнопку заполнить всю площадь панели:
private static class FullyJustifiedGridLayout implements LayoutManager {
private final int rows;
private final int columns;
public FullyJustifiedGridLayout(int rows, int columns) {
this.rows = rows;
this.columns = columns;
}
@Override
public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
double clientWidth = parent.getWidth() - parent.getInsets().left - parent.getInsets().right;
double clientHeight = parent.getHeight() - parent.getInsets().top - parent.getInsets().bottom;
for (int i = 0; i < parent.getComponents().length; i++) {
Component component = parent.getComponents()[i];
int row = i/rows, column = i % columns;
int x = (int)(clientWidth * column/columns);
int y = (int)(clientHeight * row/rows);
int nextX = (int)(clientWidth * (column + 1)/columns);
int nextY = (int)(clientHeight * (row + 1)/rows);
component.setBounds(x, y, nextX - x, nextY - y);
}
}
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(20 * 10, 20 * 10);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return new Dimension(20 * 20, 20 * 20);
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
}
Просто замените вызов нового GridLayout (20, 20) с новым FullyJustifiedGridLayout (20, 20).
Кроме того, при использовании менеджеров компоновки нет необходимости вызывать setSize, setLocation или setBounds для компонентов - они вызывается менеджером компоновки, когда она отображает панель. Если вы хотите изменить размеры компонентов, вместо этого используйте setPreferredSize.
Ваша панель p1 уже занимает весь кадр. Установите цвет фона, и вы увидите. Вопрос должен состоять в том, как вы можете получить макет, чтобы использовать все пространство. –