org.eclipse.jface.resource 套件定義一些類別,這些類別協助外掛程式管理 UI 資源,例如字型和圖示。
許多工作台延伸點允許外掛程式提供圖示,您可以在工作台使用這些圖示顯示外掛程 式的構成要素。因為 GUI 作業系統在記憶體中支援數目有限的影像或字型,所以必須小心管理外掛 程式的 UI 資源,並且有時在小組件之間共用這些資源。
我們在 Readme 工具外掛程式中已看過數個圖示的參照。它的一些圖示是指定在 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>
我們也看過快速說明影像的程式碼。下列內容來自 Readme 工具的 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 類別代表來自作業系統視景的影像。因為大部分 GUI 作業系統有限制同時可以開啟的影像數目,所以外掛程式在建立影 像時要非常小心,當結束使用影像時也要確定有妥善除去影像。透過使用 JFace ImageDescriptor 和 ImageRegistry 類別代替 SWT 影像,外掛程式通常可以避免直接建立、管 理和除去這些影像。
可以使用 ImageDescriptor 類別作為影像的簡單說明。它指定建立影像所需的一切,例如可從中取得影像的 URL 或檔案名稱。除非使用 createImage() 方法提出特別要求,否則 ImageDescriptors 不配置實際平台影像。
當建構程式碼時,要使它在一個地方定義所有圖示並依需要配置圖示,影像描述子是最佳 策略。可以隨時建立影像描述子而不必考慮 OS 資源,方便您在起始設定碼中建立它 們全部。
使用 ImageRegistry 類別保留具名影像清單。用戶端可以將影像描述子或 SWT 影像直接新增至清單。從登錄依名稱要求一個影像時,如果已建立該影像登錄就會傳回該影像,否則會從描 述子建立一個影像。這樣可讓登錄的用戶端共用影像。
任何用戶端不得除去在登錄中新增或擷取的影像。登錄負責除去影像,因為影像供多個用戶端共用。平台 GUI 系統關閉時登錄會除去影像。
在 plugin.xml 檔案指定外掛程式的 UI 物件的圖示。許多工作台延伸點包 括圖示檔的配置參數。透過在 plugin.xml 中在延伸構成要素中定義圖示,您讓平台決定影像管理策略。因為圖示通常儲存在外掛程式的目錄,所以這樣可讓您指定圖示並在一個地方集中管 理檔案。
唯有無法指定圖示作為延伸構成要素的一部分時才考慮其他型樣。
不常使用和共用影像時,明確地建立影像是最佳策略。您可以在 SWT 直接建立影像,然後在使用完影像之後除去影像。
使用 ImageDescriptor 和呼叫 createImage() 方法也可以明確建立影像。以第一個狀況來說,不再需要影像之後必須呼叫影像的 dispose() 方法。例如,當對話框開啟時如果對話框建立影像,則在關閉對話框時必須除去該影像。
在一個外掛程式中經常使用某影像而且 UI 中的許多不同物件共用該影像,則以 ImageRegistry 登錄影像描述子很有用。依相同名稱查詢影像的物件會共用登錄中的影像。您不可以除去登錄中的影像,因為還有其他物件共用這些影像。
若經常使用某影像,也許在外掛程式的生命期限內,而且由許多物件共用該影像,則新增該 影像到影像登錄中是最佳策略。使用登錄的缺點是要等到 GUI 系統關閉之後才會除去登錄中的影像。因為有限制一次可以開啟的平台(SWT)影像數目,所以外掛程式應該小心不要在一 個登錄中登錄太多圖示。
類別 AbstractUIPlugin 包括用來建立外掛程式層面的影像登錄的通訊協定。
經常使用某個圖示顯示某特定檢視器中的項目時,該檢視器中的類似項目可以使 用標籤提供者來共用該圖示。因為標籤提供者負責傳回檢視器中任何物件的影像,所以它可以控制影像的建立 以及影像在檢視器的物件之間如何共用。
標籤提供者可以使用前述技巧來產生影像。如果在 LabelProvider 子類別瀏覽 getImage() 的不同實作,則您會看到多種方法,包括快取物件 的單一圖示和依類型維護影像表。必須以提供者的 dispose() 方法 除去標籤提供者建立的影像,在除去檢視器時就會呼叫這個方法。
使用標籤提供者是明確建立與影像登錄之間一個很好的折衷方案。它提升圖示(例如影像登錄)的共用,不過仍保持控制實際影像的建立和除去。
微調外掛程式時,通常會實驗所有這些不同的影像建立型樣。這對於在個別類別中隔離有關影像建立之決策,以及指示所有用戶端使用這個類 別取得所有影像來說很有用。如此一來,您可以調整建立順序來反映外掛程式的實際效能性質。
ResourceManager 類別係用來維持 ImageDescriptors 到 Images 的對映,使得 Image 可以透過其描述子重複用於參照。從登錄依描述子要求影像時,如果已建立影像,登錄就會傳回該影像,否則會從描述子建立影像。這樣可讓登錄的用戶端共用影像。
最上層的 ResourceManager 是一個於 Display 建立的 DeviceResourceManager。由 JFaceResources.getResources() 定義的 ResourceManager 是一個 DeviceResourceManager,可以用來作為最上層 ResourceManager。 如果您需要的 ResourceManager 的生命週期比 DeviceResourceManager 還短, 您可以建立 LocalResourceManager 作為子項,並在您完成時將它刪除。
在用來建立 DeviceResourceManager 的 Display 被刪除時, 即會刪除 DeviceResourceManager,因此不需要特殊的管理程式碼。
加入管理程式或從管理程式擷取的影像,不可由任何用戶端刪除。該管理程式會負責刪除影像, 因為這些影像會供多個用戶端共用。當存放影像的 ResourceManager 被刪除時,登錄即會刪除影像。
字型是平台作業系統中另一個有限的資源。字型和影像都有建立和除去方面的問題,需要類似的速度/空間折衷方案。一般而言,使用平台相依的字型名稱來要求字型,藉此在 SWT 中配置字型。
FontRegistry 類別依字型名稱保存字型表。它管理字型的配置和除去。
一般來說,外掛程式應避免使用平台特定名稱配置字型或說明字型。雖然字型登錄使用於 JFace 內部,但是外掛程式通常不使用它。應該使用 JFaceResources 類別存取通用字型。
讓使用者在喜好設定頁面中為應用程式的字型指定他們的喜好設定是很常見的。在這些情況下,應使用 FontFieldEditor 從使用者取得字型名稱,而且可以使用 FontRegistry 保存字型。唯有在喜好設定頁面才使用 FontFieldEditor。
類別 JFaceResources 控制存取通用平台字型和影像。它維護一個內部字形組和影像登錄,使得用戶端能共用具名的字型和影像。
在工作台和其他外掛程式中使用許多技巧來共用所需的影像。工作台與外掛程式程式碼很少使用 JFaceResources 影像登錄。
使用字型比較簡單。工作台和大部分外掛程式使用 JFaceResources 類別依邏輯名稱要求字型。有提供一些方法例如 getDialogFont() 和 getDefaultFont(),使 外掛程式能夠在它們的 UI 中使用預期的字型。