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

105

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

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

Дэвид Роблес
источник

Ответы:

116

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

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

Этот setSize()метод, вероятно, ничего не сделает, если родительский компонент компонента использует диспетчер компоновки; места это, как правило , имеют эффект будет на компоненты верхнего уровня ( JFrameс и JWindowс) и вещи, которые внутри прокручивается панелей. Вы также должны вызвать, setSize()если у вас есть компоненты внутри родителя без диспетчера компоновки.

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

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

Sbodd
источник
1
Я думал, что компонент по умолчанию использует диспетчер макета (BorderLayout?), Поэтому, если я явно не устанавливаю диспетчер макета, означает ли это, что я должен использовать setSize () вместо setPreferredSize ()?
Дэвид Роблес
3
Я считаю, что JPanels по умолчанию использует BorderLayout, но у JComponent нет макета по умолчанию. В большинстве случаев вам лучше установить диспетчер компоновки, если вы будете что-то добавлять, вместо использования setSize ().
Sbodd
8
Я рекомендую всегда использовать менеджер по расположению. SetSize () следует рассматривать как что-то, что вызывает диспетчер компоновки, а не то, что вы вызываете.
Кевин Дэй,
8
@Sbodd - JPanels по умолчанию имеют FlowLayout. JFrame.getContentPane () по умолчанию имеет BorderLayout.
Nemi
10

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

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

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

Варун
источник
5

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

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

Glen
источник
Можете ли вы показать полный пример setPreferredSize (...). Думаю, это было бы полезно.
Дуг Хауф
4

IIRC ...

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

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

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

мику
источник
и что, если я добавлю две панели jpanel в jframe, не указав явно диспетчер компоновки для jframe? какой метод я должен использовать для установки размера панелей?
Дэвид Роблес
3
Панели содержимого по умолчанию используют BorderLayout ( java.sun.com/docs/books/tutorial/uiswing/layout/using.html ). Итак, в панели содержимого JFrame есть LayoutManager, поэтому setPreferredSize должен работать ..
miku
Звучит хорошо, это означает, что я должен использовать setSize для JFrame и setPreferredSize для компонентов внутри
Дэвид Роблес,
1
Обычно вы используете frame.pack (), чтобы воспользоваться рассчитанным предпочтительным размером всех дочерних компонентов. В противном случае, если вы просто случайным образом используете frame.setSize (), тогда компоненты, добавленные на панель содержимого, будут расширяться / сжиматься, чтобы соответствовать доступному пространству, что означает, что предпочтительный размер каждого компонента может быть переопределен.
camickr