Я немного смущен тем, как управлять компоновкой моих компонентов на Java (я хочу сделать это вручную, а не обрабатывать его менеджером макета). Есть эти методы в Component
:Java/AWT/Swing: об утверждении и размерах
layout
,doLayout
validate
,invalidate
,revalidate
validateTree
,invalidateTree
setSize
,setBounds
,setPreferredSize
getSize
,getBounds
,getPreferredSize
paint
,repaint
,update
updateUI
Ранее я пытался перегружать различные комбинации выше, но я не был уверен, какой из них перегружать и что именно я должен сделать внутри и что функции, я должен вызвать дочерние компоненты.
Что я делаю сейчас:
- только перегружать
doLayout
выше. - В
doLayout
для всех дочерних компонентов:- Вызов
child.doLayout
. - Звоните
child.setBounds
(иногда доchild.setBounds
, иногда после, иногда оба).
- Вызов
- В
doLayout
, потому что я делаю макет, я автоматически рассчитал также его предпочтительный размер. - В
doLayout
, звонитеthis.setPreferredSize
. - Для всех конструкторов звоните:
this.setLayout(null)
. - В некоторых конструкторах звоните:
this.doLayout
. (И если я этого не делаю, он отображается неправильно). - Когда я выполняю некоторую операцию, в которой я должен переделать макет (например, я динамически добавил некоторое текстовое поле в какой-либо контейнер, и поэтому я хочу изменить размер контейнера и также все родители соответственно), я звоню
container.revalidate()
.
Остающиеся проблемы:
- Я думаю, что я до сих пор не совсем понял, что функция вызывает то, что, что я должен перегружать и как обращаться.
- В
doLayout
, я звонюthis.setPreferredSize
.doLayout
сам часто зависит отthis.getSize()
. Для родителя частоchild.setBounds
зависит отchild.getPreferredSize()
.Поэтому у меня есть дилемма, что в некоторых случаях мне сначала нужно позвонитьchild.doLayout
, а затемchild.setBounds
, а в некоторых других случаях наоборот. А в некоторых случаях еще сложнее. Так что все кажется, что я должен позвонитьthis.setPreferredSize
где-то в другом месте. Но где? Потому что он всегда должен обновляться при изменении размера (именно поэтому я перегрузилsetBounds
раньше, но это было еще более уродливо). - У меня есть все внутри
JScrollPane
, которое устанавливает полосы прокрутки в соответствии сviewportView.getPreferredSize()
.revalidate
Я звоню в случаях, когда я хочу пересчитать макет, вызываетdoLayout
звонки, которые правильно звонятsetPreferredSize
для всех компонентов/контейнеров в иерархии. Хотя, кажется, чтоJScrollPane
устанавливает свою полосу прокрутки до, вызванныйdoLayout
, и, следовательно, это всегда неправильно. Как я могу это исправить?
Некоторые дополнительные мысли (просьба прокомментировать) о том, как я, возможно, мог бы решить эту проблему JScrollPane
(на самом деле не пытался, потому что это потребует некоторых крупных переделок, так что я хотел спросить первого):
- Удалить все
setPreferredSize
calls indoLayout
. - Перегрузка
getPreferredSize
и звонитеdoLayout
оттуда (чтобы получить предпочтительный размер).
- ИЛИ -
- Вместо вызова
revalidate
когда я делаю то, что требует, чтобы переделать макет, вызовитеvalidateTree
.
- ИЛИ -
- Вместо вызова
revalidate
когда я делаю то, что требует, чтобы переделать макет, назвать всеdoLayout
вручную, а затем сrevalidate
наJScrollPanel
.
И, наконец, как я идти о круговой зависимости от размера и предпочтительного размера? Я довольно часто имею этот случай:
comp.width
зафиксирован в корне. Я могу установить ширину в корне и рекурсивно перейти к всем дочерним элементам и установить ее ширину.comp.height
закреплен на самом внутреннем ребенке и зависит от его ширины. Поэтому после того, как я установил все ширины, я могу рассчитать и установить высоты снизу вверх.
Я не могу позвонить setPreferredSize
, прежде чем я не позвонил setSize
. И я не могу позвонить setSize
, прежде чем я не позвонил setPreferredSize
.
-1, Почему вы изобретаете колесо? «Обработка вручную» на самом деле создает собственный менеджер макетов. Почему бы просто не использовать интерфейс на месте, чтобы другие люди поняли ваш код и смогут его поддерживать? – camickr
@camickr: Потому что я всегда чувствовал, что он не делает то, что я хочу. Кроме того, мое оформление абсолютно тривиально; Я действительно не понимаю, зачем мне вообще нужен. Я абсолютно уверен, что фактический код для компоновки моих компонентов намного проще и короче, чем настроить и взломать любой существующий менеджер макетов, который работает именно так, как я хочу. – Albert
@ Альберт, тогда вы не понимаете, как работают менеджеры макетов. Гораздо проще создать собственный менеджер компоновки с тривиальной логикой компоновки, тогда он будет переопределять все те методы, о которых вы упомянули выше.Пока вы не попробуете написать простой менеджер макетов, я не думаю, что вы можете сказать, что проще. Ведь ваш текущий подход не работает, и именно поэтому вы задаете вопрос. Придерживайтесь известных подходов, и больше людей на форуме смогут помочь. У меня нет совета, чтобы предложить вашу проблему, так как я понятия не имею, что вы пытаетесь сделать. – camickr