event(new PointChangedEvent(selectedPoint, points[selectedPoint]));
else
event(new PointChangedEvent(selectedPoint, null));
event(new FractalChangedEvent(FractalChangedEvent.REDRAW));
break;
最后,移动点是一个特殊情况,如果不需要改变点的其他属性(例如颜色),那么所要处理的就是位置。这就是 MOVE 事件类型。在效果上,它与 POINT 事件类型效果很像,但它不需要事件生成器(通常是 FractalPanel 类)去关心那些它根本不知道的属性。
INSERT 和 DELETE 事件类型只有部分相关,可能应当属于 FractalChangedEvent 事件。
正如已经开始看到的,事件处理是 Buoy 与 Swing 最明显的不同之处。事件处理提供了大量灵活性。Buoy 本身的事件集相当丰富,且允许您挑选自己感兴趣的事件,从任何小部件向其他对象发送事件。例如,如果想在 Swing 中捕获鼠标事件,捕获事件的类需要实现 MouseListener 接口。这个接口有 5 个函数需要实现,即使它们就是摆设也必须实现。而且必须使用接口提供的函数名称。更糟的是,函数必须是侦听器接口的公共部分;要么把这作为公共接口的一部分公开,要么创建一个什么都不做、只是包装事件侦听器代码的内部类。
在 Buoy 中,每个小部件都是 EventSource 。这意味着可以从每个小部件侦听事件。什么类型的事件呢?任何类型都可以。关键的函数是 addEventLink()。这允许您指定类、侦听器以及可选的方法。每当 EventSource 分派这个类或它的子类的事件时,侦听器都会接收到事件,要么是通过一个叫做 processEvent()的方法,要么是通过在开始调用 addEventLink() 时提供的方法名称。提供的函数不能接受参数,也不能接受与指定事件类型兼容的类的对象;父类和接口可以。
这是一个方便的设置。可以把不同的事件路由到不同的函数或相同的函数。例如,MousePressedEvent 和 MouseReleasedEvent 会被分别处理。在示例程序中,鼠标的按下、释放和拖动分别有不同的线程,如清单 2 所示。注意,这远远超过 Swing 的 MouseListener 所能做的。如果用 Swing 编程的话,就需要实现 MouseListener 和 MouseMotionListener 这两个接口。
清单2. 只挑感兴趣的事件
this.addEventLink(MousePressedEvent.class, this, "mousePressed");
this.addEventLink(MouseRele