前言
在我的计算机组成课程上,教授要求编写一个 MIPS 汇编器并提供图形界面。由于我的工作环境并非 Windows,同时希望在各个平台的界面中使用原生控件,并且我偏好使用静态类型语言,所以决定使用 SWT 进行图形界面的编写。
集成
鉴于 Maven 上的版本老旧,推荐直接前往 SWT 官方网站 下载稳定发行版本。我使用的开发环境是 IntelliJ Idea,因此在 Project Structure 中的 Libraries 和 Artifacts 内添加相应的设置即可。
架构
我是一名 Android 开发者,因此我在学习 SWT 时也会与 Android 框架进行对比。二者多有类似,也有不同。
在 SWT 中,Display
与 Android 中 Context
和 Application
的设计有所相近,具有系统资源管理和应用层面操作的功能。而 Display
的一个实用的扩展是 Display.getCurrent()
和 Display.getDefault()
,即可以通过静态方法获取当前线程或默认的 Display
。
而与 Android 中的 Activity
相近的则是 Shell
。Shell
代表一个平台无关的抽象窗口,由此可以进行窗口相关的操作,并建立视图结构。
与 Andorid 不同,SWT 中没有 XML 布局系统,所有视图的创建需要由应用程序的 Java 代码完成(但有自动将 XML 转换为 Java 代码的工具,如 SWTXML 等)。Control
与 Android 中的 View
类似,是所有控件的基类,但不同的是,所有的 Control
在构造时都需要一个 Composite
作为父对象,既是 Android 中的 Context
,也是视图结构上的父容器。而之后如果需要更改控件的父容器,可以调用Control.setParent()
,但是否成功则需要由平台支持决定。
一个窗口最初的 Composite
实例即是 Shell
。
使用
主循环
SWT 的主循环是由应用程序自己书写的。常见的范式如下:
1 | onCreateDisplay(); |
视图结构创建
在创建 Shell
实例之后,一般会添加界面元素和布局信息。示例代码如下:
1 | private void onCreateShell() { |
视图布局
SWT 中的布局方式分为两步:使用 Composite.setLayout()
设置父元素布局子元素时使用的布局方式,使用 Control.setLayoutData()
提供子元素的布局参数。这与 Android 中的布局方式有些许不同,即 SWT 中的 Layout
是父容器的参数而非父容器本身的类型。
SWT 中常用的 Layout
包括 FillLayout
、RowLayout
、GridLayout
、FormLayout
和 SashForm
等。对于前三种基础布局,可以参考 Eclipse 的这篇文章 进行学习。
资源系统
与 Android 框架不同,SWT 只是一个图形界面库,因此不提供资源系统。
在写作一般规模的 SWT 应用时,可以使用 Java 自带的 ResourceBundle
进行资源管理与国际化。
常见的范式如下:
1 | ResourceBundle resourceBundle = ResourceBundle.getBundle("res/string/mipside", new Utf8Control()); |
其中 Utf8Control
是为了使得 ResourceBundle 支持直接读取 UTF-8 编码的资源文件的类,可以从之后我的项目中获得我编写的版本;ResourceBundle 默认只支持 ASCII 编码。
设置存储
为了保存用户的设置,可以使用 Java 自带的 Preferences
进行键值对的存储。使用时可以通过 Preferences.userNodeForPackage()
获取一个节点的 Preferences
实例,而之后则与使用 Android 中的 SharedPreferences
类似。
部署
在 Linux 上,一个 Shell 脚本执行 java -jar
已经足够。
在 Windows 上,经过一些比较,我决定使用 launch4j,至今体验良好。
在 Mac OS X 上,JVM 需要特定参数才能正常启动应用,以及其他打包应用程序的细节,可以参考 这篇 Eclipse 的文档。
评价
在使用 SWT 完成我的项目后,总体来说,感觉这是一个可用的图形库。
从接口方面看,SWT 遵循着一致的命名规范,但 Builder 模式的缺失使得构造控件的过程较为冗长,此外将样式、键码等大量常量放置在 SWT
类中也显得较为奇怪。
从功能方面看,SWT 跨平台调用原生控件的能力确实令人惊喜。众多部件在 Windows、Linux GTK+ 3 和 GTK+ 2、Mac OS X Cocoa 上不需要经过调试即表现良好,并且通过打包与原生应用几乎没有什么差异。美中不足的只是一些小的设计细节,例如标签中的文本不能使用光标选择复制、带有链接的多行标签需要使用另一个类却不能指定多行文本居中对齐。但总体来说,这些瑕疵要么可以绕过,要么相比于 SWT 本身带来的便捷来说,无伤大雅。
结语
菜单、字体、图像、对话框、StyledText
,还有关于 SWT 的很多方面这篇文章没有覆盖到。但网络上相关的资源是十分丰富的,例如 Google、Eclipse 的 Javadoc 和 Java2s 上的代码示例都是有用的信息来源。
如果有兴趣,我的项目中也有一些按照我自己对 SWT 的理解写出的代码,可以 移步至 GitHub 浏览。