看JSlider的jdk源码学观察者模式
来源:互联网 发布:视频php服务器配置 编辑:程序博客网 时间:2024/04/29 13:10
有很多Swing组建都是用MVC体系结构,其中Model层结合观察者模式通知所有观察该组件的对象。看JSlider类的部分源代码(其他的Swing组件有些是类似的):
public JSlider(int i, int j, int k, int l) { changeListener = createChangeListener(); sliderModel = new DefaultBoundedRangeModel(l, 0, j, k); sliderModel.addChangeListener(changeListener); updateUI(); }public JSlider(BoundedRangeModel boundedrangemodel) { changeListener = createChangeListener(); setModel(boundedrangemodel); sliderModel.addChangeListener(changeListener); updateUI(); }
可以看到JSlider的构造方法有两种,一种指定长宽的,另一种指定Model的,所指定的model必须是BoundedRangeModel接口的实现类,默认的Model为DefaultBoundedRangeModel。updateUI方法和MVC结构有关,这里先不说,我们讨论观察者模式。
构造器先new一个DefaultBoundedRangeModel类型的model,然后为它添加观察者,这里就是changeListener对象了,该对象是通过 createChangeListener()创建出来的,我们看看这个方法:
protected ChangeListener createChangeListener() { return new ModelListener(); }
其中ModelListener是JSlider的内部类:
private class ModelListener implements ChangeListener, Serializable { public void stateChanged(ChangeEvent changeevent) { fireStateChanged(); } final JSlider this$0; private ModelListener() { this$0 = JSlider.this; super(); } }
ModelListener实现了ChangeListener接口,任何实现了该接口的类都可以观察JSlider对象,通过上面的addChangeListener()方法,这也是我们通常所说的监听器,这正类似于我们所熟悉的addActionListener()方法,只不过监听的对象变了,由按钮变成了滑块而已。我们再看看addChangeListener的实现:
public void addChangeListener(ChangeListener changelistener) { listenerList.add(javax/swing/event/ChangeListener, changelistener); }
原来JSlider内部维护一个listenerList链表(EventListenerList listenerList其实是在父类JComponent中定义的),我们添加的观察者都被添加到了这个链表。当JSlider的model发生变化时,就会通知所有的观察者,那么是怎么观察的呢?这正是观察者模式的神奇之处。当JSlider的model发生变化时,会调用内部类ModelListener的stateChanged()方法,从源代码可以看到,该方法调用fireStateChanged():
protected void fireStateChanged() { Object aobj[] = listenerList.getListenerList(); for(int i = aobj.length - 2; i >= 0; i -= 2) { if(aobj[i] != javax/swing/event/ChangeListener) continue; if(changeEvent == null) changeEvent = new ChangeEvent(this); ((ChangeListener)aobj[i + 1]).stateChanged(changeEvent); } }
该方法依次调用listenerList链表中除了第0个的所有观察者的stateChanged()方法,这样所有的观察者就都被通知到了。分析了这么多,是时候总结了:
观察者模式通常有4类参与者:
抽象主题(Subject):在这里就是BoundedRangeModel了
抽象观察者(Observer):ChangeListener
具体主题(ConcreteSubject):DefaultBoundedRangeModel
具体观察者(ConcreteObserver):ModelListener
在抽象主题接口中,通常定义addXXXListener(),removeXXXListener(),notifyAllListener()等方法,具体主题实现该接口,并维护一个Listener链表以使每个观察者都能得到通知。在抽象观察者中,定义update()方法,被具体观察者实现,主题变化时,调用该方法。
见惯了addActionListener()这类方法,都习以为常了,便很少去想为什么。看完JSlider的观察者模式,顿时恍然大悟,有时候,多多想想这些东西对巩固基础知识还是很有好处的。。
- 看JSlider的jdk源码学观察者模式
- 从adapter源码看其中的观察者模式
- 从ListView源码看观察者模式
- JDK内部的观察者模式
- JDK自带的观察者模式
- 观察者模式-JDK和Spring的事件
- JDK自带的观察者模式
- 从观察者模式的角度看RxJava
- Java8 观察者模式详解 jdk实现源码分析
- JDK中的观察者模式
- 观察者模式-jdk
- 观察者设计模式--listView的源码分析
- 从RecyclerView的源码了解观察者模式
- 源码分析Java的观察者模式
- 如何看jdk源码
- 怎样看jdk源码
- 看源码学dagger2
- jdk的PropertyChangeSupport属性值修改的观察者模式应用
- 友好城市
- 网易博客#include<cstdio>转载
- 无锁编程入门
- CSS3+HTML5学习笔记四--CSS三栏布局-宽度只适应
- html display
- 看JSlider的jdk源码学观察者模式
- 我所理解的生活
- Positive Semi-definite matrix
- Android数据库 之 SQLite数据库(创建与使用)
- Linux 后台服务进程的开发
- 临时对象与返回值优化
- Advantages of Stainless Steel Rebar
- 球从100米高度自由落下
- java----MVC