JVM桌面框架的状态:SWT


什么是SWT?

SWT源自Eclipse项目,最初是IDE。开发人员为Eclipse建立了一个专用框架,用于在其中构建其图形组件。Swing和SWT的设计差异很大。Swing从头开始用Java实现小部件的绘制。SWT是依赖本地图形对象的精简包装API。这有两个主要好处:

窗口小部件看起来是平台固有的。 渲染速度更快。

SWT API

SWT背后有一个指导原则:因为它依赖于本机图形对象,所以每个组件都需要一个“父”对象作为其第一个参数。父对象是绘制子对象的对象。每个SWT组件的构造函数都将父级作为其第一个参数。

swt-api.png

SWT的特性

SWT具有一些特性,其中大多数与基于系统库的设计有关。

原生依赖性

SWT为每个主流操作系统(例如Windows,MacOSX等)提供JAR。例如,这是我的笔记本电脑的Maven依赖项:

<dependency>
  <groupId>org.eclipse.platform</groupId>
  <artifactId>org.eclipse.swt.cocoa.macosx.x86_64</artifactId> <!--1-->
  <version>3.114.100</version>
  <scope>runtime</scope>                                       <!--2-->
</dependency>
  1. JAR坐标取决于平台。它们包含JNI绑定形式的必需本机库。
  2. 仅在运行时需要JAR。

swt-jar-structure.jpg

SWT事件控制回路

Swing提供了一个开箱即用的事件控制循环。SWT并非如此。我们需要将以下代码复制粘贴到我们的每个应用程序中:

20210223133818.png

  1. SWT与操作系统之间的桥梁。
  2. 创建顶层窗口。
  3. 显示它。
  4. 尽管该系统的窗口本机资源尚未释放。
  5. 处理排队的事件。如果什么也不需要做...什么都不做。
  6. 释放所有系统本机资源。

无参构造函数

窗口和对话框Shell在SWT中均表示为实例。顶级窗口不需要父级,因此Shell提供了一个无参数的构造函数。但是由于Shell是图形控件,所以其所有父类也都提供了这样的构造函数。这些构造函数的主体为空,调用它们不会执行任何操作。

组件创建顺序

在父对象上实例化组件的顺序就是将它们添加到该父对象的布局中的顺序。如果需要将它们分离,则需要发挥创造力, 例如。将对构造函数的调用包装在lambda中。

这是一个SWT示例,按此顺序显示标签,文本字段和按钮:

20210223133713.png

Styling

如上一片段所示,小部件的样式在其实例化期间发生。这些样式SWT以样式位的形式编码在类中:

  • LEAD = 1 << 14
  • LEFT = LEAD
  • SINGLE = 1 << 2
  • BORDER = 1 << 11
  • PUSH = 1 << 3
  • 等等。

循环依赖

请注意,的构造函数Control采用一个Composite实例,该实例本身是的子类Control。这种循环依赖关系绑定到同一包中。

显示表格数据

SWT仅关注小部件及其渲染。与Swing和JavaFX相对,它没有数据模型的概念:您需要自己管理数据。对于0-D数据(例如文本字段),甚至对于1D数据(例如列表框),它都是可管理的。对于二维数据(即表),这很麻烦。

因此,大多数图形框架在组件及其管理的数据之间引入了模型抽象。例如,Swing具有JTable和TableModel。

Eclipse提供了JFace库,该库通过SWT API等提供了数据模型抽象。例如,对于表,JFace具有TableViewer类。每个JFace查看器类的核心都包含一个SWT控件。

jface-swt-integration.png

包装在很深的层次上适用:SWTTableColumnJFace的包装TableColumnViewer

本Viewer类具有丰富的类型层次来处理不同尺寸的数据。IStructuredContentProvider提供多行数据,例如表中的数据。由于API是在泛型之前设计的,因此需要在StructuredViewer级别上进行运行时检查以验证set的类型IContentProvider。此外,StructuredViewer还提供了排序,过滤和“装饰”功能。

JFace TableViewer功能

注意,有一个库可以管理模型和控件之间的双向数据绑定:JFace Data Binding。我找不到兼容的版本。


原文链接:http://codingdict.com