標準的SWT布局類
FillLayout:在容器中以相同的大小單行或單列的排列組件
RowLayout:以單行或多行的方式使用幾個選項(fill,wrap,spacing,justify,type)定制組件的排列方式
GridLayout:類似于swing的GridLayout的方式以格子的方式排列組件
FormLayout(SWT?2.0的新特性):通過定義組件四個邊的“粘貼”位置來排列組件,被引用的相對的組件可以父組件,也可以是同一容器中的其它組件。
在SWT中,可以由用戶自定義布局類。
在簡單的布局中,使用FillLayout和RowLayout也許就夠用了,也比較簡單。但是通常的布局都比較復雜,而且要求很精確。無論復雜程度如何,都可以由GridLayout或FormLayout來完成。通常GridLayout與FormLayout可以做成同樣的效果,但是使用FormLayout更有效,不會像GridLayout產生resize導致的布局錯位,也更簡單。下面通過一個例子簡單介紹FormLayout的使用。
布局效果
布局實施1.首先定義窗口和它的空白邊
Display.getDefault().dispose();??//移去平臺核心啟動畫面
????????display?=?new?Display();
????????shell?=?new?Shell(display,?SWT.TITLE);
????????FormLayout?layout?=?new?FormLayout();
????????layout.marginHeight?=?10;
????????layout.marginWidth?=?20;
????????shell.setLayout(layout);
????????shell.setText("用戶登錄");
2.創建窗口上的元素,其中下面的兩個button由一個使用RowLayout的組件來包容。
????????name?=?new?Label(shell,?SWT.NONE);
????????name.setText("用戶名");
????????nameText?=?new?Text(shell,?SWT.SINGLE?|?SWT.BORDER);
????????pass?=?new?Label(shell,?SWT.NONE);
????????pass.setText("密碼");
????????passText?=?new?Text(shell,?SWT.SINGLE?|?SWT.BORDER);
????????passText.setEchoChar('*');
????????passText.setTabs(2);
????????bottom?=?new?Composite(shell,?SWT.NONE);
????????RowLayout?rowLayout?=?new?RowLayout();
????????rowLayout.justify?=?true;??//justify定義組件在容器中分散開,效果類似于swing的FlowLayout
????????bottom.setLayout(rowLayout);
3.定義name標簽的位置。它的頂邊離父組件(窗口shell)的空白邊距離是父組件clientArea(除空白邊以外的空間)高度(height)的15%,偏移的點數(points)為0。
FormData?data?=?new?FormData();
????????data.top?=?new?FormAttachment(15,?0);
????????name.setLayoutData(data);
4.定義name文本輸入的位置。它的頂邊在name標簽的中心位置(這不是正確的表達,但程序是這樣解釋,事實上它的中心位置與name標簽在同一條水平線上),左邊距name標簽的右邊有10個點。
data?=?new?FormData();
????????data.top?=?new?FormAttachment(name,?0,?SWT.CENTER);
????????data.left?=?new?FormAttachment(name,?10,?SWT.RIGHT);
????????nameText.setLayoutData(data);
5.定義pass標簽的位置。它的頂邊距name標簽的底邊有10個點數的偏移。
data?=?new?FormData();
????????data.top?=?new?FormAttachment(name,?10,?SWT.BOTTOM);
????????pass.setLayoutData(data);
6.定義pass文本輸入的位置。它的頂邊在name標簽的中心位置(同上),左邊與name文本框的左邊對齊。
data?=?new?FormData();
????????data.top?=?new?FormAttachment(pass,?0,?SWT.CENTER);
????????data.left?=?new?FormAttachment(nameText,?0,?SWT.LEFT);
????????passText.setLayoutData(data);
7.定義bottom組件的位置。它的頂邊距pass標簽的底邊15個點數,左邊與pass標簽的左邊對齊,右邊與pass文本輸入的右邊對齊。
????????data?=?new?FormData();
????????data.top?=?new?FormAttachment(pass,?15,?SWT.BOTTOM);
????????data.left?=?new?FormAttachment(pass,?0,?SWT.LEFT);
????????data.right?=?new?FormAttachment(passText,?0,?SWT.RIGHT);
????????bottom.setLayoutData(data);
完整的源碼import?org.eclipse.swt.SWT;
import?org.eclipse.swt.events.SelectionAdapter;
import?org.eclipse.swt.events.SelectionEvent;
import?org.eclipse.swt.graphics.Rectangle;
import?org.eclipse.swt.layout.FormAttachment;
import?org.eclipse.swt.layout.FormData;
import?org.eclipse.swt.layout.FormLayout;
import?org.eclipse.swt.layout.RowLayout;
import?org.eclipse.swt.widgets.Button;
import?org.eclipse.swt.widgets.Composite;
import?org.eclipse.swt.widgets.Display;
import?org.eclipse.swt.widgets.Label;
import?org.eclipse.swt.widgets.Shell;
import?org.eclipse.swt.widgets.Text;
import?cn.com.efly.clientframe.core.Hook;
/**
?*?@author?efly
?*?@version?1.0.0,11/22/02
?*/
public?final?class?LoginUI?{
????private?Display?display;
????private?Shell?shell;
????private?Composite?bottom;
????private?Label?name;
????private?Label?pass;
????private?Text?nameText;
????private?Text?passText;
????private?Button?ok;
????private?Button?exit;
????private?Rectangle?clientArea;
????private?RootHook?rootHook;
????public?LoginUI(Hook?hook)?{
????????rootHook?=?(RootHook)?hook;
????}
????/**
?????*?顯示登陸界面
?????*/
????public?void?show()?{
????????Display.getDefault().dispose();
????????display?=?new?Display();
????????clientArea?=?display.getClientArea();
????????shell?=?new?Shell(display,?SWT.TITLE);
????????FormLayout?layout?=?new?FormLayout();
????????layout.marginHeight?=?10;
????????layout.marginWidth?=?20;
????????shell.setLayout(layout);
????????shell.setText("用戶登錄");
????????name?=?new?Label(shell,?SWT.NONE);
????????name.setText("用戶名");
????????nameText?=?new?Text(shell,?SWT.SINGLE?|?SWT.BORDER);
????????pass?=?new?Label(shell,?SWT.NONE);
????????pass.setText("密碼");
????????passText?=?new?Text(shell,?SWT.SINGLE?|?SWT.BORDER);
????????passText.setEchoChar('*');
????????passText.setTabs(2);
????????bottom?=?new?Composite(shell,?SWT.NONE);
????????RowLayout?rowLayout?=?new?RowLayout();
????????rowLayout.justify?=?true;
????????bottom.setLayout(rowLayout);
????????ok?=?new?Button(bottom,?SWT.PUSH);
????????ok.setText("確定");
????????ok.addSelectionListener(new?SelectionAdapter()?{
????????????public?void?widgetSelected(SelectionEvent?event)?{
????????????????ok();
????????????}
????????});
????????exit?=?new?Button(bottom,?SWT.PUSH);
????????exit.setText("取消");
????????exit.addSelectionListener(new?SelectionAdapter()?{
????????????public?void?widgetSelected(SelectionEvent?event)?{
????????????????cancel();
????????????}
????????});
????????FormData?data?=?new?FormData();
????????data.top?=?new?FormAttachment(15,?0);
????????name.setLayoutData(data);
????????data?=?new?FormData();
????????data.top?=?new?FormAttachment(name,?0,?SWT.CENTER);
????????data.left?=?new?FormAttachment(name,?10,?SWT.RIGHT);
????????nameText.setLayoutData(data);
????????data?=?new?FormData();
????????data.top?=?new?FormAttachment(name,?10,?SWT.BOTTOM);
????????pass.setLayoutData(data);
????????data?=?new?FormData();
????????data.top?=?new?FormAttachment(pass,?0,?SWT.CENTER);
????????data.left?=?new?FormAttachment(nameText,?0,?SWT.LEFT);
????????passText.setLayoutData(data);
????????data?=?new?FormData();
????????data.top?=?new?FormAttachment(pass,?15,?SWT.BOTTOM);
????????data.left?=?new?FormAttachment(pass,?0,?SWT.LEFT);
????????data.right?=?new?FormAttachment(passText,?0,?SWT.RIGHT);
????????bottom.setLayoutData(data);
????????shell.pack();
????????Rectangle?shellBounds?=?shell.getBounds();
????????shell.setLocation(
????????????(clientArea.width?-?shellBounds.width)?/?2,
????????????(clientArea.height?-?shellBounds.height)?/?2);
????????shell.open();
????????while?(!shell.isDisposed())?{
????????????if?(!display.readAndDispatch())
????????????????display.sleep();
????????}
????}
????private?void?dispose()?{
????????display.dispose();
????}
????private?void?cancel()?{
????????dispose();
????}
????private?void?ok()?{
????????verify();
????}
????private?void?verify()?{
????????rootHook.runPlatform();
????}
????????public?static?void?main(String[]){
????????????????new?LoginUI(null).show();
????????}
}