简体   繁体   English

JavaFX 2事件调度到底层节点

[英]JavaFX 2 event dispatching to underlying nodes

Is there a correct way to solve the problem with event propagation between two sibling panes? 是否有正确的方法来解决两个兄弟窗格之间事件传播的问题?

For example we have StackPane with 2 panes inside. 例如,我们的StackPane内部有2个窗格。

StackPane p = new StackPane();
Region p1 = new Region();
Region p2 = new Region();
p.getChildren().addAll(p1, p2);

p2 in this example capture mouse events and p1 can't react on it even if event is not consumed. 在此示例中,p2捕获鼠标事件,即使未消耗事件,p1也无法对其做出反应。

Is there a correct way to propagate event to p1 if it not consumed by p2? 如果没有被p2消耗,是否有正确的方法将事件传播到p1?

setMouseTransparent not solve my problem because I need that both children elements react on mouse. setMouseTransparent无法解决我的问题,因为我需要两个子元素对鼠标做出反应。

Thanks for advise. 谢谢你的建议。

By default events will just propagate up the heirarchy and terminate at the root. 默认情况下,事件将仅在层次结构中向上传播并在根处终止。 There are a few approaches you could take to solve your problem. 您可以采取一些方法来解决问题。

  1. Create your own event instance. 创建自己的事件实例。 Add an event handler to both regions that triggers your shared event instance. 向触发共享事件实例的两个区域添加事件处理程序。 Add any event handling code you want to be common across regions to the shared instance. 将您想要跨区域共同的任何事件处理代码添加到共享实例。 This is the approach I would take from the description you've given. 这是我从你给出的描述中采取的方法。
  2. Catch all events at the root and, instead of just letting them die, create a global event register that everyone can register for. 捕获根目录下的所有事件,而不是让它们死掉,创建一个每个人都可以注册的全局事件寄存器。
  3. Create an event handler at the first region and catches events and redispatches them at the second region (using buildEventDispatchChain.dispatchEvent ). 在第一个区域创建一个事件处理程序并捕获事件并在第二个区域重新分配它们(使用buildEventDispatchChain.dispatchEvent )。 Then do the same on the other side. 然后在另一边做同样的事情。

My problem was partially solved. 我的问题得到了部分解决。 Maybe I not quite correctly formulate question. 也许我没有正确地提出问题。 I write app like graphic-editor and have tools-layer panes on stackpane with guides, grid, selection-tools etc. and need that children of this layers can handle mouse and panes itself will be transparent for mouse events. 我像app-editor一样编写应用程序,并在stackpane上有工具层窗格,包括指南,网格,选择工具等。需要这些图层的子项可以处理鼠标,窗格本身对鼠标事件是透明的。

Problem was solved by override pickNode, not in public API, but it work. 问题是通过覆盖pickNode解决的,而不是在公共API中解决,但它有效。 Maybe help somebody. 也许帮助别人。

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;
}

Just catch the event in an event handler and fire it on the other components: 只需在事件处理程序中捕获事件并在其他组件上触发它:

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

You can still add mouse listeners on the top components and it works fine. 您仍然可以在顶部组件上添加鼠标侦听器,它可以正常工作。 If the bottom component does more fancy stuff with the event, you might need to clone and adjust it. 如果底部组件对事件做了更多花哨的事情,您可能需要克隆并调整它。 This also works with more than two children. 这也适用于两个以上的孩子。

Trying this might also work, 尝试这个也可行,

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

EventDispatcher Interface EventDispatcher接口

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM