|
![]() |
名片设计 CorelDRAW Illustrator AuotoCAD Painter 其他软件 Photoshop Fireworks Flash |
|
Java布局治理器深入讨论 5/23/2001 16:59:54・ 刘之佑・yesky -------------------------------------------------------------------------------- 我们都知道,java的GUI界面定义是由awt类和swing类来完成的。它在布局治理上面采用了容器和布局治理分离的方案。也就是说,容器只管将其他小件放入其中,而不管这些小件是如何放置的。对于布局的治理交给专门的布局治理器类(LayoutManager)来完成。 其实,java在GUI方面应该是并不成功的。Awt类和swing类的结构异常复杂,加上充斥其间的子类继续和接口实现,使得要想把握这两个类异常困难。这也是很多的java程序员抱怨的事情,但GUI已经成了程序发展的方向,所以这里我们也得勉为其难了。 现在我们来看java中布局治理器的详细实现。我们前面说过,java中的容器类(Container),它们只管加入小件(Meta),也就是说,它只使用自己的add()方式向自己内部加入小件。同时他记录这些加入其内部的小件的个数,可以通过container.getComponentCount()方式类获得小件的数目,通过container.getComponent(i)来获得相应小件的句柄。然后LayoutManager类就可以通过这些信息来实际布局其中的小件了。 java已经为我们提供了几个常用的布局治理器类,例如:BorderLayout、FlowLayout、GridBagLayout等等。但在实际的布局上,我们还是会有其他的需要。我在不久前的一个问题中曾经要一个垂直的流式布局,我称之为VflowLayout,其实BoxLayout和GridBagLayout可以完成类似的工作,但前者是swing类的成员,我的客户端是一个applet,不能使用,而后者必须在类生成的时候指定列数,而失去了灵活性,所以我决定重写一个自己的布局治理器来实现。经过分析,所有的LayoutManager都要实现一个接口,就是LayoutManager Inerface或者是他的一个子接口LayoutManager2 Interface,后者用于复杂的布局治理,例如GridCardLayout。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; file://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); } } 大家可以试一下。 返回类别: 教程 上一教程: Java入门笔记5_非常 下一教程: Sitemesh学习[1] 您可以阅读与"Java布局治理器深入讨论"相关的教程: · 离开Java布局治理器 · Java中非常机制的深入研究 · Java源码分析:深入探讨Iterator模式 · 深入浅出基于Java的解释器设计模式 · 关于java非常处理机制的深入理解 |
![]() ![]() |
快精灵印艺坊 版权所有 |
首页![]() ![]() ![]() ![]() ![]() ![]() ![]() |