setPreferredSize的副作用是什么?

我有包含多个面板的窗口。 我无法访问窗口代码。 (我只能修改面板的代码。)

我从面板中删除了一些组件。 窗户缩小了它的尺寸。 但窗口太小,无法正确显示所有内容。

我添加了行setPreferredSize(getPreferredSize()); 。 现在窗口大小合适。

setPreferredSize的副作用是什么?

编辑:使用BorderLayout。 哪个应该忽略getXXXSize()。 我的小组在CENTER。 不适合屏幕的面板位于NORTH。

这就是发生的事情:

  • getPreferredSize()查看之前是否设置了大小。 如果没有,该方法会向LayoutManager询问组件本身(这是您的JPanel)的首选大小,然后根据组件计算。
  • setPreferredSize(...)然后在JPanel上设置此值,并将其记忆以供日后使用。
  • 稍后您将删除JPanel的一些组件。
  • 即使以后,当窗口尝试重新布局时(或被告知这样做),窗口(或contentpane的/ RootPane的/ …)Layoutmanager再次调用JPanel的getPreferredSize()方法。
  • 现在, getPreferredSize()不会询问JPanel的LayoutManager,而只返回先前由setPreferredSize()设置的存储大小。

对于宽度,BorderLayout忽略了NORTH和South组件的首选宽度,它只考虑CENTER,EAST和WEST。 (同样适用于身高)。

我刚刚看了一下BorderLayout.preferredLayoutSize的实现(在Sun的1.6.0_13中),它的工作原理如下:

宽度计算为

 max( EAST.width + CENTER.width + WEST.width + h-gaps, NORTH.width, SOUTH.width ) + insets 

高度计算为

 max( EAST.height, CENTER.height, WEST.height) + NORTH.height + SOUTH.height + v-gaps + insets 

(每个width / height是这些组件的preferredSize的值。)如果缺少五个组件中的一些,则不包括它们的高度/宽度,也不包括间隙。)

它对minimalLayoutSize工作方式相同,而maximumLayoutSize只返回Integer.MAX_VALUE

因此,原则上它应该开箱即用。

但一般来说,如果窗口的布局不在您的控制之下,您不必担心不受您控制的组件被切断:-)

是的 ,它有很多影响。 效果取决于

  1. 正在使用的布局管理器
  2. 设置首选大小的组件。

主要原因是,一旦调用setPreferredSize()来设置大小,组件将不再要求ui获得首选大小。 理想情况下,只有组件的ui委托知道组件的理想pref大小。 一旦你自己设置了pref大小,就不会查询ui的pref大小。

为清楚起见,请参阅Jcomonent.getPreferredSize()代码:

  if (isPreferredSizeSet()) { return super.getPreferredSize(); } Dimension size = null; if (ui != null) { size = ui.getPreferredSize(this); } 

现在为什么它依赖于布局管理器,因为只有一些布局调用(使用) getPreferredSize()进行计算。 例如,flowlayout使用pref大小但边框布局不

方法setPreferredSize()是无副作用的。

Suraj Chandran描述了getPreferredSize()的工作原理。

PaŭloEbermann解释了为什么setPreferredSize(getPreferredSize())有效。