转自:http://hi.baidu.com/fcansvwdktkluyr/item/7fbb4ddf45893f3f48e1ddda
setPreferredSize用于布局管理器。
在使用布局管理器的时候,可以不使用setSize(),因为布局管理器会自动调用组件的setSize方法设置组件的大小。即使用户调用setSize方法设置组件大小,最终可能被覆盖。参照下面的布局管理器了解被覆盖的过程。
下面给出一个简单的布局管理器CenterLayout(将容器中的组件(最多只能有一个可见)居中显示)
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.io.Serializable;
public class CenterLayout implements LayoutManager, Serializable {
@Override
public void addLayoutComponent(String name, Component comp) {
}
// 将组件compont, 在父容器中居中显示
private void center(Container parent, Component component) {
Dimension parentDimension = parent.getPreferredSize();
Dimension d = component.getPreferredSize();
int x = (parentDimension.width - d.width) / 2;
if (x < 0) {
x = 0;
}
int y = (parentDimension.height - d.height) / 2;
if (y < 0) {
y = 0;
}
component.setLocation(x, y);
}
// 返回并集
private Dimension union(Dimension d, Dimension d2) {
return new Dimension(Math.max(d.width, d2.width), Math.max(
d.height, d2.height));
}
@Override
public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
Component[] components = parent.getComponents();
// 最多只能有一个组件是可见的
for (Component component : components) {
if (component.isVisible()) {
center(parent, component);
// 这句不能少,否则组件不能显示,除非组件调用过setSize。
//这句覆盖了用户之前调用的setSize方法。
component.setSize(component.getPreferredSize());
break;
}
}
}
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(0, 0);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
Component[] components = parent.getComponents();
// 最多只能有一个组件是可见的
for (Component component : components) {
if (component.isVisible()) {
// 不能调用parent.getPreferredSize(),否则导致死循环
return union(parent.getSize(), component.getPreferredSize());
}
}
}
// 不能调用parent.getPreferredSize(),否则导致死循环
return parent.getSize();
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public String toString() {
return getClass().getName();
}
}