您的位置:首页 > 产品设计 > UI/UE

java:Observable/Observer模式在SWT环境下UI线程/非UI线程的透明化调用

2016-12-15 14:44 501 查看
观察者模式(Observable/Observer)在UI设计方面非常有用,可以通过Observer来实现UI界面的更新,因而可以实现UI层与业务层的分离。

但是我们知道大部分UI框架(比如SWT)都要区分UI线程和非UI线程,如果Observable对象在非UI线程执行notifyObservers操作,而Observer的update方法又涉及UI对象的操作时就会抛出异常。(参见 《SWT的UI线程和非UI线程》)

如果Observer的代码不用关心自己是不是在UI线程,就可以降低Observer代码的复杂度,所以为解决这个问题,我对Observable做了进一步封装。

SWTObservable.java

package net.gdface.ui;

import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import org.eclipse.swt.widgets.Display;

/**
* SWT环境下对{@link Observable}的易用性封装<br>
* 实现{@link Observer}类型的侦听器在SWT下UI线程/非UI线程的透明化调用
* @author guyadong
*
*/
public class SWTObservable extends Observable {
/**
* {@link Observer}在SWT环境下的重新封装<br>
* 实现UI/非UI线程透明化
* @author guyadong
*
*/
class SWTObserver implements Observer {
final Observer observer;
/**
* 私有构造方法
* @param observer
*/
private SWTObserver(Observer observer) {
super();
if (null == observer)
throw new IllegalArgumentException("the argument observer must not be null");
this.observer = observer;
}
@Override
public void update(Observable o, Object arg) {
// 判断UI/非UI线程,区别对待
if (display.getThread() == Thread.currentThread()) {
observer.update(o, arg);
} else {
// 非UI线程下调用 Display.syncExec方法执行
display.syncExec(new Runnable() {
@Override
public void run() {
observer.update(o, arg);
}
});
}
}
}
/**
* 保存所有被 {@link Observable#addObserver(Observer)}方法添加的 {@link SWTObserver}对象,<br>
* 以便在 {@link Observable#deleteObserver(Observer)}删除{@link Observer}对象时查找到对应的{@link SWTObserver}对象
*/
private final Vector<SWTObserver> listeners=new Vector<SWTObserver>();
private final Display display;
SWTObservable(Display display) {
if (null == display)
throw new IllegalArgumentException("the argument display must not be null");
this.display = display;
}
/**
* 在 {@link #listeners}中 查找{@link Observer}对应的{@link SWTObserver}对象,找不到则返回null
* @param listener
* @return
*/
private SWTObserver find(Observer listener){
for(SWTObserver o:this.listeners){
if(o.observer==listener)return o;
}
return null;
}
@Override
public synchronized void addObserver(Observer o) {
add(o);
}

@Override
public synchronized void deleteObserver(Observer o) {
delete(o);
}
synchronized SWTObserver add(Observer o) {
if (null==find(o)) {
SWTObserver obs = new SWTObserver(o);
this.listeners.add(obs);
super.addObserver(obs);
return obs;
}
return null;
}
synchronized SWTObserver delete(Observer o) {
SWTObserver obs = find(o);
if(null!=obs){
this.listeners.remove(obs);
super.deleteObserver(obs);
}
return obs;
}
@Override
public void notifyObservers(Object arg) {
setChanged();
super.notifyObservers(arg);
}
}


参考资料:

《设计模式之观察者模式(Observable与Observer)》http://www.cnblogs.com/xudong-bupt/p/3428108.html

《SWT的UI线程和非UI线程》http://blog.csdn.net/dollyn/article/details/38582743
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息