当前页面: 开发资料首页 → JSP 专题 → Eclipse中用SWT和JFace开发入门
摘要: Eclipse中用SWT和JFace开发入门
可以使用标准窗口小部件工具箱(Standard Widget Toolkit,SWT)和 JFace 库来开发用于 Eclipse 环境的图形用户界面,而且还可以将它们用于开发单独的 GUI 本机应用程序。在本文中,我将介绍一些基本的 SWT(基本 GUI 对象的名称)类型,并展示如何综合使用它们来创建有用的应用程序。
关于 Eclipse、SWT 和 JFace
正如 Eclipse 的 Web 站点上所提到的,Eclipse 是一种通用工具平台。它是一个开放的、可用于任何东西的可扩展 IDE,没什么特别之处,它为工具开发人员提供了灵活性以及对软件技术的控制。
Eclipse 为开发人员提供了生产大量 GUI 驱动的工具和应用程序的基础。而这项功能的基础就是 GUI 库 SWT 和 JFace。
SWT 是一个库,它创建了Java 版的本地主机操作系统 GUI 控件。它依赖于本机实现。这意味着基于 SWT 的应用程序具有以下几个关键特性:
基本控件
几乎所有 SWT GUI 都是从某些基础部分开始创建的。所有 SWT 窗口小部件都可以在 org.eclipse.swt.widget
或 org.eclipse.swt.custom
包中找到。(一些 Eclipse 插件还在其他包中提供了定制的窗口小部件。)窗口小部件包中包含一些基于操作系统控件的控件,而定制包中则包含一些超出操作系统控件集之外的控件。一些定制的软件包控件类似于窗口小部件包中的控件。为了避免命名冲突,定制控件的名称都是以“C”开始的(例如,比较 CLabel 与 Label)。
在 SWT 中,所有控件(除了一些高级控件,比如 shell,将在后面进行讨论)在创建的时候都必须有一个父控件(一个复合实例)。在创建的时候,这些控件被自动“添加”到父控件中,这与必须明确添加到父控件中的 AWT/Swing 中的控件有所不同,自动添加产生了一种“自上而下”地构造 GUI 的方法。这样,所有控件都可以采用一个复合父控件(或者一个子类)作为构造函数的参数。
大多数控件都有一些必须在创建时设置的标记选项。因此,大多数控件还有另外一个构造函数参数,我们通常称之为样式,该参数提供了设置这些选项的标记。所有这些参数值都是 static final int
,并且都是在 org.eclipse.swt
包的 SWT
类中定义的。如果不需要任何参数,则可以使用 SWT.NONE
值。
标签
标签可能是最简单的控件,标签 被用于显示纯文本(没有颜色、特殊字体或样式的文本)或称为图标的小图像。标签不接受焦点(换句话说,用户不能通过 Tab 键或鼠标移动到标签),因此,标签无法产生输入事件。
清单 1 展示了如何创建一个简单的文本标签。
清单 1. 创建一个带文本的标签
import org.eclipse.swt.widget.*;
:
Composite parent = ...;
:
// create a center aligned label
Label label = new Label(parent, SWT.CENTER);
label.setText("This is the label text");
import com.eclipse.swt.graphics.*;
import org.eclipse.swt.widget.*;
import org.eclipse.swt.custom.*;
:
Composite parent = ...;
Image image = ...;
:
// create a left aligned label with an icon
CLabel Clabel = new CLabel(parent, SWT.LEFT);
label.setText("This is the imaged label text"");
label.setImage(image);
import org.eclipse.swt.widget.*;
:
Composite parent = ...;
:
// create a text field
Text name = new Text(parent, SWT.SINGLE);
name.setText("");
name.setTextLimit(50);
name.setToolTipText("Enter your name -- Last, First");
name.selectAll(); // enable fast erase
清单 4 创建了一个“Clear”按钮:
清单 4. 创建一个按钮
import org.eclipse.swt.widget.*;
:
Composite parent = ...;
:
// create a push button
Button clear = new Button(parent, SWT.PUSH);
clear.setText("Clea&r");
&
导致利用紧接着的一个字母创建一个加速器,允许通过 Ctrl+<字母> 顺序的方式按下按钮(控件顺序由主机操作系统决定)。 SelectionListener
(在 org.eclipse.swt.events
包中)做到这一点。当按钮状态发生改变时(通常是按钮被按下),就会生成事件。清单 5 在单击 Clear 按钮时输出一条消息。
import org.eclipse.swt.events.*;
:
// Clear button pressed event handler
clear.addSelectionListener(new SelectionListener() {
public void widgetelected(selectionEvent e) {
System.out.println("Clear pressed!");
}
public void widgetDefaultSelected(selectionEvent e) {
widgetelected(e);
}
});
...Listener
类还有一个类似的 ...Adapter
类,这个类提供了一些空的方法实现,并且可以减少您需要编写的代码数量。例如,还有一个 SelectionAdapter
类,这个类实现了 SelectionListener
。 复合控件
至此,我们已经讨论了一些单独的控件。在多数 GUI 中,许多控件被组合在一起以提供丰富的用户体验。在 SWT 中,这种组合是通过 Composite 类实现的。
复合控件可以在任何级别上进行嵌套,并且可以混合和匹配控件,将它们作为子控件进行组合。这样做可以极大地减少 GUI 开发的复杂性,并为 GUI 代码重用(通过封装内部 GUI)创造了机会。复合控件可以是有边界的,并且这些边界很容易在视觉上产生混淆,或者它们也可以是无边界的,无缝集成到更大的组中。
清单 6. 创建一个有边界的复合控件。
单 6. 创建一个有边界的复合控件
import org.eclipse.swt.widget.*;
:
Composite parent = ...;
:
Composite border = new Composite(parent, SWT.BORDER);
import org.eclipse.swt.widget.*;
:
Composite parent = ...;
:
Group border = new Group(parent, SWT.SHADOW_OUT);
border.setText("Group Description");
SWT.SHELL_TRIM
或 SWT.DIALOG_TRIM
。shell 可以是模态的,也可以是非模态的。模态 shell 常常用于对话框,防止父 GUI(如果有的话)在关闭子 shell 之前被处理。
import org.eclipse.swt.widget.*;
:
Shell frame = new Shell(SWT.SHELL_TRIM);
:
:
Shell dialog = new Shell(frame, SWT.DIALOG_TRIM);
:
在多数情况下,应该选择使用 LayoutManagers,因为很容易调整它们来适应可变大小的 GUI。SWT 也提供了一些布局管理器供您使用;在这一期的系列文章中,我们将讨论两种基本的布局管理器:FillLayout 和 GridLayout。在这两种情况下,每当重新设置复合控件的大小,都需要进行定位。
一些布局管理器常常是专为某一个复合控件分配的。一些布局管理器只使用它们自身的参数就可以控制,而另一些布局管理器还需要其他参数 —— LayoutData,该参数是在它们管理的复合控件中的每个控件上指定的。
FillLayout
FillLayout 以行或列的形式安排控件。每个控件所设置的大小将与填充该复合控件所需的宽度和高度相同,在这些控件之间,空间是平均分配的。一种特殊情况是:在仅有一个子控件时,该控件的大小被设置为填充整个父复合控件的大小。
清单 10. 使用 FillLayout 创建一列控件
import org.eclipse.swt.widget.*;
import org.eclipse.swt.layouts.*;
:
Composite composite = ...;
FillLayout fillLayout = new FillLayout(SWT.VERTICAL);
composite.setLayout(fillLayout);
import org.eclipse.swt.widget.*;
import org.eclipse.swt.layouts.*;
:
Composite composite = ...;
GridLayout gridLayout = new GridLayout(2, false);
composite.setLayout(gridLayout);
Label l1 = new Label(composite, SWT.LEFT);
l1.settext("First Name: ");
Text first = new Text(composite, SWT.SINGLE);
Label l1 = new Label(composite, SWT.LEFT);
l2.setText("Last Name: ");
Text last = new Text(composite, SWT.SINGLE);
first.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
last.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
import org.eclipse.swt.widget.*;
:
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Shell Title");
// *** construct Shell children here ***
shell.open(); // open shell for user access
// process all user input events
while(!shell.isDisposed()) {
// process the next event, wait when none available
if(!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose(); // must always clean up