利用觀察者模式,在Eclipse RCP 的視圖、對話方塊之間優雅地進行資料傳遞

來源:互聯網
上載者:User

    在學習Eclipse的RCP過程中,一直對於如何對修改的資料相應的顯示到不同的視圖中存在疑問,後來在網上查了許久,瞭解到了觀察者的設計模式,將其應用到這方面發現實現效果非常理想且相當優雅,故記之。

一、什麼是觀察者(Observer)模式1.概念

      observer模式定義對象間的一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。JDK裡提供的observer設計模式的實現由java.util.Observable類和 java.util.Observer介面組成。從名字上可以清楚的看出兩者在Observer 設計模式中分別扮演的角色:Observer是觀察者角色,Observable是被觀察目標(subject)角色。

2.使用時機

1. 當一個對象的改變需要同時改變其他對象,而且它不知道具體有多少對象有待改變時, 應該考慮使用觀察者模式;

2. 一個抽象模型有兩個方面,其中一個方面依賴於另一方面, 這時用觀察者模式可以將這兩者封閉在獨立的對象中使它們各自獨立地改變和複用;

3. 觀察者模式所做的工作其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體,從而使得各自的變化都不會影響另一邊的變化。

 

3.舉例

      我們用一個實際的例子來說明:日常生活中說起觀察者,最常見的例子可能就是天氣預報,在這裡我們的觀察對象是地球,而我們是通過發射氣象衛星這個觀察者來檢測地球氣象變化的。

      這個例子中涉及三個對象:

      地球  (Earth):                        被觀察對象

氣象衛星(Satellite):                觀察者

氣象局(WeatherService):        用戶端調用

被觀察對象:地球  (Earth)

import java.util.Observable;</p><p>public class Earth extends Observable {<br />private String weather =" 晴朗 ";</p><p>public String getWeather() {<br />return weather;<br /> }<br />public void setWeather(String weather) {<br />this.weather = weather;</p><p>// 設定變化點<br />setChanged();<br />notifyObservers(weather);<br />}</p><p>}<br />   

[注意]  在需檢測的對象前需要設定變化點setChanged()和通知觀察者notifyObservers(),這兩個函數是由Observable類實現的,封裝了觀察者模式實現的細節。

 

觀察者:氣象衛星(Satellite)  

import java.util.Observable;</p><p>import java.util.Observer;</p><p>public class Satellite implements Observer {</p><p>private String weather;</p><p>public void update(Observable obj, Object arg) {</p><p>weather = (String) arg;</p><p>// 捕獲天氣變化情況,反饋給檢測者</p><p>System.out.println(" 近期天氣變化:" + weather);</p><p>}</p><p>}  

 

用戶端調用:氣象局(WeatherService)  

public class WeatherService {</p><p>public static void main(String[] args) {<br />Earth earth = new Earth();<br />Satellite satellite = new Satellite();</p><p>// 註冊,務必添加<br />earth.addObserver(satellite);</p><p>System.out.println(" 天氣預報: ");<br />System.out.println(" ------------ ");<br />earth.setWeather(" 颱風‘珍珠’逼近 ");<br />earth.setWeather(" 大到暴雨 ");<br />earth.setWeather(" 天氣炎熱 ");<br />}</p><p>}<br />  

 

[運行結果]  

天氣預報:

------------

近期天氣變化:颱風‘珍珠’逼近

近期天氣變化:大到暴雨

近期天氣變化:天氣炎熱

 

二、設計理念1.情況描述    

      對於如何利用觀察者模式,在Eclipse RCP的視圖、對話方塊之間優雅地進行資料的傳遞,我們同樣用一個執行個體來進行介紹。假設我們要開發一個人員資訊管理的模組,人員資訊有姓名、性別屬性需要儲存,這個模組要實現人員資訊的添加、修改和刪除操作,並通過一個表來羅列所有人員資訊。

2.理念

      在這個人員資訊管理模組中,我們首先構建人員資訊模型(EO),並通過一個資料集(人員資訊資料處理站)來儲存需要顯示的人員資訊資料,而這個資料集就是我們的觀察對象,而Eclipse RCP中用來顯示人員資訊的視圖就是觀察者。當使用者通過對話方塊或其他形式修改了資料集時,RCP視圖自動作相應的重新整理顯示。

 

三、源碼實現1.源碼組成

2.程式源碼(1)dialogs.FirstDialog.java

 package dialogs;</p><p>import org.eclipse.jface.dialogs.Dialog;<br />import org.eclipse.jface.dialogs.IDialogConstants;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.graphics.Point;<br />import org.eclipse.swt.layout.FillLayout;<br />import org.eclipse.swt.layout.GridData;<br />import org.eclipse.swt.layout.GridLayout;<br />import org.eclipse.swt.widgets.Composite;<br />import org.eclipse.swt.widgets.Control;<br />import org.eclipse.swt.widgets.Label;<br />import org.eclipse.swt.widgets.Shell;<br />import org.eclipse.swt.widgets.Text;<br />import org.eclipse.ui.PlatformUI;</p><p>import pojos.Person;<br />import rcptest.View;<br />import rcptest.PersonFactory;</p><p>public class FirstDialog extends Dialog {</p><p>private Text text_1;<br />private Text text;<br />/**<br /> * Create the dialog<br /> * @param parentShell<br /> */<br />public FirstDialog(Shell parentShell) {<br />super(parentShell);<br />}</p><p>/**<br /> * Create contents of the dialog<br /> * @param parent<br /> */<br />protected Control createDialogArea(Composite parent) {<br />Composite container = (Composite) super.createDialogArea(parent);<br />container.setLayout(new FillLayout());</p><p>final Composite composite_1 = new Composite(container, SWT.NONE);<br />final GridLayout gridLayout = new GridLayout();<br />gridLayout.numColumns = 2;<br />composite_1.setLayout(gridLayout);</p><p>final Label label = new Label(composite_1, SWT.NONE);<br />label.setLayoutData(new GridData());<br />label.setText("姓名:");</p><p>text = new Text(composite_1, SWT.BORDER);<br />text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));</p><p>final Label label_1 = new Label(composite_1, SWT.NONE);<br />label_1.setText("性別:");</p><p>text_1 = new Text(composite_1, SWT.BORDER);<br />text_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));<br />//<br />return container;<br />}</p><p>/**<br /> * Create contents of the button bar<br /> * @param parent<br /> */<br />protected void createButtonsForButtonBar(Composite parent) {<br />createButton(parent, IDialogConstants.OK_ID, "確定",<br />true);<br />createButton(parent, IDialogConstants.CANCEL_ID,<br />"取消", false);<br />}</p><p>/**<br /> * Return the initial size of the dialog<br /> */<br />protected Point getInitialSize() {<br />return new Point(275, 184);<br />}<br />protected void buttonPressed(int buttonId) {<br />if (buttonId == IDialogConstants.YES_ID){<br />PersonFactory pf =((View)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(View.ID)).getFactory();<br />pf.delPerson(new Person(text.getText(), text_1.getText()));<br />}<br />if (buttonId == IDialogConstants.OK_ID) {<br />PersonFactory pf =((View)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(View.ID)).getFactory();<br />pf.addPerson(new Person(text.getText(), text_1.getText()));<br />}<br />super.buttonPressed(buttonId);<br />this.close();</p><p>}</p><p>} 

(2)pojos.Person.java

package pojos;</p><p>public class Person {<br />private String name;<br />private String sex;</p><p>public Person() {<br />this.name ="";<br />this.sex ="";<br />}<br />public Person(String name, String sex) {<br />this.name =name;<br />this.sex =sex;<br />}<br />public String getName() {<br />return name;<br />}<br />public void setName(String name) {<br />this.name = name;<br />}<br />public String getSex() {<br />return sex;<br />}<br />public void setSex(String sex) {<br />this.sex = sex;<br />}</p><p>}<br />

(3)rcptest.PersonFactory.java

package rcptest;</p><p>import java.util.HashMap;<br />import java.util.Map;<br />import java.util.Observable;</p><p>import pojos.Person;</p><p>public class PersonFactory extends Observable {<br />//private List<Person> data;<br />private static PersonFactory pf;<br />private static HashMap<String, Person> data;</p><p>private PersonFactory() {<br />}</p><p>public static PersonFactory getSinglePersonFactory() {<br />if (pf ==null) {<br />pf =new PersonFactory();<br />data =new HashMap<String, Person>();<br />data.put("張三", new Person("張三", "男"));<br />data.put("李四", new Person("李四", "女"));<br />data.put("陳二", new Person("陳二", "女"));<br />}<br />return pf;<br />}</p><p>public HashMap<String, Person> getData() {<br />return data;<br />}</p><p>public void addPerson(Person p) {<br />data.put(p.getName(), p);</p><p>/**寫入資料庫*/<br />//actions</p><p>setChanged();<br />notifyObservers(p);<br />}</p><p>public void delPerson(Person p) {<br />data.remove(p.getName());</p><p>setChanged();<br />notifyObservers(p);<br />}</p><p>public void modifyPerson(Person p) {<br />data.remove(p.getName());<br />data.put(p.getName(), p);</p><p>setChanged();<br />notifyObservers(p);<br />}</p><p>}<br />

(4)View.java

package rcptest;</p><p>import java.util.Iterator;<br />import java.util.Observable;<br />import java.util.Observer;</p><p>import org.eclipse.jface.action.Action;<br />import org.eclipse.jface.action.IMenuManager;<br />import org.eclipse.jface.action.IToolBarManager;<br />import org.eclipse.jface.viewers.StructuredSelection;<br />import org.eclipse.jface.viewers.TableViewer;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.events.SelectionAdapter;<br />import org.eclipse.swt.events.SelectionEvent;<br />import org.eclipse.swt.widgets.Button;<br />import org.eclipse.swt.widgets.Composite;<br />import org.eclipse.swt.widgets.Label;<br />import org.eclipse.swt.widgets.Shell;<br />import org.eclipse.swt.widgets.Table;<br />import org.eclipse.swt.widgets.TableColumn;<br />import org.eclipse.swt.widgets.Text;<br />import org.eclipse.ui.PlatformUI;<br />import org.eclipse.ui.part.ViewPart;</p><p>import com.swtdesigner.SWTResourceManager;</p><p>import pojos.Person;</p><p>import dialogs.FirstDialog;</p><p>public class View extends ViewPart implements Observer{</p><p>private Table table;<br />private PersonFactory pf;<br />private TableViewer tableViewer;<br />public static final String ID = "RCPTest.view"; //$NON-NLS-1$</p><p>/**<br /> * Create contents of the view part<br /> * @param parent<br /> */<br />public void createPartControl(Composite parent) {<br />Composite container = new Composite(parent, SWT.NONE);</p><p>pf =PersonFactory.getSinglePersonFactory();<br />pf.addObserver(this);</p><p>tableViewer = new TableViewer(container, SWT.BORDER|SWT.SELECTED);<br />table = tableViewer.getTable();<br />table.setLinesVisible(true);<br />table.setHeaderVisible(true);<br />table.setBounds(0, 54, 494, 292);<br />for (int i=0; i <FirstTableArgs.LABLE.length; i++) {<br />TableColumn tc =new TableColumn(table, SWT.CENTER);<br />tc.setText(FirstTableArgs.LABLE[i]);<br />tc.setMoveable(true);<br />table.getColumn(i).pack();<br />}</p><p>tableViewer.setSorter(new FirstTableSorter());<br />TableColumn column =table.getColumn(0);<br />column.addSelectionListener(new SelectionAdapter() {<br />public void widgetSelected(SelectionEvent e) {<br />((FirstTableSorter)(tableViewer.getSorter())).doSort(FirstTableArgs.NAME);<br />tableViewer.refresh();<br />}<br />});<br />column =table.getColumn(1);<br />column.addSelectionListener(new SelectionAdapter() {<br />public void widgetSelected(SelectionEvent e) {<br />((FirstTableSorter)tableViewer.getSorter()).doSort(FirstTableArgs.SEX);<br />tableViewer.refresh();<br />}<br />});</p><p>tableViewer.setContentProvider(new FirstContentProvider());<br />tableViewer.setLabelProvider(new FirstTableLabelProvider());<br />tableViewer.setInput(pf);</p><p>final Button button = new Button(container, SWT.NONE);<br />button.addSelectionListener(new SelectionAdapter() {<br />public void widgetSelected(final SelectionEvent e) {<br />FirstDialog fd =new FirstDialog(new Shell());<br />fd.open();<br />}<br />});<br />button.setText("增加");<br />button.setBounds(25, 15, 48, 22);</p><p>final Button button_1 = new Button(container, SWT.NONE);<br />button_1.addSelectionListener(new SelectionAdapter() {<br />public void widgetSelected(final SelectionEvent e) {<br />View fv =(View)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(View.ID);<br />TableViewer tv=fv.getTableViewer();<br />StructuredSelection ss =(StructuredSelection)tv.getSelection();<br />Iterator it =ss.iterator();<br />while(it.hasNext()) {<br />fv.getFactory().delPerson((Person)it.next());<br />}<br />}<br />});<br />button_1.setText("刪除");<br />button_1.setBounds(90, 15, 48, 22);<br />//<br />createActions();<br />initializeToolBar();<br />initializeMenu();<br />}</p><p>/**<br /> * Create the actions<br /> */<br />private void createActions() {<br />// Create the actions<br />}</p><p>/**<br /> * Initialize the toolbar<br /> */<br />private void initializeToolBar() {<br />IToolBarManager toolbarManager = getViewSite().getActionBars()<br />.getToolBarManager();</p><p>}</p><p>/**<br /> * Initialize the menu<br /> */<br />private void initializeMenu() {<br />IMenuManager menuManager = getViewSite().getActionBars()<br />.getMenuManager();<br />}</p><p>public void setFocus() {<br />// Set the focus<br />}</p><p>public void setText(String st) {<br />}</p><p>public TableViewer getTableViewer() {<br />return tableViewer;<br />}</p><p>public PersonFactory getFactory() {<br />return pf;<br />}</p><p>public void update(Observable obj, Object arg) {<br />tableViewer.refresh();<br />}<br />}<br />

(5)FirstContentProvider.java

package rcptest;</p><p>import java.util.ArrayList;<br />import java.util.HashMap;<br />import java.util.Iterator;<br />import java.util.List;<br />import java.util.Set;</p><p>import org.eclipse.jface.viewers.IStructuredContentProvider;<br />import org.eclipse.jface.viewers.Viewer;</p><p>import pojos.Person;</p><p>public class FirstContentProvider implements IStructuredContentProvider {</p><p>public Object[] getElements(Object inputElement) {</p><p>PersonFactory pf =(PersonFactory)inputElement;<br />List list =new ArrayList();</p><p>HashMap<String, Person> map=pf.getData();<br />Set set =pf.getData().keySet();<br />Iterator iterator =set.iterator();<br />while (iterator.hasNext()) {<br />list.add(map.get(iterator.next()));<br />}<br />return list.toArray();<br />}</p><p>public void dispose() {<br />// TODO Auto-generated method stub</p><p>}</p><p>public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {<br />// TODO Auto-generated method stub</p><p>}</p><p>}<br />

(6)FirstLabelProvider.java

package rcptest;</p><p>import org.eclipse.jface.viewers.ILabelProviderListener;<br />import org.eclipse.jface.viewers.ITableLabelProvider;<br />import org.eclipse.swt.graphics.Image;</p><p>import pojos.Person;</p><p>public class FirstTableLabelProvider implements ITableLabelProvider {</p><p>public Image getColumnImage(Object element, int columnIndex) {<br />// TODO Auto-generated method stub<br />return null;<br />}</p><p>public String getColumnText(Object element, int columnIndex) {<br />Person ps =(Person)element;<br />if (columnIndex ==FirstTableArgs.ID[0]) {<br />return ps.getName()+"";<br />} else if (columnIndex ==FirstTableArgs.ID[1]) {<br />return ps.getSex()+"";<br />}<br />return "";<br />}</p><p>public void addListener(ILabelProviderListener listener) {<br />// TODO Auto-generated method stub</p><p>}</p><p>public void dispose() {<br />// TODO Auto-generated method stub</p><p>}</p><p>public boolean isLabelProperty(Object element, String property) {<br />// TODO Auto-generated method stub<br />return false;<br />}</p><p>public void removeListener(ILabelProviderListener listener) {<br />// TODO Auto-generated method stub</p><p>}</p><p>}<br />

(7)FirstTableSorter.java

package rcptest;</p><p>import org.eclipse.jface.viewers.Viewer;<br />import org.eclipse.jface.viewers.ViewerComparator;<br />import org.eclipse.jface.viewers.ViewerSorter;</p><p>import pojos.Person;</p><p>public class FirstTableSorter extends ViewerSorter {</p><p>private static final int ASCENDING =0;<br />private static final int DESCENDING =1;</p><p>private int order;<br />private int column;</p><p>public void doSort(int column) {<br />if (column ==this.column) {<br />order =1-order;<br />} else {<br />this.column =column;<br />order =ASCENDING;<br />}<br />}</p><p>public int compare(Viewer viewer, Object e1, Object e2) {<br />int result =0;<br />ViewerComparator vc =new ViewerComparator();</p><p>Person p1 =(Person)e1;<br />Person p2 =(Person)e2;</p><p>switch(column) {<br />case FirstTableArgs.NAME:<br />result =vc.compare(viewer, p1.getName(), p2.getName());<br />break;<br />case FirstTableArgs.SEX:<br />result =vc.compare(viewer, p1.getSex(), p2.getSex());<br />break;<br />};<br />if (order ==DESCENDING) {<br />result =-result;<br />}<br />return result;<br />}</p><p>}<br />

(8)FirstTableArgs.java

package rcptest;</p><p>public class FirstTableArgs {<br />public final static int ID[] ={0, 1};<br />public final static int NAME =0;<br />public final static int SEX =1;<br />public final static String LABLE[] ={"姓名", "性別"};<br />}<br />

 

四、參考

http://koskoswh1.blog.163.com/blog/static/126433078200972402933608/

http://blog.csdn.net/wsh622827/archive/2009/11/01/4755140.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.