Я использую JPanel (с несколькими маркировками внутри) для добавления динамической информации о графике. Эта панель динамично создается, это не видимо, прежде чем я буду использовать его для рисования.
Для этого я использую BufferedImage, и я выполняю приблизительно те же шаги, как описано по этому другому вопросу. Это работает хорошее, пока я указываю все размеры (панель и ее компоненты).
Как спрошенный также в комментариях отнесенного вопроса, как я могу определить оптимальный размер этой панели? Та же операция была бы сделана, если бы эта панель была отображена в обычном кадре / установка расположения.
В моем случае, как я могу "упаковать", в некотором смысле, эта панель, так, чтобы ее размер и размер ее содержания были установлены на оптимальное (определенный размером маркировок, затем)?
Сурадж и willcodejavaforfood поставили меня на верный путь.
Проверяя, что на самом деле делается в методе pack ()
, я вижу, что это в основном установка текущего размера на тот, который возвращается getPreferredSize ()
.
Исходя из этого, мне удалось сделать следующее решение:
// Creating the panel
JPanel lPanel = new JPanel();
//lPanel.setSize(1000, 1000); //default size, not needed anymore
lPanel.setLayout(new BoxLayout(lPanel, BoxLayout.PAGE_AXIS));
//Adding the content
lPanel.add(new JLabel("Blah"));
// etc...
//Adjust the panel to its preferred size
lPanel.setSize(lPanel.getPreferredSize());
//Call the layout method
//(this will adjust the content components to their correct size and position)
lPanel.doLayout();
Этот метод работает правильно и настраивает панель и ее содержимое до правильного размера (и упрощенно отвечает на мой вопрос: «как найти предпочтительный размер? getPreferredSize ()
").
Однако для этого необходимо установить достаточно большой начальный размер, чтобы содержимое поместилось, иначе они не будут помещены в макет. Это немного жаль и не совсем "чисто", но пока я не могу найти способа избежать этого.
Изменить: На самом деле размер по умолчанию не был необходим, потому что getPreferredSize ()
возвращает правильное значение, даже до вызова doLayout ()
. Таким образом, перед вызовом метода макета панель можно настроить на правильный размер.
Прямой ответ - вызвать Window # pack () . Этот метод автоматически установит размер всех нижележащих дочерних элементов. к их предпочтительным размерам (конечно, это зависит от макетов дочерних контейнеров, например, BorderLayout doesent наплевать на предпочтительные размеры).
Итак, если вы установили предпочтительные размеры (или минимальные / максимальные размеры в случае l ayouts похожи на BorderLayout) ваших дочерних компонентов, метод pack () будет всем, что вам нужно.
[ОБНОВЛЕНИЕ]
Один из способов - добавить HierarchyListener в jpanel и проверить наличие HierarchyEvent #DISPLAYABILITY_CHANGED события. Это событие вызывается, когда ваша панель осознается, что готова к отображению (и родительский элемент доступен), в этот момент вы можете сделать:
SwingUtilities # getWindowAncestor (myPanel) .pack ();