Размер JPanel по внутренним компонентам
Можно ли сообщить JPanel установить его размер для соответствия всем компонентам, которые он содержит? Что-то вроде pack()
для JFrame.
edit: трюк с preferredSize не помог. У меня JSplitPane, где в одной части есть GridBagLayout со многими ярлыками (см. Снимок экрана) и метки перекрываются друг с другом.
снимок экрана http://foto.darth.cz/pictures/screen.png
Ответы
Ответ 1
Посмотрев исходный код pack()
, я придумал:
panel.setPreferredSize(panel.getPreferredSize());
Это заставляет панель пересчитывать свой предпочтительный размер на основе предпочтительных размеров его подкомпонентов.
Возможно, вам может понадобиться позвонить validate()
; на моем крошечном примере это, казалось, не имело значения, но Джавадок говорит:
Метод validate
используется для того, чтобы контейнер снова выложил свои подкомпоненты. Он должен вызываться, когда подкомпоненты этого контейнера изменяются (добавляются или удаляются из контейнера или изменяются сведения о компоновке) после отображения контейнера.
Итак, я думаю, это зависит от того, почему вам нужно переупаковать ваш JPanel
.
Ответ 2
По умолчанию Container
имеют предпочтительный размер, соответствующий размеру макета, заданному контейнером. Таким образом, буквально все, что вам нужно сделать, это:
panel.setSize(panel.getPreferredSize());
Предположительно, вы делаете что-то нечетное с родителем, чтобы остановить родительский менеджер макета, выполнив эквивалент этого.
Ответ 3
возможно, вы можете сделать что-то подобное, удалив из панели
setResizable (ложь);
Ответ 4
Я бы попробовал:
panel.revalidate();
panel.repaint();
Это не обязательно приведет к выбору размера панели, что больше зависит от того, что решает использовать менеджер макета.
Это полезно в тех случаях, когда вы добавили/удалили компоненты с панели, которая в настоящее время отображается и отображается.
Обновление:
На основании вашего снимка экрана я могу сказать следующее:
1) Рассмотрим программное изменение положения разделителя.
2) Рассмотрим программное изменение размера окна непосредственно по горизонтали, так как кажется, что он немного напряжен, чтобы показать обе стороны разделительной панели.
Или оба.
Вы можете установить местоположение разделителя, выполнив
splitPane.setDividerLocation(newSize);
Имейте в виду, что для этого есть два перегруженных метода: один принимает float, берущий int. Поплавок делает процент от размера, а int - размером в пикселях. Размер для левой панели (или верхней панели для этой ориентации).
Я бы подумал, возможно, изменить расположение разделителя на основе предпочтительной ширины панелей.
Ответ 5
У меня была аналогичная проблема, используя NetBeans GUI Builder. Мои внутренние панели приобретали странные размеры; Я пытался настроить минимальные и предпочтительные размеры вручную, что было расстраивающим упражнением.
Проблема была решена, когда я reset все минимальные и предпочтительные размеры возвращаются к стандартным (в NetBeans GUI Builder: щелкните правой кнопкой мыши компонент JPanel → Свойства → preferredSize → Reset до По умолчанию). Когда нет установленного размера, jpanel принимает размер внутреннего компонента.
Примечание: GridBaLayout использовался в моем случае
Ответ 6
JSplitPanes немного суетливы, когда дело доходит до размеров своих детей, посмотрите учебник по Java. Правильно ли вы используете GridBagLayout? Похоже, что он не устанавливает правильный минимальный размер JPanel.
Ответ 7
Тайны javax.swing проявляются только постепенно, и только тем, кто готов предложить много возлияний (особенно разорванные куски волос, часы, сжигающие полночное масло и т.д.) богам Свинг.
Однако для этого случая в пункте я я бы предложил следующее как своего рода швейцарский армейский нож, который обычно делает то, что, по вашему мнению, должен делать каркас:
myJPanel.getTopLevelAncestor().validate()
Как говорится в священном тексте: "Проверяет этот контейнер и все его подкомпоненты". (Container.validate). NB getTopLevelAncestor() - метод JComponent.
Не помню, как JSplitPane вписывается в это: попробуйте, и вы, вероятно, обнаружите, что он проверяет оба компонента (справа и слева, сверху и снизу), но я был бы удивлен, если изменение разделителя не сделает этого для вас в любом случае.