/*
2009年2月17日17:21:43
有关布局管理器的问题
*/import java.awt.Frame;
import java.awt.Panel;
import java.awt.Color;
import java.awt.FlowLayout;public class TestFrameWithPanel{
public static void main(String args[]) {
Frame f = new Frame("MyTest");
Panel pan = new Panel();
pan.setLayout(null);  //注释掉本语句则14行语句不起作用, 如果不被注释掉,则输出结果中pan尺寸就是(200, 200),即14行语句生效,为什么
f.setSize(500,500);
f.setBackground(Color.cyan);
f.setLayout(new FlowLayout()); 
pan.setSize(200, 200);  //14行
pan.setBackground(Color.green);
f.add(pan);
pan.setLocation(40,40);
f.setLocation(300,300);
f.setVisible(true);
}
}
/*
问题:
布局管理器决定的不是该组件内部组件的大小和位置么?
假设Frame 对象f已经指定了布局管理器,请问我们还能不能指定f内部组件的大小和位置?
我觉得不可以,按道理讲我觉得本程序中pan的大小是应该有f对象的布局管理器决定的,
但是本程序的运行结果却是:
当我们指定了f的布局管理器时,如果pan含有布局管理器,则pan大小无法自己设置,
如果pan没有指定布局管理器,则pan大小可以自己设置
难道pan自己的布局管理器还可以决定自己本身大小的尺寸么?

请诸位高手指教,小弟不甚感谢!!!!!!!!
*/

解决方案 »

  1.   

    因为Frame默认布局管理器是BorderLayout
    回答完毕
    快给分啊
      

  2.   

    因为Frame默认布局管理器是BorderLayout 
    回答完毕 
    快给分啊 -------------------------------
    看来老兄没有仔细看我的问题啊
      

  3.   

    其实你只是描述的事情的一部分
    试一下这样,在f使用不同的layout的情况下(默认的BorderLayout/set为FlowLayout/set为null),
    pan有/无layout的显示情况然后,能得出什么样的结果呢?
      

  4.   

    如果给f和pan里面分别再添加一个控件,比如Button,
    pan.add(new Button("TEST"));
    f.add(new Button("TEST2"));
    再试一下就比较明显了
      

  5.   

    布局管理器就是管理容器中控件的布局的,关于控件的大小则与容器和自身的布局都有关系,有些布局管理器则会强制设定组件的大小(比如BorderLayout),而且大都布局管理器都这样,而与其他布局管理器不同,FlowLayout布局管理器并不强行设定组件的大小,而是允许组件拥有它们自己所希望的尺寸。而且,要想设定一个控件的大小,不但容纳它的容器不能强制限制大小而且这个控件最好也是null布局的。所以当你有这句 pan.setLayout(null)时,panel就可以自己设定自己的大小,但没那句时,frame的flowlayout就会起作用了,所以有没有14行都没作用了,其实后面设定位置的也没作用了,panel仅仅受frame容器布局的控制了。(至于为什么这样,感觉是容器重叠导致的)
    总之,要想随意设定一个容器中控件的大小,最后容器的布局选为null,这样控件的大小和位置才好自由设置,而控件中的控件的布局也是这个道理
      

  6.   


    pane.setLayout(null);
    //先将布局管理器设置为空,什么含义呢?就是可以自定义了。
    //-------------以下结论为本人收藏多年的-----------
    //LayoutManager有五个方法需要实现,分别是:
    1、public void addLayoutComponent(String name, Component comp); 2、public void removeLayoutComponent(Component comp); 3、public Dimension preferredLayoutSize(Container container); 4、public Dimension minimUMLayoutSize(Container container); 5、public void layoutContainer(Container container); 
    第一个方法其实就是你在使用container.add(String name,component comp);时调用的方法,例如BorderLayout为布局管理器时。但在FlowLayout中由于没有其他的附加信息,所以不需要填充这个方法。相应的第二个方法也就不需要填充了。真正核心的方法是第三个和第五个方法,前者是最终确定Container有多大的,而后者就是决定Container中各个小件的实际位置的了。也就是说,当我们用container.setLayout(LayoutManager)后,再加入小件后,最后系统做的工作其实是LayoutManager. layoutContainer(container);和container.setSize(LayoutManager. PreferredLayoutSize(container));。下面是我的新类:VflowLayout。 
    package render_account; import java.awt.*; 
    import java.io.*; public class VFlowLayout implements LayoutManager,Serializable{ int hgap; 
    int vgap; public VFlowLayout(){ 
    this(5,5); 
    } public VFlowLayout(int i,int j){ 
    this.hgap=i; 
    this.vgap=j; 
    } public void addLayoutComponent(String name, Component comp){ } public void removeLayoutComponent(Component comp){ } public Dimension preferredLayoutSize(Container container){ 
    synchronized(container.getTreeLock()){ 
    Dimension dimension1=new Dimension(0,0); 
    int i=container.getComponentCount(); 
    for(int j=0;j Component component = container.getComponent(j); 
    if(component.isVisible()){ 
    Dimension dimension2=component.getPreferredSize(); 
    dimension1.width=Math.max(dimension1.width,dimension2.width); 
    if(j>0) 
    dimension1.height+=vgap; 
    dimension1.height+=dimension2.height; 


    Insets insets=container.getInsets(); 
    dimension1.height+=insets.top+insets.bottom+vgap*2; 
    dimension1.width+=insets.left+insets.right+hgap*2; 
    Dimension dimension=dimension1; 
    return dimension; 
    //return(new Dimension(50,200)); 

    } public Dimension minimumLayoutSize(Container container){ 
    synchronized(container.getTreeLock()){ 
    Dimension dimension1=new Dimension(0,0); 
    int i=container.getComponentCount(); 
    for(int j=0;j Component component = container.getComponent(j); 
    if(component.isVisible()){ 
    Dimension dimension2=component.getMinimumSize(); 
    dimension1.width=Math.max(dimension1.width,dimension2.width); 
    if(j>0) 
    dimension1.height+=vgap; 
    dimension1.height+=dimension2.height; 


    Insets insets=container.getInsets(); 
    dimension1.height+=insets.top+insets.bottom+vgap*2; 
    dimension1.width+=insets.left+insets.right+hgap*2; 
    Dimension dimension=dimension1; 
    return dimension; 

    } public void layoutContainer(Container container){ 
    synchronized(container.getTreeLock()){ 
    Insets insets=container.getInsets(); 
    int vSpace=container.getSize().height-(insets.top+insets.bottom+vgap*2); 
    int componentCount=container.getComponentCount(); 
    int left=insets.left+hgap; 
    int totalHeight=0; 
    int width=0; 
    int componentStart=0; 
    for(int i=0;i Component component=container.getComponent(i); 
    if(component.isVisible()){ 
    Dimension dimension=component.getPreferredSize(); 
    component.setSize(dimension.width,dimension.height); 
    if(totalHeight==0 || totalHeight+dimension.height<=vSpace){ 
    if(totalHeight>0) 
    totalHeight+=vgap; 
    totalHeight+=dimension.height; 
    width=Math.max(width,dimension.width); 
    }else{ 
    moveComponents(container,insets.top+vgap,left,width,componentStart,i); 
    totalHeight=0; 
    left+=hgap+width; 
    width=dimension.width; 
    componentStart=i; 



    moveComponents(container,insets.top+vgap,left,width,componentStart,componentCount); 

    } private void moveComponents(Container container,int top,int left,int width,int componentStart,int componentEnd){ 
    synchronized(container.getTreeLock()){ 
    for(int i=componentStart;i Component component=container.getComponent(i); 
    if(component.isVisible()){ 
    component.setLocation(left,top); 
    top+=component.getPreferredSize().height+vgap; 



    } public void setHgap(int i){ 
    this.hgap=i; 
    } public void setVgap(int i){ 
    this.vgap=i; 
    } public int getHgap(){ 
    return(this.hgap); 
    } public int getVgap(){ 
    return(this.vgap); } }