By cszhao1980
现在,实现Undo功能已经比较简单了:
(1) 建立一个“普通”的UndoableEdit对象,完成真正的Undo()、Redo()功能;
(2) 建立一个UndoManager对象,作为“普通”UndoableEdit对象的观察者;
(3) 建立一个UndoableEditSupport对象,辅助建立两者之间的观察关系。
观察这三条,发现他们其实是具有高内聚的一组对象,我们完全可以把他们合起来,对外展现一个对象——即Swing提供的StateEdit类。
【注】:StateEdit类实现了UndoableEdit接口,没有实现UndoableEditListener接口,这其实很容易理解,既然他们变成了一个类,又何必使用事件传递信息呢。
StateEdit可以保持两个状态,在两个状态之间切换,从而实现redo()、undo()功能。这两个状态是通过两个Hashtable来保存的,我们通过以下两个方法实现状态切换:
void |
restoreState(Hashtable<Object, Object> state) |
void |
storeState(Hashtable<Object, Object> state) |
使用Hashtable有很多好处:
(1) StateEdit的一个状态可以记录多个对象的内容,即实现了组合Edit;
(2) 按照键值(可使用对象句柄)可以提取每个对象的内容,从而完成每个对象的Undo、Redo。
StateEdit的undo()、redo()会自动调用restoreState()方法来完成操作,因此,我们必须重载该方法,以真正完成undo、redo操作——这很容易实现,通过传入的Hashtable,我们可以轻易获取存放的对象和其中的内容,逐一更新即可。
前面说过,StateEdit含有两个状态——也就维护了两个Hashtable。但是storeState(Hashtable<Object, Object> state)方法仅有一个。而且,传入的是“New状态” Hashtable,“old状态”Hashtable会被自动维护,我们不需要处理。
另一个重要的方法是end()
void |
end() |
该方法会自动调用storeState(HashtableObject, Object> state)方法——事实上,在使用stateEdit对象时,一般不直接调用storeState,而是通过end()方法。
借助StateEdit类,我们很容易实现连续UNDO、REDO的功能。我们可以为每次编辑创立一个StateEdit对象,并维护好每个对象的前后关系。我们要做的就是找到正确的StateEdit对象——剩下的事情,交给它就好了。