如何确定用户是否在特定JavaFX节点外单击? [英] How to determine if the user clicked outside a particular JavaFX node?

查看:181
本文介绍了如何确定用户是否在特定JavaFX节点外单击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 TextField ,如果用户点击任何地方 ,我想做点什么 TextField 本身。

I have a TextField, and I would like to do something if the user clicks anywhere that is not the TextField itself.


  • 显然, onMouseClicked 事件如果你没有点击节点本身就不会触发,这样就行了。

  • focusedProperty 可能有这是一个好主意,但问题是几乎整个应用程序都不能通过焦点遍历,因此在很多情况下,在文本字段外单击不会使它失去焦点,因此不会通知监听器。

  • Apparently, the onMouseClicked event won't trigger if you don't click the node itself, so that wouldn't work.
  • Listening the focusedProperty may have been a good idea, but the problem is that almost the entirety of my application is not focus traversable, so in many cases clicking outside the textfield won't unfocus it, so the listener won't be notified.

我唯一想到的就是在场景上放置一个事件过滤器,拦截鼠标点击,获取点击坐标并确定它们是否属于文本区域的边界。我发现这有点矫枉过正,我可能会遗漏一些更明显的东西。

The only thing left in my mind is to put an event filter on the scene itself, intercept mouse clicks, get the click coordinates and determine if they fall within the bounds of the textfield. I find this a little bit overkill and I may be missing something more obvious.

还有另一种方法可以确定用户是否点击了之外的任何地方TextField 节点?

Is there another way to determine if the user clicked anywhere outside my TextField node?

推荐答案


我唯一想到的是在场景本身上放置一个事件过滤器,拦截鼠标点击,获取点击坐标并确定它们是否属于文本字段的范围。我发现这有点矫枉过正,我可能会遗漏一些更明显的东西。

The only thing left in my mind is to put an event filter on the scene itself, intercept mouse clicks, get the click coordinates and determine if they fall within the bounds of the textfield. I find this a little bit overkill and I may be missing something more obvious.

事实上我认为这是你最好的选择,但是变体:

In fact I consider this your best option, but with a variation:

使用 PickResult MouseEvent 提供目标节点并检查它是否在节点的层次结构中。
(如果节点有子节点,这可能是必要的;例如 TextField 也包含文本元素。)

Use the PickResult provided by the MouseEvent to get the target Node and check, if it's in the hierarchy of the Node. (This can be necessary, if the Node has children; e.g. a TextField also contains a Text element.)

事实上,这似乎是唯一一个不能通过在场景图。

In fact this seems to be the only option that cannot be broken by consuming the event somewhere in the scene graph.

这会将焦点移动到根窗格,以防用户点击除了 TextField

This moves the focus to the root pane in case the user clicks somewhere except the TextField.

public static boolean inHierarchy(Node node, Node potentialHierarchyElement) {
    if (potentialHierarchyElement == null) {
        return true;
    }
    while (node != null) {
        if (node == potentialHierarchyElement) {
            return true;
        }
        node = node.getParent();
    }
    return false;
}

@Override
public void start(Stage primaryStage) {
    TextField textField = new TextField();
    textField.setMinSize(400, Region.USE_PREF_SIZE);
    textField.setMaxWidth(400);
    textField.setEditable(false);
    textField.textProperty().bind(Bindings.when(textField.focusedProperty()).then("Got the Focus!").otherwise("Please give me the focus!"));

    StackPane root = new StackPane();
    root.getChildren().add(textField);

    Scene scene = new Scene(root, 500, 200);

    scene.addEventFilter(MouseEvent.MOUSE_CLICKED, evt -> {
        if (!inHierarchy(evt.getPickResult().getIntersectedNode(), textField)) {
            root.requestFocus();
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}

这篇关于如何确定用户是否在特定JavaFX节点外单击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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