Базовый c ответ заключается в том, что вам необходимо воспользоваться преимуществами инфраструктуры управления макетами.
Менеджеры компоновки работают с учетом предпочтительного / минимального / максимального размера компонента, но будьте осторожны, они являются только руководствами, и менеджеры по расположению могут игнорировать некоторые или все из них в зависимости от своих потребностей и доступного пространства.
Это простой пример, который переопределяет метод getPreferredSize
header
для возврата «желаемого» "size:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new BorderLayout());
JPanel header = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 50);
}
};
header.setLayout(new BorderLayout());
header.setBackground(Color.gray);
// I would allow the content of the panel determine the actual size
// but I've overridden `getPreferredSize` for demonstration purposes
JPanel body = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
body.setLayout(new BorderLayout());
body.setBackground(Color.black);
frame.add(header, BorderLayout.NORTH);
frame.add(body, BorderLayout.CENTER);
// pack is preferred over setSize, as it will "pack" the window around
// the content, which will produce a more consistent result
frame.pack();
frame.setVisible(true);
Проблема заключается в том, что компонент больше не будет учитывать требования к размерам своих дочерних элементов, поэтому у вас могут возникнуть странные побочные эффекты.
Существуют и другие решения, которые могут предоставить некоторые другие преимущества и недостатки, и вам нужно будет рассмотреть их в вашем случае использования.
Почему следует переопределить getPreferredSize
вместо вызова setPreferredSize
?
В основном, контроль. Вы можете запретить другим частям кода изменять состояние, и вы контролируете, «как» выполняется вычисление. Конечно, ничто не мешает другим кодам расширять компонент и переопределять метод, но это более сложно и не учитывает сценарий ios, где предоставляется экземпляр компонента, а не создается.
Зачем использовать pack
сверх setSize
?
pack
"упаковывает" рамку окна вокруг содержимого, поэтому содержимое всегда будет соответствовать своему предпочтительному размеру, а не уменьшаться содержание, так что украшения кадра могут быть размещены. В целом это приведет к более согласованному результату на нескольких платформах