Когда GridBagLayout не может вместить все предпочтительные размеры дочерних компонентов, он «сдается» и устанавливает для каждого отдельного дочернего компонента минимальный размер. Таким образом, одним из решений является установка минимального размера каждого компонента равным предпочтительному размеру.
Однако вместо того, чтобы математически учитывать каждый пиксель на экране, у вас есть более надежные варианты.
Одним из решений является установка размера только одной панели в любом конкретном измерении, чтобы другая всегда занимала оставшееся пространство. Таким образом, вы никогда не сможете «переполнить» доступное пространство. BorderLayout хорошо подходит для этого, поскольку его центральный компонент растянут, чтобы занять все доступное пространство, которое не используются боковыми компонентами.
Итак, для ваших пурпурных и синих панелей вы должны установить высоту только пурпурной панели:
JPanel leftPanel = new JPanel(new BorderLayout());
// 1
JPanel leftUpper = new JPanel();
leftUpper.setBackground(Color.MAGENTA);
leftUpper.setPreferredSize(new Dimension(1, height/7));
leftPanel.add(leftUpper, BorderLayout.NORTH);
// 2
JPanel leftLower = new JPanel();
leftLower.setBackground(Color.BLUE);
leftPanel.add(leftLower, BorderLayout.CENTER);
И аналогично для красных и голубых:
JPanel rightPanel = new JPanel(new BorderLayout());
// 3
JPanel rightUpper = new JPanel();
rightUpper.setBackground(Color.RED);
rightPanel.add(rightUpper, BorderLayout.CENTER);
// 4
JPanel rightLower = new JPanel();
rightLower.setBackground(Color.CYAN);
rightLower.setPreferredSize(new Dimension(1, height/5));
rightPanel.add(rightLower, BorderLayout.SOUTH);
И затем вы делаете что-то похожее на эти две панели, чтобы собрать их вместе:
JPanel masterPanel = new JPanel(new BorderLayout());
masterPanel.setBackground(Color.GREEN);
leftPanel.setPreferredSize(new Dimension(width / 3,
leftPanel.getPreferredSize().height));
masterPanel.add(leftPanel, BorderLayout.WEST);
masterPanel.add(rightPanel, BorderLayout.CENTER);
А поскольку сообщение о границах, заданных окнам системным диспетчером окон, ненадежно, вы избегаете какой-либо явной математики и просто максимизируете окно:
frame.add(masterPanel);
frame.pack();
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setVisible(true);
Если вам абсолютно необходимо поддерживать соотношение между панелями (например, magenta_height: blue_height :: 1: 6), вы можете сделать это с помощью SpringLayout , но SpringLayout более сложный и обычно не не стоит хлопот Позволяет указать диапазоны размеров, которые могут быть кратны другим диапазонам размеров:
SpringLayout layout = new SpringLayout();
JPanel masterPanel = new JPanel(layout);
masterPanel.setBackground(Color.GREEN);
// 1
JPanel leftUpper = new JPanel();
leftUpper.setBackground(Color.MAGENTA);
masterPanel.add(leftUpper);
// 2
JPanel leftLower = new JPanel();
leftLower.setBackground(Color.BLUE);
masterPanel.add(leftLower);
// 3
JPanel rightUpper = new JPanel();
rightUpper.setBackground(Color.RED);
masterPanel.add(rightUpper);
// 4
JPanel rightLower = new JPanel();
rightLower.setBackground(Color.CYAN);
masterPanel.add(rightLower);
Spring leftUpperHeight = Spring.height(leftUpper);
Spring leftLowerHeight = Spring.scale(leftUpperHeight, 6);
Spring rightLowerHeight = Spring.scale(leftUpperHeight, 7 / 5f);
Spring leftWidth = Spring.width(leftUpper);
Spring rightWidth = Spring.scale(leftWidth, 3);
layout.getConstraints(leftLower).setHeight(leftLowerHeight);
layout.getConstraints(rightLower).setHeight(rightLowerHeight);
layout.getConstraints(rightUpper).setWidth(rightWidth);
layout.getConstraints(rightLower).setWidth(rightWidth);
// Place leftLower beneath leftUpper.
layout.putConstraint(
SpringLayout.NORTH, leftLower, 0,
SpringLayout.SOUTH, leftUpper);
// Make leftLower's width match leftUpper's width.
layout.putConstraint(
SpringLayout.WEST, leftLower, 0,
SpringLayout.WEST, leftUpper);
layout.putConstraint(
SpringLayout.EAST, leftLower, 0,
SpringLayout.EAST, leftUpper);
// Make container high enough to hold both leftLower and leftUpper.
layout.putConstraint(
SpringLayout.SOUTH, masterPanel, 0,
SpringLayout.SOUTH, leftLower);
// Place rightUpper and rightLower to the right of leftUpper.
layout.putConstraint(
SpringLayout.WEST, rightLower, 0,
SpringLayout.EAST, leftUpper);
layout.putConstraint(
SpringLayout.WEST, rightUpper, 0,
SpringLayout.WEST, rightLower);
// Make container wide enough to accommodate rightUpper and rightLower.
layout.putConstraint(
SpringLayout.EAST, masterPanel, 0,
SpringLayout.EAST, rightLower);
// Align bottom of rightLower with bottom of leftLower.
layout.putConstraint(
SpringLayout.SOUTH, rightLower, 0,
SpringLayout.SOUTH, leftLower);
// Place rightUpper above rightLower.
layout.putConstraint(
SpringLayout.SOUTH, rightUpper, 0,
SpringLayout.NORTH, rightLower);
// Stretch rightUpper to reach to the top of the container.
layout.putConstraint(
SpringLayout.NORTH, rightUpper, 0,
SpringLayout.NORTH, masterPanel);