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