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