I have window containing multiple panels. I don't have access to window code. (I can modify only panel’s code.)
I removed few components from panel. Window has shrunk its size. But window is too small to display everything correctly.
I added line setPreferredSize(getP开发者_如何转开发referredSize());
. Now window have right size.
What are side effects of setPreferredSize?
Edit: BorderLayout is used. Which should ignore getXXXSize(). My panel is in CENTRE. Panel which doesn't fit the screen is on NORTH.
This is what is happening:
getPreferredSize()
looks whether the size was set before. If not, the method asks the LayoutManager of the component itself (which is your JPanel) about the preferred size, which is then calculated from the components.setPreferredSize(...)
then sets this value on the JPanel, memorizing it for later.- Later you remove some components of the JPanel.
- Even later, when the window tries to re-layout itself (or is told to do so), the window's (or contentpane's/RootPane's/...) Layoutmanager calls your JPanel's
getPreferredSize()
method again. - now
getPreferredSize()
does not ask the JPanel's LayoutManager, but simply returns the stored size previously set bysetPreferredSize()
.
For width, the BorderLayout is ignoring the preferred width of the NORTH and south component, it only takes CENTER, EAST and WEST into account. (Similarly for height).
I just took a look at the implementation of BorderLayout.preferredLayoutSize
(in 1.6.0_13 from Sun), and it works like this:
The width is calculated as
max( EAST.width + CENTER.width + WEST.width + h-gaps,
NORTH.width, SOUTH.width ) + insets
The height is calculated as
max( EAST.height, CENTER.height, WEST.height)
+ NORTH.height + SOUTH.height + v-gaps + insets
(Each of the width
/height
are the values of the preferredSize
of these components.)
If some of the five components are missing, their height/width is not included, neither are the gaps.)
It works the same for minimalLayoutSize
, while maximumLayoutSize
simply returns Integer.MAX_VALUE
.
So, in principle it should work out of the box.
But in general, if the layout of the window is not under your control, you should not have to worry about components not under your control being cut off :-)
Yes, it has a lot of effect. The effect depends on
- the layout manager in use
- component on which the preferred size is set.
The main reason is that once you call setPreferredSize() to set the size, the component will no more ask ui to get the prefered size. Ideally, only the ui delegate of your component knows the ideal pref size of the component. Once you set the pref size yourself, the ui will not be queried for pref size.
For clarity see the Jcomonent.getPreferredSize() code:
if (isPreferredSizeSet()) { return super.getPreferredSize(); } Dimension size = null; if (ui != null) { size = ui.getPreferredSize(this); }
Now why does it depend on layout-manager, because only some layouts call(use) getPreferredSize() for computation. For e.g flowlayout uses pref size but border layout doesnt
Method setPreferredSize() is side effect free.
How getPreferredSize() works was described by Suraj Chandran.
Why setPreferredSize(getPreferredSize()) worked is explained by Paŭlo Ebermann.
精彩评论