事件传递过程
1、对象选择
2、线路构建
3、事件捕获
4、事件冒泡
对象选择
当动作发生时,系统判断哪个节点是对象的规则为:
键盘事件,拥有焦点的节点为对象
鼠标事件,光标所处的节点为对象
触摸屏连续的手势事件,手势开始时,所有触点中心的节点为对象;对于间接触摸屏,对象是光标存在的节点。
如果超过一个节点处于光标或触点,最上方的节点被认为是对象
当一个鼠标按键被压下并且对象已选定,所有随后的鼠标事件被传递到这个对象,至到按钮被释放。
事件捕获阶段
在事件捕获阶段,事件传递从根节点到目标节点。
如果链中的任何节点被注册了当前事件类型的过滤器,过滤器会被调用。过滤器执行完成后,事件传递到链的下一个节点。
事件冒泡阶段
当事件对象到达,并且所有注册的过滤器被执行后,事件从对象节点返回到根节点。
如果链中的任何节点被注册了当前事件类型的处理器,处理器会被调用。处理器执行完成后,事件返回到前一个节点
事件处理
过滤器与处理器最大的区别在于什么时候被执行。
事件过滤器
事件过滤器允许你在事件捕获阶段处理事件。一个节点可以有一个或多个过滤器去处理一个事件。一个过滤器可以被多个节点多个事件类型使用。过滤器允许父节点提供公共方法给他的子节点,或者拦截事件并且防止子节点运行此事件。
事件处理器
消费事件
(address: http://docs.oracle.com/javase/8/javafx/sample-apps/DraggablePanelsExample.zip)
这个例子展示了filter的如下应用:
* 注册一个超类事件的filter,提供通用功能给子类事件
* 消费一个事件,以防止子节点触发动作
(http://docs.oracle.com/javase/8/javafx/events-tutorial/img/initial_panels_screen.png)展示了这个例子启动后的界面。用户界面由3个panel组成。每一个panel包含不同的UI控件。在界面的底部是一个可选按钮,控制是否这些panel能够被拖拽。
如果可选按钮(是否拖拽)没有被选中,点击这些panel上的任何控件都会生成一个响应。如果可选按键(是否拖拽)被选中,这些个体的控件不再响应鼠标点击。而替换为,panel的任何位置并得以拖动整个panel,允许你变动panel的位置。
在这个例子里,makeDraggable()方法用来生成三个可以移动的panel。每个panel定义并注册了如下事件的filter:
* MouseEvent.ANY。panel的这个filter处理所有鼠标事件。如果可选按钮(是否拖拽)被选择,filter消费此事件,所以子节点不会收到事件信息。
* MouseEvent.MOUSE_PRESSED。panel的这个filter只处理鼠标按下事件
* MouseEvent.MOUSE_DRAGGED。panel的这个filter只处理鼠标拖动事件
注意观察,每个panel注册了三个filter。特定事件的filter会在超类事件的filter前执行,所以MouseEvent.MOUSE_PRESSED和MouseEvent.MOUSE_DRAGGED会在MouseEvent.ANY前执行。