Java布局管理器深入讨论(转)

  我们都知道,java GUI的界面定义是由awt类和swing类来完成的。它在布局管理上面采用了容器和布局管理分离的方案。也就是说,容器只管将其他小件放入其中,而不管这些小件是如何放置的。对于布局的管理交给专门的布局管理器类(LayoutManager)来完成。      其实,java在GUI方面应该是并不成功的.Awt类和swing类的结构非常复杂,加上充斥其间的子类继承和接口实现,使得要想掌握这两个类非常困难。这也是很多的java程序员抱怨的事情,但GUI已经成了程序发展的方向,所以这里我们也得勉为其难了。      现在我们来看java中布局管理器的具体实现。我们前面说过,java中的容器类(容器),它们只管加入小件(元),也就是说,它只使用自己的添加()方法向自己内部加入小件。同时他记录这些加入其内部的小件的个数,可以通过container.getComponentCount()方法类获得小件的数目,通过container.getComponent (i)来获得相应小件的句柄,然后LayoutManager类就可以通过这些信息来实际布局其中的小件了。      java已经为我们提供了几个常用的布局管理器类,例如:BorderLayout, FlowLayout, GridBagLayout等等。但在实际的布局上,我们还是会有其他的需要。我在不久前的一个问题中曾经要一个垂直的流式布的局,我称之为VflowLayout,其实BoxLayout和GridBagLayout可以完成类似的工作,但前者是swing类的成员,我的客户端是一个applet,不能使用,而后者必须在类生成的时候指定列数,而失去了灵活性,所以我决定重写一个自己的布局管理器来实现。经过分析,所有的LayoutManager都要实现一个接口,就是LayoutManager交互或者是他的一个子接口LayoutManager2接口,后者用于复杂的布局管理,例如GridCardLayout.LayoutManager有五个方法需要实现,分别是:      1、公共空addLayoutComponent(字符串名称、组件comp);      2、公共空removeLayoutComponent comp(组件);      3、公共维度preferredLayoutSize(容器容器);      4、公共维度minimumLayoutSize(容器容器);      5、公共空layoutContainer(容器容器);      第一个方法其实就是你在使用容器。添加(comp字符串名称、组件);时调用的方法,例如BorderLayout为布局管理器时。但在FlowLayout中由于没有其他的附加信息,所以不需要填充这个方法。相应的第二个方法也就不需要填充了。真正核心的方法是第三个和第五个方法,前者是最终确定容器有多大的,而后者就是决定容器中各个小件的实际位置的了。也就是说,当我们用container.setLayout (LayoutManager)后,再加入小件后,最后系统做的工作其实是LayoutManager。layoutContainer(容器);和container.setSize (LayoutManager。PreferredLayoutSize(容器));。      下面是我的新类:VflowLayout。   包render_account;      进口java.awt。*;   进口. io . *;      公共类VFlowLayout实现LayoutManager Serializable {      int hgap;   int vgap;      公共VFlowLayout () {   (5);   }      公共VFlowLayout (int, int j) {   this.hgap=我;   this.vgap=j;   }      公共空间addLayoutComponent (comp字符串名称、组件){      }      公共空间removeLayoutComponent comp(组件){      }      公共维度preferredLayoutSize(容器容器){   同步(container.getTreeLock ()) {   维dimension1=新维度(0,0);   int i=container.getComponentCount ();   for (int j=0; j=container.getComponent组件组件(j);   如果(component.isVisible ()) {   维dimension2=component.getPreferredSize ();   dimension1.width=Math.max (dimension1.width dimension2.width);   如果(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;   维维=dimension1;   返回维度;   文件://返回(新维度(50200));   }   }      公共维度minimumLayoutSize(容器容器){   同步(container.getTreeLock ()) {   维dimension1=新维度(0,0);   int i=container.getComponentCount ();   for (int j=0; j=container.getComponent组件组件(j);   如果(component.isVisible ()) {   维dimension2=component.getMinimumSize ();   dimension1.width=Math.max (dimension1.width dimension2.width);   如果(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;   维维=dimension1;   返回维度;   }   }      公共空间layoutContainer(容器容器){   同步(container.getTreeLock ()) {   Insets Insets=container.getInsets ();   int vSpace=container.getSize () .height (insets.top + insets.bottom + vgap * 2);   int componentCount=container.getComponentCount ();   int左=insets.left + hgap;   int totalHeight=0;   int宽度=0;   int componentStart=0;   (int i=0;我组件组件=container.getComponent(我);   如果(component.isVisible ()) {   维维=component.getPreferredSize ();   component.setSize (dimension.width dimension.height);   如果(totalHeight==0 | | totalHeight + dimension.height0)   totalHeight +=vgap;   totalHeight +=dimension.height;   宽度=Math.max(宽度、dimension.width);   其他}{   moveComponents(容器,insets.top + vgap,左,宽度,componentStart, i);   totalHeight=0;   左+=hgap +宽度;   宽度=dimension.width;   componentStart=我;   }   }   }   moveComponents(容器,insets.top + vgap,左,宽度,componentStart, componentCount);   }   }      私人空间moveComponents(容器容器,int, int, int宽度,int componentStart, int componentEnd) {   同步(container.getTreeLock ()) {   for (int i=componentStart;我组件组件=container.getComponent(我);   如果(component.isVisible ()) {   component.setLocation(左前);   前+=component.getPreferredSize () .height + vgap;   }   }   }   }      公共空间setHgap (int i) {   this.hgap=我;   }      公共空间setVgap (int i) {   this.vgap=我;   }      公共int getHgap () {   返回(this.hgap);   }      公共int getVgap () {   返回(this.vgap);   }   }      大家可以试一下。[@more@]

Java布局管理器深入讨论(转)