在上篇文章中我们介绍了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的子类,谢谢大家