1 回答
TA贡献2065条经验 获得超13个赞
回答
除了两个问题外,您似乎已正确设置所有内容。
你永远不会添加一个EventHandler监听你的事件的。
实现任意接口不会使您的对象对您的自定义事件做出反应。事件处理系统不知道你的接口,甚至不知道你已经实现了它。如果您希望onMyEvent()在事件到达标签时调用您的方法,则需要执行以下操作:
public MyLabel() {
//...
addEventHandler(MyEvent.MY_EVENT, event -> onMyEvent());
}
请注意,我使用addEventHandler的是类本身不依赖于该onMyEvent属性。如果您依赖该属性,则外部代码可能会通过替换EventHandler.
这让我想知道MyEventListener接口是否真的有必要。你不能在里面做你需要的EventHandler吗?
您实际上从未触发过您的MyEvent.
您目前拥有:
btnSender.setOnAction(e -> MyEvent.fireEvent(lblReceiver, e));
这只是将e(an ActionEvent) 重新点燃到lblReceiver. 该fireEvent方法是由static声明的方法javafx.event.Event。为方法调用加上前缀MyEvent不会改变此处实际调用的方法。将其更改为以下内容:
btnSender.setOnAction(e -> Event.fireEvent(lblReceiver, new MyEvent()));
// or...
btnSender.setOnAction(e -> lblReceiver.fireEvent(new MyEvent()));
// The second option is a convenience method and simply forwards to Event.fireEvent
为了在您的标签上实际触发您自己的事件类的实例。
事件派发基础
JavaFX 中的事件处理有两个阶段:
捕获阶段
第一阶段。在这里,事件从其路径的起点向下传播到目标。在此过程中的每一步,都会调用适当的事件过滤器。过滤器是通过诸如
Node.addEventFilter(EventType,EventHandler)
.冒泡阶段
第二阶段。在这里,事件从目标返回到路径的起点。在此过程中的每一步,都会调用适当的事件处理程序。处理程序是通过诸如 和 之类的方法和
Node.addEventHandler(EventType,EventHandler)
属性添加的。Node.onKeyPressed
ButtonBase.onAction
事件处理由以下组件组成:
javafx.event.Event
(和子类)实际对象传递过来。携带与事件相关的信息(例如
MouseEvent
s 的光标位置)。一个
Event
也携带来源。但是,来源是动态的;它始终是EventHandler
当前处理事件的对象。因此,EventHandler
添加到 a的事件Button
将具有Button
作为事件源的事件,但同一事件将具有父级作为EventHandler
添加到父级的源。即使您EventHandler
两次使用同一个实例,此行为也不会改变。细化一类的含义
Event
。例如,MouseEvent
带有MOUSE_PRESSED
类型的 a 毫不奇怪地表示鼠标被按下了。一个EventType
有一个超类型;这为每种事件形成了所有类型的层次结构。为超类型注册的处理程序也将收到子类型的通知。不能有两个或多个
EventType
具有相同超类型和名称的 s。这就是为什么实例通常public static final
是相应事件类的字段。处理其注册的任何事件。这是一个功能接口(可以是 lambda 表达式或方法引用的目标)。执行应用程序级工作的是此接口的实现(即,在触发按钮时执行某些操作)。
负责将事件分派给适当的处理程序。每个能够成为事件目标的对象通常都有自己的调度程序。例如,每个
Window
、Scene
和Node
instance 都有自己的EventDispatcher
实例(保存在属性中)。注意:在高度专业化的情况之外,您永远不必直接处理此接口。
表示事件在目标处触发时将采用的路径。此接口的实例用作
EventDispatcher
s 的堆栈。触发事件时,将根据事件的目标创建和配置新链。在场景图和目标是 a 的情况下Node
,堆栈由EventDispatcher
属于 s的 s 组成Window
,Scene
然后每个Node
向下到(父到子)并包括目标。事件沿这条链向下传播(捕获阶段),然后返回这条链(冒泡阶段)。注意:您可能永远不需要直接使用此界面。
事件的实际目标。该
EventTarget
接口具有一种用于构建EventDispatchChain
. 换句话说,目标决定了事件的路径。这是中的第一个参数Event.fireEvent(EventTarget,Event)
。注意:如果您正在创建一个可以(显然)成为事件目标的对象(并且您的对象不是从 的实现扩展的
EventTarget
),则只需要使用此接口。
添加回答
举报