В общем, вы не должны играть с абсолютными процентами, особенно на отдельных композитах. Вы должны позволить компоненту отображаться в его предпочтительном размере. Так что твой пример действительно не имеет никакого смысла. Когда у вас есть форма с текстовой областью и кнопками. Тогда изменения в размере должны влиять на текстовую область, а не на кнопки. Затем вы добавляете полосу прокрутки в текстовую область, чтобы полоса прокрутки появлялась или исчезала по мере необходимости.
Однако, если по какой-то причине вам нужно использовать абсолютные проценты на уровне панели, вы можете использовать код, подобный следующему:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagSSCCE extends JPanel
{
JPanel red;
JPanel green;
public GridBagSSCCE()
{
setLayout( new GridBagLayout() );
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.VERTICAL;
red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(300, 10) );
gbc.weighty = 0.1;
add(red, gbc);
green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(300, 90) );
gbc.gridy = 1;
gbc.weighty = 0.9;
add(green, gbc);
JPanel buttons = new JPanel();
buttons.add( new JButton("Ok") );
buttons.add( new JButton("Cancel") );
buttons.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
gbc.gridy = 2;
gbc.weighty = 0.0;
gbc.anchor = GridBagConstraints.LINE_END;
add(buttons, gbc);
addComponentListener( new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
System.out.println(red.getSize() + " : " + green.getSize());
}
});
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("GridBagSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new GridBagSSCCE() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Ключ в приведенном выше коде - начать с предпочтительного размера при желаемом соотношении (10/90), а также установить весовые коэффициенты компонентов в том же соотношении.
Если вы хотите, вы также можете проверить Относительный макет , который был написан специально для этой цели.
Edit:
GridBagLayout не отображает компоненты в процентах. То, что у вас есть две строки, не означает, что каждая строка составляет 50%. Высота каждой строки зависит от высоты каждого компонента, добавляемого в каждую строку.
Сначала вы решаете, какой объем данных будет отображаться в текстовой области. Для двух строк вы бы использовали что-то вроде:
JTextArea textArea = new JTextArea(2, 40);
JScrollPane scrollPane = new JScrollPane( textArea );
Затем вы создаете панель с кнопками.
Может получиться, что текстовая область с 2 строками примерно такого же размера, как панель с кнопками, потому что панель добавляет вертикальный разрыв над и под компонентом, а кнопка имеет относительно большую границу, но это просто совпадение , Но вы не должны заставлять текстовую область быть больше половины. Просто позвольте менеджеру раскладки и методу pack () выполнить свою работу.
Теперь вам нужно решить, что произойдет, когда размер кадра увеличится, так как это определит менеджер компоновки родительского контейнера. В этом случае я бы, вероятно, использовал BorderLayout, поэтому я бы использовал такой код:
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
Вам все равно, является ли текстовая область половиной рамки или нет. Метод упаковки определяет относительные размеры каждого компонента на основе их предпочтительных размеров. Если рамка увеличивается, текстовая область становится больше места.