Проблема в том, что GridLayout гарантирует, что все компоненты имеют одинаковый размер.Это означает, что ширина и высота панели (p1) должны быть кратны 20, чтобы компоненты достигли края.Вы можете либо убедиться, что панель имеет фиксированный размер, например так (в конце конструктора):
setResizable(false);
p1.setPreferredSize(new Dimension(400, 400));
add(p1);
pack();
Ваш вызов frame.setSize (...) не сделал панель 400400, потому что размер кадра включает в себя границу вокруг рамки.
В качестве альтернативы вы можете использовать собственный менеджер макета, который не гарантирует, что все кнопки имеют одинаковый размер.Этот пример заставит кнопки заполнить всю область панели:
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.