Java: разница между методами setPreferredSize() и setSize() в компонентах

В чем основная разница между setSize() и setPreferredSize(). Иногда я использовал setSize(), иногда setPreferredSize(), иногда одно делает то, что я хочу, иногда другое.

Какой вызов следует использовать для JFrames и JPanels?


person David Robles    schedule 23.11.2009    source источник


Ответы (4)


Использование зависит от того, есть ли у родителя компонента менеджер компоновки или нет.

  • setSize() -- использовать, когда родительского менеджера компоновки не существует;
  • setPreferredSize() (также связанные с ним setMinimumSize и setMaximumSize) -- используйте, когда существует родительский менеджер компоновки.

Метод setSize(), вероятно, ничего не сделает, если родитель компонента использует менеджер компоновки; обычно это влияет на компоненты верхнего уровня (JFrames и JWindows) и элементы внутри прокручиваемых панелей. Вы также должны вызывать setSize(), если у вас есть компоненты внутри родителя без менеджера компоновки.

Как правило, setPreferredSize() компонует компоненты, как и ожидалось, если присутствует менеджер компоновки; большинство менеджеров компоновки работают, получая предпочтительные (а также минимальные и максимальные) размеры своих компонентов, а затем используя setSize() и setLocation() для позиционирования этих компонентов в соответствии с правилами компоновки.

Например, BorderLayout пытается сделать границы своей северной области равными предпочтительному размеру своего северного компонента --- они могут оказаться больше или меньше этого, в зависимости от размера JFrame, размера других компонентов. в макете и так далее.

person Sbodd    schedule 23.11.2009
comment
Я думал, что компонент использует менеджер компоновки по умолчанию (BorderLayout?), поэтому, если я явно не устанавливаю менеджер компоновки, означает ли это, что я должен использовать setSize() вместо setPreferredSize()? - person David Robles; 23.11.2009
comment
Я считаю, что JPanels используют BorderLayout по умолчанию, но JComponent не имеет макета по умолчанию. В большинстве случаев вам лучше установить менеджер компоновки, если вы будете что-то добавлять, вместо использования setSize(). - person Sbodd; 23.11.2009
comment
Я рекомендую всегда использовать менеджер компоновки. SetSize() следует рассматривать как нечто, вызываемое менеджером компоновки, а не то, что вызываете вы. - person Kevin Day; 24.11.2009
comment
@Sbodd - JPanels по умолчанию имеют FlowLayout. JFrame.getContentPane() по умолчанию имеет BorderLayout. - person Nemi; 25.11.2009

setSize() или setBounds() можно использовать, когда менеджер компоновки не используется.

Однако, если вы используете менеджер компоновки, вы можете предоставить подсказки менеджеру компоновки, используя методы setXXXSize(), такие как setPreferredSize() и setMinimumSize() и т. д.

И убедитесь, что контейнер компонента использует менеджер компоновки, который учитывает запрошенный размер. Менеджеры FlowLayout, GridBagLayout и SpringLayout используют предпочтительный размер компонента (последние два зависят от установленных вами ограничений), но BorderLayout и GridLayout обычно этого не делают. Если вы указываете новые подсказки размера для уже видимого компонента, вам нужно вызовите для него метод revalidate, чтобы убедиться, что его иерархия сдерживания выложена снова. Затем вызовите метод перерисовки.

person Varun    schedule 23.11.2009

setSize изменит размер компонента до указанного размера.

setPreferredSize устанавливает предпочтительный размер. На самом деле компонент может не иметь такого размера в зависимости от размера контейнера, в котором он находится, или если пользователь изменил размер компонента вручную.

person Glen    schedule 23.11.2009
comment
Можете ли вы показать полный пример setPreferredSize(...). Я думаю, что это было бы полезно. - person Doug Hauf; 09.02.2014

IIRC ...

setSize устанавливает размер компонента.

setPreferredSize устанавливает предпочтительный размер. Layoutmanager попытается выделить столько места для вашего компонента.

Это зависит от того, используете ли вы менеджер компоновки или нет...

person miku    schedule 23.11.2009
comment
а что, если я добавлю две панели jpanel в jframe без явного указания менеджера компоновки для jframe? какой метод я должен использовать для установки размера jpanels? - person David Robles; 23.11.2009
comment
Панели содержимого по умолчанию используют BorderLayout (java.sun.com/docs /books/tutorial/uiswing/layout/using.html). Таким образом, панель содержимого JFrame имеет LayoutManager, поэтому setPreferredSize должен работать. - person miku; 23.11.2009
comment
Звучит хорошо, это означает, что я должен использовать setSize для JFrame и setPreferredSize для компонентов внутри - person David Robles; 23.11.2009
comment
Обычно вы используете frame.pack(), чтобы воспользоваться расчетным предпочтительным размером всех дочерних компонентов. В противном случае, если вы просто случайным образом используете frame.setSize(), то компоненты, добавленные на панель содержимого, будут расширяться/сжиматься, чтобы соответствовать доступному пространству, что означает, что предпочтительный размер каждого компонента может быть переопределен. - person camickr; 23.11.2009