自定义布局管理器, setSize和setPreferredSize的区别

转自: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();
}

}



你可能感兴趣的:(JAVA)