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
上一篇