豐富的 GUI 中的視圖可以以各種方式顯示信息
從而改善用戶體驗
非常自然
UI 視圖之間是相互依賴的
需要進行交互
Eclipse 簡化了鏈接 UI 視圖的工作
並提供了將視圖鏈接應用到非 UI 場景的方式
簡介 Eclipse 平台允許使用可插入組件 —— 插件 —— 幫助創建豐富的圖形用戶界面(graphical user interface
GUI)應用程序
例如
插件可以向 GUI 提供視圖
但是
在現實的應用程序中
UI 視圖不能是孤立的
它們需要根據其他視圖的狀態進行交互和對本身進行更新
一個簡單的例子是描述世界各地的主要旅游目的地的 GUI 應用程序
這個 GUI 可能有一個 Select City 視圖
用於顯示旅游景點和公共交通信息
圖
視圖鏈接的例子
本文介紹在 Eclipse 中結合視圖的方式以及如何對其他視圖的狀態做出響應
還討論鏈接視圖方式在哪些情況下可能比其他方式合適
Eclipse 開發人員可以依賴以下方法對視圖進行鏈接
選擇提供器
選擇監聽器(selection provider
selection listener)模式
從而讓視圖對其他視圖中的選擇做出反應
IAdaptable 接口
與某些事件結合使用
屬性改變監聽器
它允許視圖將屬性改變事件告之已注冊的監聽器
選擇提供器 選擇監聽器范型 選擇提供器
選擇監聽器模式能夠方便地創建對其他視圖中的改變做出響應的視圖
例如
當用戶點擊代表城市名的 UI 項時
另一個視圖可能需要顯示這個城市的景點詳情
這樣的視圖可以使用 UI 選擇對象(可能是代表城市名的字符串對象)中包含的信息
並使用它從模型中獲取和顯示其他信息
視圖應該能夠識別並利用 UI 選擇事件
org
eclipse
ui
ISelectionListener 是接收 UI 選擇事件的監聽器接口
選擇監聽器必須注冊到工作台頁面
工作台頁面實現 org
eclipse
ui
ISelectionService 接口定義的服務
從而將 UI 選擇事件告之監聽器
選擇監聽器必須注冊到選擇服務
用於顯示可選擇的 UI 項的視圖還應該能夠公布 UI 選擇
視圖通過將
選擇提供器
注冊到它們各自的工作台站點來實現這一點
Eclipse 中的每個 UI 部分通過 org
eclipse
ui
IWorkbenchPartSite 引用與工作台站點聯絡
選擇提供器注冊到工作台站點
在使用選擇提供器
選擇監聽器模式鏈接視圖時
視圖可以將本身作為監聽器添加到工作台頁面
而希望公布選擇的其他視圖必須將選擇提供器添加到它們各自的工作台站點
org
eclipse
ui
ISelectionListener 接口如下所示
public void selectionChanged(IWorkbenchPart part
ISelection selection);
要使視圖能夠監聽選擇改變
視圖必須實現 ISelectionListener 接口並必須將自己注冊到工作台頁面
清單
顯示一個例子
清單
將選擇監聽器添加到工作台頁面
public class MyView extends ViewPart implements ISelectionListener{
public void createPartControl(Composite parent) {
// add this view as a selection listener to the workbench page
getSite()
getPage()
addSelectionListener((ISelectionListener) this);
}
// Implement the method defined in ISelectionListener
to consume UI selections
public void selectionChanged(IWorkbenchPart part
ISelection selection) {
//Examine selection and act on it!
}
}
使用 UI 選擇的更好的方法是
將消費者視圖作為監聽器注冊到特定的視圖部分
正如在下面的例子中可以看到的
源視圖部分的視圖 ID 在注冊選擇監聽器期間被作為一個參數
getSite()
getPage()
addSelectionListener(
SampleViewId
(ISelectionListener)this);
這種方式可以避免對消費者視圖進行多余的回調
如果視圖被注冊為非特定的監聽器
就會出現這種情況
清單
中的代碼片段顯示一個視圖的 createPartControl() 方法
這個方法創建一個 JFace TableViewer 並將它作為選擇提供器添加到工作台站點
這些代碼使 TableViewer 中的任何 UI 選擇改變能夠傳播到頁面
並最終傳播到對這種事件感興趣的消費者視圖
清單
設置選擇提供器
public void createPartControl(Composite parent) {
// Set up a JFace Viewer
viewer = new TableViewer(parent
SWT
MULTI | SWT
H_SCROLL | SWT
V_SCROLL);
viewer
setContentProvider(new ViewContentProvider());
viewer
setLabelProvider(new ViewLabelProvider());
viewer
setSorter(new NameSorter());
viewer
setInput(getViewSite());
// ADD the JFace Viewer as a Selection Provider to the View site
getSite()
setSelectionProvider(viewer);
}
這個視圖將它創建的 JFace TableViewer 注冊為選擇提供器有兩個原因
這個視圖打算使用這個 TableViewer 顯示信息
而且用戶將與 TableViewer 進行交互
TableViewer 實現了選擇提供器接口並能夠向工作台部分站點傳播選擇事件
因為 JFace 查看器是選擇提供器
所以在大多數情況下就不必創建選擇提供器了
視圖只需使用眾多的 JFace 查看器之一來顯示信息
並將 JFace 查看器注冊為選擇提供器
另一種鏈接方式
某些情況需要另一種視圖鏈接方式
信息量可能太大
由於內存使用量增加
UI 選擇對象無法有效地容納它
視圖可能希望公布其他信息
而不只是公布可視化選擇信息
公布的信息可能是根據選擇進行某些後期處理的結果
視圖可能希望使用來自另一個插件的信息
而這個插件可能根本沒有提供視圖(使用包含的 JFace 查看器)
在這種情況下
使用基於 UI 選擇的鏈接是不可能的
可以使用 re
runtime
IAdaptable 接口來緩解第一個問題
這個接口使選擇對象能夠在需要時傳播更多信息
第二個和第三個問題需要用手工方式解決
屬性改變監聽器模式是合適的解決方案
使用 IAdaptable 接口 實現 IAdaptable 接口的類能夠動態地返回某些類型的適配器
然後可以使用這些適配器獲取更多信息
如果查看器中的選擇對象實現了 IAdaptable 接口
那麼根據它們可以返回的適配器類型
可以有效地獲取更多信息或相關信息
re
runtime
IAdaptable 接口如下所示
public void object getAdapter(Class adapter);
顯然
調用者應該知道它期望選擇返回的適配器接口類型
考慮一個 JFace TreeViewer
它在一個單層的樹中顯示城市
代表城市的對象是 CityClass 類型的
CityClass 對象應該包含關於此城市的基本信息
並只在需要時返回詳細信息
在清單
中要注意
CityClass 支持的適配器類型使調用者能夠在需要時獲得更多信息
清單
JFace TreeViewer 中的 CityClass
class CityClass implements IAdaptable {
private String cityName;
public CityClass(String name) {
this
name = name;
}
public String getName() {
return name;
}
public CityClass getParent() {
return parent;
}
public String toString() {
return getName();
}
public Object getAdapter(Class key) {
if (key
getName()
equals(
ITransportationInfo
))
return CityPlugin
getInstance()
getTransportAdapter();
else (key
getName()
equals(
IPlacesInfo
))
return CityPlugin
getInstance()
getPlacesAdapter();
return null;
}
}
熟悉 Eclipse IDE 工作台的開發人員都了解 Outline 視圖
這個視圖提供了編輯器中打開的文件的結構化視圖
這個 Outline 視圖展示了 IAdaptable 接口如何與某些事件類型結合使用
從而有效地根據其他視圖的內容對視圖進行初始化
編輯器必須為用戶打開的文件創建一個 Content Outline 頁面
Content Outline 頁面符合 IContentOutlinePage 接口
編輯器還必須實現 IAdaptable 接口
這樣就能夠向編輯器查詢 IContentOutlinePage 類型的適配器
使用這個適配器來獲取和顯示文件的大綱信息
IAdaptable 接口的另一個例子是 Properties 視圖
Properties 視圖跟蹤對活動部分的選擇
並調用當前選擇對象上的 getAdapter 方法
查詢的適配器類型是 IPropertySource
然後
Properties 視圖使用 IPropertySource 適配器來獲取要顯示的信息
在這些視圖鏈接例子中
應用程序在接到 Selection Changed 或 Part Activation 通知時
通過 IAdaptable 獲取信息
因此
如果選擇對象實現了 IAdaptable
那麼與從選擇對象本身獲取的信息量相比
用戶可以通過適配器獲得多得多的信息
屬性改變監聽器范型 可以使用屬性改變監聽器類型的交互來解決前面提到的另外兩個問題
視圖如何使用來自未提供視圖的插件的信息
以及視圖如何公布在可視化選擇之後某些處理所生成的信息?
可以建立一個插件來接受屬性改變監聽器的注冊
並在需要時通知注冊的監聽器
應用程序可以將定制的事件告之監聽器
事件中還可以包含要共享的信息
與選擇提供器的情況不同
屬性改變提供器不需要實現特定的接口
您必須決定將監聽器注冊到提供器的語義
清單
中的代碼片段是一些方法
它們允許在屬性提供器視圖或插件類中添加或刪除屬性改變監聽器
清單
添加和刪除屬性改變監聽器
//To add a listener for property changes to this notifier:
public void addPropertyChangeListener(IPropertyChangeListener listener);
//To remove the given content change listener from this notifier:
public void removePropertyChangeListener(IPropertyChangeListener listener);
屬性提供器應該使用 org
eclipse
jface
util
PropertyChangeEvent 來創建一個可以有效填充和傳播的事件
另外
屬性提供器要負責維護監聽器列表並對它們進行回調
作為一個例子
請考慮一個每小時調用 World Weather Web Service 來查詢主要城市的氣象的插件
它要使這些信息可供其他插件和視圖使用
CityWeatherPlugin 可以公開一個稱為 CitiesWeatherXML 的屬性
消費者可以將本身作為 PropertyChange 監聽器注冊到 CityWeatherPlugin
為此
監聽器必須了解 CityWeatherPlugin 中的注冊方法
這樣才能將本身注冊為氣象數據事件的監聽器
CityWeatherPlugin 應該跟蹤並通知監聽器
它使用 PropertyChangeEvent 向監聽器提供數據
清單
創建屬性提供器
class CityPopulationPlugin {
ArrayList myListeners;
// A public method that allows listener registration
public void addPropertyChangeListener(IPropertyChangeListener listener) {
if(!ntains(listener))
myListeners
add(listener);
}
// A public method that allows listener registration
public void removePropertyChangeListener(IPropertyChangeListener listener) {
myListeners
remove(listener);
}
public CityPopulationPlugin (){
// method to start the thread that invokes the population \
web service once every hour
// and then notifies the listeners via the propertyChange() callback method
initWebServiceInvokerThread( myListeners );
}
void initWebServiceInvokerThread(ArrayList listeners) {
// Code to Invoke Web Service Periodically
and retrieve information
// Post Invocation
inform listeners
for (Iterator iter = erator(); iter
hasNext();) {
IPropertyChangeListener element = (IProperty\
ChangeListener) iter
next();
element
propertyChange(new PropertyChangeEvent(this
\
CitiesWeatherXML
null
CityWeatherXMLObj));
}
}
}
屬性改變監聽器必須實現 org
eclipse
jface
util
IPropertyChangeListener 接口
以便允許屬性改變提供器對它進行回調
這個接口有一個方法 public void propertyChange(PropertyChangeEvent event)
清單
實現 IPropertyChangeListener
class MyView implements IPropertyChangeListener {
public void createPartControl() {
//register with a Known Plugin that sources Population Data
CityPopulationPlugin
getInstance()
addPropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent event) {
//This view is interested in the Population Counts of the Cities
//The population data is being sourced by another
plugin in the background
if( event
getProperty()
equals(
CitiesWeatherXML
)) {
Object val = event
getNewValue();
// do something with val
}
}
}
這種方式的靈活性在於
應用程序可以在需要時通知監聽器
並根據各種場景向它們傳遞信息
傳遞的信息不必直接與 UI 選擇相關
這些信息可以是某些後期處理的結果
另外
它可以與其他後台作業的狀態相關
或者是定期從模型中獲取的最新信息
例如
City Selector View 可能不只是傳播選擇的城市
還使用 PropertyChange 范型將當前選擇的城市的氣象信息異步地傳播給其他消費者
結束語 本文討論了使視圖相互協作和響應的各種方式
如果 UI 選擇本身不夠
可以使用 IAdaptable 接口加強它們
屬性改變監聽器也為滿足非 UI 場景提供了更大的靈活性
共
頁
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28496.html