在上篇文章中我们介绍了swt的四大布局,通过代码我们可以发现4种布局都是继承与一个Layout抽象父类,那我们是不是可以自己通过继承Layout写一个属于自己的布局呢,答案是肯定, 下面我来介绍一个自己写布局,BorderLayout 此布局一次至多现实5个子控件,分别指定,top bottom left right center control 来完成布局下面是其源码
public class BorderLayout extends Layout {
public int marginWidth = 0;
public int marginHeight = 0;
public Control topControl;
public Control bottomControl;
public Control rightControl;
public Control leftControl;
public Control centerControl;
Point computeSize (Control control, boolean flushCache) {
int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT;
return control.computeSize (wHint, hHint, flushCache);
}
@Override
protected Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
int topHeight=0;
int bottomHeight=0;
int centerHeight=0;
int leftWidth=0;
int centerWidth=0;
int rightWidth=0;
if(topControl!=null){
Point size = computeSize(topControl, flushCache);
topHeight=size.y;
centerWidth=Math.max(size.x, centerWidth);
}
if(centerControl!=null){
Point size= computeSize(centerControl, flushCache);
centerHeight=Math.max(size.y,centerHeight);
centerWidth=Math.max(size.x, centerWidth);
}
if(leftControl!=null){
Point size= computeSize(leftControl, flushCache);
centerHeight=Math.max(size.y,centerHeight);
leftWidth=size.x;
}
if(rightControl!=null){
Point size= computeSize(rightControl, flushCache);
centerHeight=Math.max(size.y,centerHeight);
rightWidth=size.x;
}
if(bottomControl!=null){
Point size= computeSize(bottomControl, flushCache);
bottomHeight=size.y;
centerWidth=Math.max(size.x, centerWidth);
}
int height=topHeight+centerHeight+bottomHeight+2 * marginWidth;
int width=leftWidth+centerWidth+rightWidth+2 * marginHeight;
if (wHint != SWT.DEFAULT) width = wHint;
if (hHint != SWT.DEFAULT) height = hHint;
return new Point(width, height);
}
@Override
protected boolean flushCache(Control control) {
// TODO Auto-generated method stub
return true;
}
@Override
protected void layout(Composite composite, boolean flushCache) {
Rectangle rect = composite.getClientArea();
rect.x += marginWidth;
rect.y += marginHeight;
rect.width -= 2 * marginWidth;
rect.height -= 2 * marginHeight;
if(topControl!=null){
Point size = computeSize(topControl, flushCache);
Rectangle top_rect=new Rectangle(rect.x+(rect.width-size.x)/2 ,rect.y, size.x,size.y);
topControl.setBounds(top_rect);
}
if(centerControl!=null){
Point size= computeSize(centerControl, flushCache);
Rectangle center_rect=new Rectangle(rect.x+(rect.width-size.x)/2 ,rect.y+(rect.height-size.y)/2, size.x,size.y);
centerControl.setBounds(center_rect);
}
if(leftControl!=null){
Point size= computeSize(leftControl, flushCache);
Rectangle left_rect=new Rectangle(rect.x ,rect.y+(rect.height-size.y)/2, size.x,size.y);
leftControl.setBounds(left_rect);
}
if(rightControl!=null){
Point size= computeSize(rightControl, flushCache);
Rectangle right_rect=new Rectangle(rect.x+rect.width-size.x ,rect.y+(rect.height-size.y)/2, size.x,size.y);
rightControl.setBounds(right_rect);
}
if(bottomControl!=null){
Point size= computeSize(bottomControl, flushCache);
Rectangle bottom_rect=new Rectangle(rect.x+(rect.width-size.x)/2 ,rect.y+(rect.height-size.y), size.x,size.y);
bottomControl.setBounds(bottom_rect);
}
}
}
在下面是其应用代码:
BorderLayout bl=new BorderLayout();
shell.setLayout(bl);
Button top_b=new Button(shell,SWT.PUSH);
top_b.setText("top");
bl.topControl=top_b;
Button bottom_b=new Button(shell,SWT.PUSH);
bottom_b.setText("bottom");
bl.bottomControl=bottom_b;
Button left_b=new Button(shell,SWT.PUSH);
left_b.setText("left");
bl.leftControl=left_b;
Button right_b=new Button(shell,SWT.PUSH);
right_b.setText("right");
bl.rightControl=right_b;
Button center_b=new Button(shell,SWT.PUSH);
center_b.setText("center");
bl.centerControl=center_b;
接下来是其UI效果图
其实在swt库中,还有很多其他layout只是用的比较少,现在我在为大家介绍一种我在实际情况中用的比较多的一个:StackLayout
此布局一次只能显示一个子控件,通过它的一个属性topControl 用此我们可以做一个类似卡片一样的控件,通过点击它显示的子控件,来更换控件,下面是具体代码:
StackLayout sl=new StackLayout();
shell.setLayout(sl);
for(int i=0;i<5;i++){
Button b=new Button(shell,SWT.PUSH);
b.setText("button"+i);
b.setData(i);
if(i==0){
sl.topControl=b;
}
b.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
// TODO Auto-generated method stub
for(Control c:shell.getChildren()){
int index=(int) b.getData();
if(index<4){
index++;
if(index==(int)c.getData()){
sl.topControl=c;
shell.layout();
break;
}
}else{
if(0==(int)c.getData()){
sl.topControl=c;
shell.layout();
break;
}
}
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
}
窗口刚打开效果如图:
按钮点击一下的效果如下,以此类推
想要知道更多swt库中以后的布局,可以查询Layout的子类,谢谢大家