SwingWorker任务队列
RemoteTable用一个QueuedExecutor调度它的SwingWorker任务,QueuedExecutor在单个线程中顺序执行所有的任务。(QueuedExecutor是DougLea的util.concurrent包的一部分,请参见后面的“参考资料”部分。)远程模型用RMI回调操作通知它的监听器。
为了支持可视的反馈,RemoteTable发送Task事件给注册的Task监听器。在任务进入调度时,监听器的taskStarted()被调用,taskEnded()在任务完成时被调用。客户端演示程序使用这些事件来启动或停止一个小动画并更新状态来。
执行次序
表示的是单元格的更新过程。执行过程的开始和结束都位于左边的事件派发线程。SwingWorker任务则在右边的executor的线程中执行。Worker的finished()方法的执行过程没有表示出来。
SwingWorker任务简化
简单起见,远程模型并没有对互相冲突的编辑提供保护。所以在同一时刻仅能有一个编辑器在运行。(并发编辑可以用添加请求ID(requestIDs)的方法来实现。)
所作的另一项简化决定是客户端和服务器必须预先对表的列结构协商好。换句话说,服务器性客户端提供行数据,而客户端必须已经知道他们要处理的是什么表。演示用的客户端用DefaultModelTemplate来预先定义了各列的名称和类,来确定哪个单元格可以被编辑。(在演示程序中,前两列是不可编辑的。)
本节的余下部分阐述了类结构和实现。如果不想了解这个演示程序中所用的修订版的SwingWorker,你可以跳过去。“下载”一节解释了如何下载并运行这个演示程序。
SwingWorker任务实现
远程模型实现了RemoteTableModel接口,这个接口和AbstractTableModel很相似,除了它的所有方法都会抛出异常。要启动一个客户端,远程表模型发送一个完全更新事件给客户端已注册的的监听器。
RemoteTableModelAdapter配接任意的TableModel到一个RemoteTableModel。演示程序中的表模型取自TheJavaTutorial,但插入了一些延迟来模拟实际情况。远程表模型事件包含已更新的单元格的值。
RemoteTable 组件用一个DefaultRemoteTableModelListener来接受来自远程模型的回调。这个监听器会在事件派发线程中更新本地模型。因为远程模型可能要通知插入或删除某些行,所以监听器要求本地模型支持插入和删除操作,DefaultTableModel满足这个要求。
【编辑推荐】