gr8vyguy@Blogjava

SWT中模拟AWT的BorderLayout

BorderLayout JFrame 的默认布局类,相信大家都用过,SWT没有提供这个Java程序员非常熟悉的Layout类。我们怎们来自己定义一个呢?首先要稍微了解一下Layout的内部实现原理。

borderlayout.jpg

Layouts 是一个容器用来对其子成员布局的一个算法,符合 Strategy Design Pattern . SWT 打开一个 Composite 时,会调用 Composite 里的 layout.computeSize() 计算 Composite 的大小,然后再调 layout.layout() 设置子成员的位置和大小 . 如果需要, layout 会调用子成员的 getLayoutData() 来获得单个子成员特别的属性。

computeSize()
layout() 是抽象类 Layout 的两个抽象方法。

要定义一个新的 layout ,也就是要定义一个 Layout 的子类, 实现 computeSize layout. BorderLayout 来说,我们需要区分子控件是在哪个位置的 , WEST 的,还是 EAST 的,还是 CENTER 的,这个属性通过 Control.setLayoutData() 方法保存的各个控件里。

废话少说了,先看源代码

public   class  BorderLayout  extends  Layout {
    
private  Control north;
    
private  Control south;
    
private  Control east;
    
private  Control west;
    
private  Control center;

    
protected   void  getControls(Composite composite) {
        Control[] children  =  composite.getChildren();
        
for  ( int  i  =   0 , n  =  children.length; i  <  n; i ++ ) {
            Control child 
=  children[i];
            BorderData borderData 
=  (BorderData) child.getLayoutData();
            
if  (borderData  ==  BorderData.NORTH)
                north 
=  child;
            
else   if  (borderData  ==  BorderData.SOUTH)
                south 
=  child;
            
else   if  (borderData  ==  BorderData.EAST)
                east 
=  child;
            
else   if  (borderData  ==  BorderData.WEST)
                west 
=  child;
            
else
                center 
=  child;
        }
    }
}

Control的Layout Data可以用Control.setLayoutData()方法设定, 所以getControl()方法找着各个控件的相应位置。

     protected  Point computeSize(Composite composite,  int  wHint,  int  hHint,
            
boolean  flushCache) {
        getControls(composite);
        
int  width  =   0 , height  =   0 ;

        width  +=  west  ==   null   ?   0  : getSize(west, flushCache).x;
        width 
+=  east  ==   null   ?   0  : getSize(east, flushCache).x;
        width 
+=  center  ==   null   ?   0  : getSize(center, flushCache).x;

        
if  (north  !=   null ) {
            Point pt 
=  getSize(north, flushCache);
            width 
=  Math.max(width, pt.x);
        }
        
if  (south  !=   null ) {
            Point pt 
=  getSize(south, flushCache);
            width 
=  Math.max(width, pt.x);
        }

        height  +=  north  ==   null   ?   0  : getSize(north, flushCache).y;
        height 
+=  south  ==   null   ?   0  : getSize(south, flushCache).y;

        
int  heightOther  =  center  ==   null   ?   0  : getSize(center, flushCache).y;
        
if  (west  !=   null ) {
            Point pt 
=  getSize(west, flushCache);
            heightOther 
=  Math.max(heightOther, pt.y);
        }
        
if  (east  !=   null ) {
            Point pt 
=  getSize(east, flushCache);
            heightOther 
=  Math.max(heightOther, pt.y);
        }
        height 
+=  heightOther;

         return   new  Point(Math.max(width, wHint), Math.max(height, hHint));
    }

computeSize计算Composite所需的大小。

     protected   void  layout(Composite composite,  boolean  flushCache) {
        getControls(composite);
        Rectangle rect 
=  composite.getClientArea();
        
int  left  =  rect.x, right  =  rect.width, top  =  rect.y, bottom  =  rect.height;
        
if  (north  !=   null ) {
            Point pt 
=  getSize(north, flushCache);
            north.setBounds(left, top, rect.width, pt.y);
            top 
+=  pt.y;
        }
        
if  (south  !=   null ) {
            Point pt 
=  getSize(south, flushCache);
            south.setBounds(left, rect.height 
-  pt.y, rect.width, pt.y);
            bottom 
-=  pt.y;
        }
        
if  (east  !=   null ) {
            Point pt 
=  getSize(east, flushCache);
            east.setBounds(rect.width 
-  pt.x, top, pt.x, (bottom  -  top));
            right 
-=  pt.x;
        }
        
if  (west  !=   null ) {
            Point pt 
=  getSize(west, flushCache);
            west.setBounds(left, top, pt.x, (bottom 
-  top));
            left 
+=  pt.x;
        }
        
if  (center  !=   null ) {
            center.setBounds(left, top, (right 
-  left), (bottom  -  top));
        }
    }

而layout方法让控件们各归其位。整个布局调用是回归的。

完整的代码borderlayout.rar

上一篇

posted on 2007-02-20 23:18 gr8vyguy 阅读(3324) 评论(1)  编辑  收藏 所属分类: Java

评论

# re: SWT中模拟AWT的BorderLayout 2007-02-22 06:06 BeanSoft

支持一下, 最近也在苦学 SWT, 实现一个自己用的资料管理软件, 哥们真是好人!  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2007年2月>
28293031123
45678910
11121314151617
18192021222324
25262728123
45678910

导航

统计

公告

  • 转载请注明出处.
  • msn: gr8vyguy at live.com
  • 常用链接

    留言簿(9)

    随笔分类(68)

    随笔档案(80)

    文章分类(1)

    My Open Source Projects

    搜索

    积分与排名

    最新评论