SWT概述
SWT是IBM公司开发的UI开发组件,它与AWT/SWING组件类似,但是SWT克服了AWT/SWING中许多问题,所以用SWT编写UI程序无论在美观成都还是响应速度上都远远超越了AWT和SWING.这主要是因为AWT只是单纯模拟本地操作系统窗口组件,而SWT最大化了操作系统的图形构件API,也就是说只要操作系统提供了图形构件,SWT就可以利用JNI调用他们,只有操作系统中不提供的组件SWT才会去模拟实现. 由于使用了JNI,使得它和本地操作系统紧密连接在一起,因此编写的界面和本地系统窗口几乎没有区别.JFace是SWT的一个增强库,它以来SWT并将其扩展,功能强大. 目前企业级的Java开发应用都会用到这个。
调用关系:
JFaceàSWTàJNIà--à本地操作系统窗口组件
安装
下载SWT安装的Jar包(注意操作系统),也可以在eclipse的plugin目录中找到(SWT.jar),然后用WinRAR解压缩得到org.eclipse.swt.win32.win32.x86_3.4.1.v3449c.jar以及5个dll文件,如果已经配置好了JDK,那么将jar文件复制到JDK/jre/lib/ext/中,将dll文件复制到JDK/jre/bin/目录下,就完成了安装。
http://zhidao.baidu.com/question/130025979.html?fr=ala0
一、SWT程序起步
第一个SWT程序:实现了一个记事本
package swt;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import java.io.*;
public class FirstSWT {
private static String fn = "";
private static Display display;
private static Shell shell;
private static Text text;
private Button newButton;
private Button openButton;
private Button saveButton;
private Button delButton;
private Button quitButton;
public FirstSWT(){
display = new Display();
//基本对话框
shell = new Shell(display,SWT.DIALOG_TRIM);
shell.setText("Note pad");
shell.setSize(600,400);
newButton = new Button(shell,SWT.PUSH);
newButton.setLocation(2,5);
newButton.setSize(50,20);
newButton.setText("new");
openButton = new Button(shell,SWT.PUSH);
openButton.setLocation(60,5);
openButton.setSize(50,20);
openButton.setText("open");
saveButton = new Button(shell,SWT.PUSH);
saveButton.setLocation(118,5);
saveButton.setSize(50,20);
saveButton.setText("save");
delButton = new Button(shell,SWT.PUSH);
delButton.setLocation(180,5);
delButton.setSize(50,20);
delButton.setText("delete");
quitButton = new Button(shell,SWT.PUSH);
quitButton.setLocation(540,5);
quitButton.setSize(50,20);
quitButton.setText("quit");
text = new Text(shell,SWT.MULTI|SWT.BORDER|SWT.V_SCROLL|SWT.WRAP);
text.setLocation(2,30);
text.setSize(shell.getClientArea().width-4,shell.getClientArea().height-35);
newButton.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent event)
{
fn = "";
shell.setText("第一个SWT程序");
text.setText("");
}
});
openButton.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
FileDialog dlg = new FileDialog(shell,SWT.OPEN);
String fileName = dlg.open();
try{
if(fileName != null)
{
//打开指定文件
FileInputStream fis = new FileInputStream(fileName);
text.setText("");
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String s = null;
//将指定文件一行一行的加入记事本
while((s=in.readLine())!=null)
text.append(s+"/r/n");
fn = fileName;
shell.setText(fn);
MessageBox successBox = new MessageBox(shell);
successBox.setMessage("打开文件成功");
successBox.setText("信息");
successBox.open();
in.close();
}
}catch(NullPointerException en)
{
System.out.println("warning No file selected!");
}catch(Exception e)
{
MessageBox errorBox = new MessageBox(shell,SWT.ICON_ERROR);
errorBox.setText("错误");
errorBox.setMessage("打开文件失败!");
errorBox.open();
}
}
}
);
saveButton.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
try{
String fileName = null;
if(fn.equals(""))
{
FileDialog dlg = new FileDialog(shell,SWT.SAVE);
fileName = dlg.open();
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter out = new OutputStreamWriter(fos);
out.write(text.getText());
out.close();
alertMsg(shell,"创建文件成功");
if(fileName != null)
{
fn = fileName;
shell.setText(fn);
}
}else
{
FileOutputStream fos = new FileOutputStream(fn);
OutputStreamWriter out = new OutputStreamWriter(fos);
out.write(text.getText());
out.close();
}
}catch(NullPointerException en)
{
System.out.println("warning No file selected!");
}
catch(Exception e)
{
e.printStackTrace();
MessageBox errorBox = new MessageBox(shell,SWT.ICON_ERROR);
errorBox.setText("错误");
errorBox.setMessage("保存文件失败!");
errorBox.open();
}
}
});
quitButton.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
System.out.println(e.toString());
display.dispose();
}
});
shell.open();
while(!shell.isDisposed())
{
if(!display.readAndDispatch())
{
// System.out.println(display.msg.toString());
display.sleep();
}
}
System.out.println("closed");
display.dispose();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new FirstSWT();
}
public static void alertMsg(Shell shell,String msg)
{
MessageBox alertBox = new MessageBox(shell);
alertBox.setMessage(msg);
alertBox.setText("信息");
alertBox.open();
}
}
SWT程序流程
1. 创建一个Display对象
2. 创建一个或者多个Shell对象,你可以认为Shell代表了程序的窗口。
3. 在Shell内创建各种部件(widget)
4. 对各个部件进行初始化(外观,状态等),同时为各种部件的事件创建监听器(listener)
5. 调用Shell对象的open()方法以显示窗体
6. 各种事件进行监听并处理,直到程序发出退出消息
7. 调用Display对象的dispose()方法以结束程序。
可见和Swing&AWT差不多,都是一个主容器以及一系列内部容器嵌套而成。只是这里我们在组建或是容器的构造函数中就指定了其所述的父组件,不用再add了。在一个就是SWT的布局管理和Swing有所不同。
二、SWT的布局管理
主要分为:FillLayout,GridLayout,RowLayout,FormLayout,StackLayout,顾名思义吧。目前绝大多数(90%)都是GridLayout,资料甚多,不介绍了,介绍下自己感觉比较灵活的另一种FormLayout。
FormLayout formLayout = new FormLayout();
formLayout.marginHeight = 5;
formLayout.marginWidth = 5;
formLayout.spacing = 5;
//设置了边界高度和宽度以及组件间距的FormLayout
这个在原有UI组件中没有,它是一个非常灵活可控的布局方式,每一个组件在添加时候,需要设置一个构造并设置一个FormData对象,布局管理器通过对它的设置来完成布局。FromData拥有四个域top,bottom,left,right分别对应此组件的上下左右。每一个域都要构造一个FormAttachment对象来进行设置,FormAttachment构造器如下:
来看如下代码:
formData = new FormData();
formData.top = new FormAttachment(0,0);
formData.left = new FormAttachment(tabFolder,0,SWT.RIGHT);
formData.right = new FormAttachment(100,0);
formData.bottom = new FormAttachment(97,0);
channelTree.setLayoutData(formData);
这里这个Tree组件的top被设置在距离顶端0%,偏移为0个像素点的位置,当然,因为前面我们设置了组件的边界高度、宽度以及间距,所以它并不会顶格;组件的left被设置在距离tabFolder组件右边0个像素点的位置,同理因为有margin和space,两组件有至少10的距离;后面两个比较好理解,即右边界设置为整个父组件的最右边(从左往右100%)的位置,偏移为0,下边界为97%的位置。
三、SWT中的ActiveX/Com接口
SWT中,我们可以通过java代码(OLE操作)调用ActiveX组件,例如Word,Excel,WMP等,而且它们都是可控的。下面介绍下具体的引用和控制方法。
基本方法:
1. 使用SWT进行OLE操作时,所有的对OLE对象的引用都是通过OlE定义的Id获得,获得各个对象的Id方法稍后会进行说明。
2. 所有的动作都通过OleAutomation对象进行,OleAutomation可以代表任一OLE对象,如Workbook、Worksheet、Range。可以通过getProperty()方法获得它的属性,也可以用setProperty()方法为它的属性赋值
3. Variant对象一般是封装了OLE对象的值,可以通过它进行值传入及获得相应的值,也可以通过它获得OleAutomation对象。
以控制Excel表格为例介绍SWT的OLE操作:
1. 打开OLE/COM Object Viewer(VS2008自带),找到DocumentObjects,找到Microsoft Excel工作表。找到VersionIndependentProgID,也就是对应的程序中需要调用的ID值。这里是Excel.Sheet,然后写下如下代码,创建workbook
OleClientSite clientSite = new OleClientSite(oleFrame,SWT.NONE,"Excel.Sheet");
//获得Excel的workbook对象
OleAutomation workbook = new OleAutomation(clientSite);
2. 点击右键选择view type informat,找到dispinterface _Workbooks (注意:有下划线。如果使用了分类功能,在Dispinterfaces节点下),然后点击method,即查找它所包含的方法,选择sheet,找到对应方法的ID 0x000001e5
3. OleAutomation sheet = workbook.getProperty(SHEET_ID,new Variant[]{new Variant(1)}).getAutomation();获得sheet对象。这里SHEET_ID就是0x000001e5。
4. 获得worksheet对象之后,再查找worksheet的方法(dispinterface _Worksheet),找到Range,得知:这个方法是获得一组Range对象,是一个是一个proget类型的方法(get类型),方法描述是Range* Range([in] VARIANT Cell1, [in, optional] VARIANT Cell2),这里的“in”表示传入的参数,“optional”表示这个参数是可选的,即可要可不要。传入的参数以单元格的location表示(如:A1,D2,E5),一个参数表示一个单元格,两个参数表示两个参数代表的单元格区域(如:A1 * D5),那么我们可以根据这个方法写如下代码:
5. Variant cellA1Variant = sheet.getProperty(CELL_ID, new Variant[]{new Variant("A1")});
OleAutomation cellA1 = cellA1Variant.getAutomation();
获得A1单元格,CELL_ID即刚才Range方法的ID 0x000000c5。
6. 获得cellA1这个Range对象之后,查找其中的Value方法,可以对其赋值:
//为A1单元格赋值
cellA1.setProperty(CELL_VALUE_ID, new Variant("Hello OLE!"));
其中CELL_VALUE_ID是Value方法的ID,这样就Hello OLE写到了A1单元格中了。
7. 在组件中不仅有propset类型的方法,也会有对应的propget的方法,用于获得相应的值,返回值仍然用Variant带回。
Variant getValue = cellA1.getProperty(CELL_VALUE_ID);
System.out.println(getValue.toString());
四、结束
由于时间关系只能讲一些SWT的基本应用,更加全面的学习的话大家可以去参阅《Eclipse从入门到精通》,里面不仅介绍了SWT,对JFace也有一定的讲解,内容涵盖较广。