JavaFX:用于父级及其子级的鼠标单击事件

时间:2017-11-20 12:43:21

标签: java javafx

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

当卡片中出现时,无论是卡片本身还是其中一个孩子,我都需要随时抓住on mouse clicked事件。目前,如果单击文本字段,则不会触发事件。

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

与上面的示例一样,如果单击文本字段键入内容,则不会打印"Clicked!"

1 个答案:

答案 0 :(得分:4)

您可以使用

执行此操作
card.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> System.out.println("Clicked!"));

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

在事件处理的任何阶段,过滤器或处理程序可能consume事件。这基本上阻止了事件的任何进一步传播。有些控件有内置的处理程序,它们会消耗某些事件;示例中的文本字段是一个。因此,鼠标单击文本字段将不会传播到父节点中的处理程序。注册事件过滤器而不是处理程序允许事件由处理程序处理。