用户界面资源

org.eclipse.jface.resource 包定义用来帮助插件管理用户界面资源(例如,字体和图标)的类。

许多工作台扩展点允许插件提供可以用来显示它们在工作台中的添加项的图标。由于图形用户界面操作系统的内存只能同时支持有限数量的图像或字体,因此,必须小心管理插件的用户界面资源,有时在窗口小部件之间还要共享这些资源。

我们已经了解了对自述文件工具插件中的图标的几个引用。它的一些图标是在 plugin.xml 标记中指定的。

<extension
   point="org.eclipse.ui.views">
	<category
	   id="org.eclipse.ui.examples.readmetool"
	   name="%Views.category">
	</category>
	<view
	   id="org.eclipse.ui.examples.readmetool.views.SectionsView"
	   name="%Views.ReadmeSections"
	   icon="icons/view16/sections.png"
	   category="org.eclipse.ui.examples.readmetool"
	   class="org.eclipse.ui.examples.readmetool.ReadmeSectionsView">
	</view>
</extension>

我们还了解了用来描述运动中的图像的代码。下列代码来自于自述文件工具的 ReadmeEditorActionBarContributor

public ReadmeEditorActionBarContributor() {
      	...
	action1 = new EditorAction(MessageUtil.getString("Editor_Action1"));
	action1.setToolTipText(MessageUtil.getString("Readme_Editor_Action1"));
	action1.setDisabledImageDescriptor(ReadmeImages.EDITOR_ACTION1_IMAGE_DISABLE);
	action1.setImageDescriptor(ReadmeImages.EDITOR_ACTION1_IMAGE_ENABLE);
	...

JFace 提供了一些基本支持类,它们允许插件管理自己的图标和字体,而不用担心何时创建和毁坏相应的平台图形对象。这些支持类可以按如上所示直接由插件来使用,也可以在工作台使用这些类来获取在扩展点标记中所描述的图像时间接使用。

图像描述符和注册表

SWT Image 类表示来自操作系统的透视图的图像。因为大多数图形用户界面操作系统都对可同时打开的图像数量有限制,所以,在创建它们时,插件应当特别小心,并且确保在使用完它们时,还要正确地除去它们。通过使用 JFace ImageDescriptorImageRegistry 类而不是 SWT 图像,插件通常都可以避免直接创建、管理和处理这些图像。

图像描述符

ImageDescriptor 类可以用作图像的轻量级描述。它指定创建图像所需要的所有内容,例如,可以从其中获得图像的 URL 或文件名。ImageDescriptors 不会分配实际的平台图像,除非使用 createImage() 方法来特别请求。

如果代码构造为在一个位置定义所有图标,并在需要它们时进行分配,则图像描述符是最佳策略。可以在任何时候创建图像描述符,而不用担心操作系统资源,全部在初始化代码中创建它们是很方便的。

图像注册表

ImageRegistry 类用来保存已命名的图像的列表。客户可以直接将图像描述符或 SWT 图像添加到列表中。在注册表中按名称来请求图像时,注册表将返回该图像(如果创建了该图像的话),或者根据描述符来创建一个图像。这允许注册表的客户共享图像。

添加到注册表中的图像或者从注册表中检索到的图像一定不能由任何客户来除去。注册表负责处理图像,原因是图像是由多个客户共享的。当平台图形用户界面系统关闭时,注册表就将除去图像。

使用图像的插件模式

在 plugin.xml 中指定图像

如果可能,在 plugin.xml 文件中指定插件的用户界面对象的图标。许多工作台扩展点都包含用于图标文件的配置参数。通过在 plugin.xml 中的扩展添加项中定义图标,于是就使图像管理策略保留在了平台上。由于通常将图标保存在插件的目录中,因此允许您在同一个位置指定图标和管理文件。

仅当不能将图标指定为扩展添加项的一部分时,才应考虑其它模式。

显式创建

当图像不是频繁使用并且也不共享时,显式地创建图像是最佳策略。可以直接在 SWT 中创建图像,并在使用它之后进行除去。

也可以通过使用 ImageDescriptor 并调用 createImage() 方法来显式地创建图像。在第一种情况下,在不再需要图像之后,必须调用图像的 dispose() 方法。例如,如果在对话框在打开的情况下创建了图像,则在关闭对话框时它就应该除去该图像。

图像注册表

当在插件中频繁地使用图像并且在用户界面中的许多不同的对象之间共享图像时,向 ImageRegistry 注册图像描述符是很有用的。注册表中的图像将与按同一名称来查询图像的任何对象共享。您一定不能除去注册表中的任何图像,因为其它对象也共享这些图像。

当图像可能在插件的整个有效期内频繁使用,并且被许多对象共享时,将图像添加到图像注册表中是最佳策略。使用注册表的缺点是,在关闭图形用户界面系统之前不会除去注册表中的图像。由于对可同时打开的平台(SWT)图像数量有限制,因此,插件应当小心,不要在注册表中注册太多图标。

AbstractUIPlugin 中包含关于创建插件宽幅图像注册表的协议。

标注提供程序

当频繁使用图标来显示特定查看器中的项时,可以通过使用标注提供程序来使它在查看器中的相似项目之间共享。由于标注提供程序负责为查看器中的任何对象返回图像,因此,它可以控制图像的创建以及在查看器中的对象之间共享图像。

标注提供程序可以使用先前讨论的任何技术来生成图像。如果浏览 LabelProvider 子类中的 getImage() 的各种实现,则您将看到多种方法,包括高速缓存对象的单个图标和按类型来维护图像的表。必须在标注提供程序的 dispose() 方法中除去由标注提供程序创建的图像,该方法是在除去查看器时调用的。

使用标注提供程序是在显式创建和图像注册表之间的一种很好的折衷。它促进了类似图像注册表之类的图标的共享,但是仍然保持对实际图像的创建和处理进行控制。

插件宽幅图像类

当精确调整插件时,通常都会对所有这些不同的图像创建模式进行试验。将有关图像创建的决策制定隔离在一个单独的类中,并指导所有客户使用该类来获取所有图像,这是很有用的。这样,就可以调整创建顺序,以便反映插件的实际性能特征。

ResourceManager

ResourceManager 类用来保持将 ImageDescriptor 映射到 Image,以便可以通过 Image 的描述符引用该 Image 来复用它。当通过描述符来向注册表请求图像时,如果该图像已被创建,注册表将返回该图像,否则将根据该描述符创建一个图像。这允许注册表的客户机共享图像。

顶级 ResourceManager 是对 Display 创建的 DeviceResourceManagerJFaceResources.getResources() 定义的 ResourceManager 是 DeviceResourceManager,它可以被用作顶级 ResourceManager。如果需要生命周期比 DeviceResourceManager 短的 ResourceManager,则可以创建 LocalResourceManager 作为子代并在使用完成后将其除去。

当用来创建 DeviceResourceManager 的 Display 被除去从而不再需要特殊管理代码时,该 DeviceResourceManager 就会被除去。

添加到管理器的图像或者从管理器中检索的图像一定不能由任何客户机除去。由于图像由多个客户机共享,所以管理器负责除去图像。当存放图像的 ResourceManager 被除去时,注册表将除去图像。

字体注册表

字体是平台操作系统中另一个受限制的资源。字体的创建和处理问题与图像是相同的,需要类似的速度/空间折衷。通常,在 SWT 中,字体的分配是通过使用平台的相关字体名来请求字体来实现的。

FontRegistry 类按照字体的名称来保存字体表。它管理字体的分配和处理。

通常,插件应当避免分配任何字体或描述具有特定于平台的名称的字体。尽管字体注册表是在 JFace 内部使用的,但是插件通常不使用字体注册表。JFaceResources 类应当用来访问公共字体。

允许用户在首选项页面中指定应用程序的首选字体是很常见的。在这些情况下,应该使用 FontFieldEditor 来获取用户的字体名,并使用 FontRegistry 来保存字体。FontFieldEditor 仅在首选项页面中使用。

JFaceResources

JFaceResources 控制对常见平台字体和图像的访问权。它维护内部字体和图像注册表,以便客户可以共享已命名的字体和图像。

在工作台和其它插件中使用了很多技术以便在需要的地方共享图像。JFaceResources 图像注册表未在工作台和插件代码中广泛使用。

字体的使用更简单。工作台和大多数插件使用 JFaceResources 类来根据逻辑名请求字体。提供了诸如 getDialogFont()getDefaultFont() 方法,以便插件可以在它们的用户界面中使用期望的字体。