JavaFX2事件分派到底层节点

JavaFX2事件分派到底层节点,java,event-handling,javafx-2,javafx,Java,Event Handling,Javafx 2,Javafx,有没有正确的方法来解决两个同级窗格之间的事件传播问题 例如,我们有一个内部有两个窗格的StackPane StackPane p = new StackPane(); Region p1 = new Region(); Region p2 = new Region(); p.getChildren().addAll(p1, p2); 在本例中,p2捕获鼠标事件,即使事件未被消耗,p1也无法对其作出反应 如果事件未被p2消耗,是否有正确的方法将其传播到p1 setMouseTransparent

有没有正确的方法来解决两个同级窗格之间的事件传播问题

例如,我们有一个内部有两个窗格的StackPane

StackPane p = new StackPane();
Region p1 = new Region();
Region p2 = new Region();
p.getChildren().addAll(p1, p2);
在本例中,p2捕获鼠标事件,即使事件未被消耗,p1也无法对其作出反应

如果事件未被p2消耗,是否有正确的方法将其传播到p1

setMouseTransparent无法解决我的问题,因为我需要两个子元素都对鼠标作出反应


感谢您的建议。

默认情况下,事件只会向上传播继承权并在根目录处终止。有几种方法可以解决您的问题

  • 创建自己的事件实例。将事件处理程序添加到触发共享事件实例的两个区域。将您希望跨区域通用的任何事件处理代码添加到共享实例中。这是我将从你给出的描述中采用的方法
  • 在根节点捕获所有事件,并创建一个每个人都可以注册的全局事件寄存器,而不是让它们死掉
  • 在第一个区域创建事件处理程序,捕获事件并在第二个区域重新修补它们(使用
    buildEventDispatchChain.dispatchEvent
    )。然后在另一边做同样的事情

  • 我的问题部分解决了。也许我对这个问题的表述不太正确。 我编写的应用程序类似于图形编辑器,在stackpane上有工具层窗格,其中包含向导、网格、选择工具等。我需要这些层的子层能够处理鼠标,并且窗格本身对于鼠标事件是透明的

    这个问题是通过重写pickNode解决的,它不在公共API中,但可以工作。 也许可以帮助别人

    protected Node impl_pickNodeLocal(double localX, double localY) {
        if (containsBounds(localX, localY)) {
            ObservableList<Node> children = getChildren();
            for (int i = children.size()-1; i >= 0; i--) {
                Node picked = children.get(i).impl_pickNode(localX, localY);
                if (picked != null) return picked;
            }
            // hack to make pane itself transparent for mouse
            // if (contains(localX, localY)) return this;
        }
        return null;
    }
    
    protectednode impl\u pickNodeLocal(双localX,双localY){
    if(包含边界(localX,localY)){
    ObservableList children=getChildren();
    对于(int i=children.size()-1;i>=0;i--){
    拾取的节点=children.get(i).impl\u pickNode(localX,localY);
    如果(已拾取!=null)返回已拾取;
    }
    //黑客使窗格本身对鼠标透明
    //如果(包含(localX,localY))返回此值;
    }
    返回null;
    }
    
    只需在事件处理程序中捕获事件,并在其他组件上触发它:

    top.addEventHandler(EventType.ROOT, event -> bottom.fireEvent(event));
    

    您仍然可以在顶部组件上添加鼠标侦听器,而且效果很好。如果底部组件对事件进行了更多的处理,您可能需要克隆并调整它。这也适用于两个以上的孩子。

    尝试这一方法也可能有效

    p1.setEventDispatcher(p2.eventDispatcherProperty().get()); 
    

    请看,这已经不起作用了。
    impl.*
    -方法已被弃用,“有效私有”和final。