我试图想出一个解决方案,允许多个窗格节点在组装成StackPane时独立处理鼠标事件
StackPane
Pane 1
Pane 2
Pane 3
我希望能够在每个子级中处理鼠标事件,并且第一个调用消费()的子级会停止将事件传递给下一个子级。
我也知道setPickOnBands(false),但这并不能解决所有情况,因为一些覆盖将基于Canvas的像素,即不涉及场景图。
我用Node.fireEvent()
尝试了各种实验。然而,这些总是导致递归以堆栈溢出告终。这是因为事件是从根场景传播的,并再次触发相同的处理程序。
我要寻找的是一些方法来单独触发子窗格上的事件处理程序,而不让事件通过其正常路径。
到目前为止,我最好的解决方法是使用过滤器捕获事件并手动调用处理程序。我需要为MouseMove等重复此操作
parent.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
for (Node each : parent.getChildren()) {
if (!event.isConsumed()) {
each.getOnMouseClicked().handle(event);
}
}
event.consume();
});
然而,这只会触发使用setOnMouseClicked添加的侦听器,而不是addEventHandler,并且仅在该节点上,而不是子节点上。
另一种解决方案是接受JavaFX不是这样工作的,并像这样重组窗格,这将允许正常的事件传播发生。
Pane 1
Pane 2
Pane 3
import javafx.application.Application;
import javafx.event.Event;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class EventsInStackPane extends Application {
public static void main(String[] args) {
launch(args);
}
private static class DebugPane extends Pane {
public DebugPane(Color color, String name) {
setBackground(new Background(new BackgroundFill(color, CornerRadii.EMPTY, Insets.EMPTY)));
setOnMouseClicked(event -> {
System.out.println("setOnMouseClicked " + name + " " + event);
});
addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
System.out.println("addEventHandler " + name + " " + event);
});
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
System.out.println("addEventFilter " + name + " " + event);
});
}
}
@Override
public void start(Stage primaryStage) throws Exception {
DebugPane red = new DebugPane(Color.RED, "red");
DebugPane green = new DebugPane(Color.GREEN, "green");
DebugPane blue = new DebugPane(Color.BLUE, "blue");
setBounds(red, 0, 0, 400, 400);
setBounds(green, 25, 25, 350, 350);
setBounds(blue, 50, 50, 300, 300);
StackPane parent = new StackPane(red, green, blue);
eventHandling(parent);
primaryStage.setScene(new Scene(parent));
primaryStage.show();
}
private void eventHandling(StackPane parent) {
parent.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
if (!event.isConsumed()) {
for (Node each : parent.getChildren()) {
Event copy = event.copyFor(event.getSource(), each);
parent.fireEvent(copy);
if (copy.isConsumed()) {
break;
}
}
}
event.consume();
});
}
private void setBounds(DebugPane panel, int x, int y, int width, int height) {
panel.setLayoutX(x);
panel.setLayoutY(y);
panel.setPrefWidth(width);
panel.setPrefHeight(height);
}
}
使用@jewelsea的提示,我可以使用自定义链。我从添加到堆栈窗格前面的“catcher”窗格中完成了此操作。然后,使用所有子项按相反顺序构建一个链,不包括自身。
private void eventHandling(StackPane parent) {
Pane catcher = new Pane() {
@Override
public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
EventDispatchChain chain = super.buildEventDispatchChain(tail);
for (int i = parent.getChildren().size() - 1; i >= 0; i--) {
Node child = parent.getChildren().get(i);
if (child != this) {
chain = chain.prepend(child.getEventDispatcher());
}
}
return chain;
}
};
parent.getChildren().add(catcher);
}
我有以下代码来显示(自定义by-mvn repo) 问题是, > 我希望在鼠标输入时显示弹出窗口-工作正常。 我希望在用户从标签退出鼠标时隐藏弹出窗口,但在弹出窗口中输入鼠标时不隐藏弹出窗口。 我已经在标签上添加了鼠标插入和鼠标退出操作,但如何处理另一种情况,即如果用户输入鼠标进入弹出窗口,我不想隐藏弹出窗口。
捕获和冒泡允许我们实现一种被称为 事件委托 的强大的事件处理模式。 这个想法是,如果我们有许多以类似方式处理的元素,那么就不必为每个元素分配一个处理程序 —— 而是将单个处理程序放在它们的共同祖先上。 在处理程序中,我们获取 event.target 以查看事件实际发生的位置并进行处理。 让我们看一个示例 —— 反映中国古代哲学的 八卦图。 如下所示:在新窗口中打开 在沙箱中打开 其 HTML 如
您好,当鼠标单击stackpane(父)时,我试图取消选择listview项。我尝试了这段代码,但当用户单击按钮(Stackpane的子项)时,事件仍然被触发: 如何仅触发stackpane鼠标事件单击?
主要内容:为什么要使用事件委托,事件委托实现原理,事件委托的优点,总结利用 JS 事件冒泡动态为元素绑定事件的方法称为事件委托(Event Delegation,也称为“事件代理”),是 JavaScript 中最热门的技术之一。 事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。 举个简单的例子,整个宿舍的同学都需要去取快递,一种方法是让他们
本文向大家介绍C#中的委托是什么?事件是不是一种委托?事件和委托的关系。相关面试题,主要包含被问及C#中的委托是什么?事件是不是一种委托?事件和委托的关系。时的应答技巧和注意事项,需要的朋友参考一下 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的指针。 委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实
本文向大家介绍事件委托的优点?相关面试题,主要包含被问及事件委托的优点?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 把一个元素响应事件(click、keydown......)的函数委托到另一个元素; 优点:减少内存消耗、动态绑定事件。