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

来源:互联网 发布:黄金交易行情软件 编辑:程序博客网 时间:2024/06/06 04:15

观察者模式(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

0 0
原创粉丝点击