JavaFX:用于父级及其子级的鼠标单击事件 [英] JavaFX: On Mouse Clicked event for parent and its children

查看:567
本文介绍了JavaFX:用于父级及其子级的鼠标单击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张卡片,由标题,正文和页脚组成,可以包含更多节点,如标签,文本字段等。

I have a card, that consists of header, body and footer, that can consist of more nodes, like labels, text fields etc.

我需要当点击发生卡内时,无论是卡片本身还是其中一个孩子,都可以随时点击鼠标点击事件。现在,如果我单击文本字段,则不会触发事件。

And I need to catch on mouse clicked event ANY TIME when the click occurred inside the card, no matter if it was the card itself or one of its children. For now if I click text field, event is not triggered.

private StackPane newCard() {
        //card wrapper
        StackPane card = new StackPane();
        VBox cardContent = new VBox();

        JFXDepthManager.setDepth(card, 1);
        //Header
        StackPane header = new StackPane();

        VBox headerContent = new VBox();
        header.getChildren().add(headerContent);
        Label label = new Label("Card title");

        //if I click this text field, event is not triggered
        TextField groupCode = new TextField();

        headerContent.getChildren().addAll(label, groupCode);

        //body
        StackPane body = new StackPane();


        //footer
        StackPane footer = new StackPane();


        cardContent.getChildren().addAll(header, body, footer);
        card.getChildren().add(cardContent);

        //event
        card.setOnMouseClicked(event -> System.out.println("Clicked!"));

        return card;
    }

如上例所示,如果我点击文本字段键入内容, 点击!未打印。

So like in example above, if I click the text field to type something, "Clicked!" is not printed.

推荐答案

你可以用

card.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println("Clicked!"));

描述了JavaFX中事件处理的完整机制这里。简而言之,事件具有目标,在这种情况下,它是与鼠标单击相交的最顶层节点。 (直观地说,它是用户在视觉上点击的节点。)因此,如果单击文本字段,则目标是文本字段。事件调度分为两个阶段:捕获冒泡。在捕获阶段,事件首先传递到根节点,然后传递到作为目标祖先的根节点,直到它到达目标为止。在捕获阶段,将调用向相应节点注册的任何过滤器事件。事件捕获完成后,冒泡阶段开始。在冒泡阶段,事件首先传递到目标节点,然后传递到其父节点,依此类推,直到它再次到达根节点。在冒泡阶段,调用在节点注册的事件处理程序

The full mechanism of event handling in JavaFX is described here. In a nutshell, though, an event has a target, which in this case is the topmost node that intersects the mouse click. (Intuitively, it's the node on which the user clicks, visually.) So if you click in the text field, the target is the text field. There are two phases of event dispatch: capturing and bubbling. In the capturing phase, the event is first passed to the root node, then to the child node of the root that is an ancestor of the target, and so on until it reaches the target. During the capturing phase, any event filters registered with the appropriate node will be invoked. Once event capture is complete, the bubbling phase starts. In the bubbling phase, the event is first passed to the target node, then to its parent, and so on until it reaches the root node again. During the bubbling phase, event handlers registered with the node are invoked.

在事件处理的任何阶段,过滤器或处理程序可以< a href =https://docs.oracle.com/javase/9​​/docs/api/javafx/event/Event.html#consume-- =nofollow noreferrer>消费事件。这基本上阻止了事件的任何进一步传播。有些控件有内置的处理程序,它们会消耗某些事件;示例中的文本字段是一个。因此,鼠标单击文本字段将不会传播到父节点中的处理程序。注册事件过滤器而不是处理程序允许事件由处理程序处理。

At any stage of the event processing, a filter or handler may consume the event. This essentially prevent any further propagation of the event. Some controls have built-in handlers which consume certain events; the text field in your example is one. Consequently, mouse clicks on the text field will not propagate to handlers in parent nodes. Registering an event filter instead of a handler allows the event to be processed by your handler.

这篇关于JavaFX:用于父级及其子级的鼠标单击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆