我有一个TextField,如果用户单击不是其本身的任何位置,我想做些事情TextField。
onMouseClicked如果您不单击节点本身,则事件不会触发,因此将无法正常工作。focusedProperty可能是一个好主意,但问题是我的应用程序几乎整个都无法遍历焦点,因此在许多情况下,在文本字段之外单击不会使焦点不集中,因此不会通知侦听器。我唯一想做的就是在事件本身上放置一个事件过滤器,拦截鼠标单击,获取单击坐标并确定它们是否在文本框的范围内。我发现这有点矫kill过正,我可能会缺少一些显而易见的东西。
还有另一种方法来确定用户是否单击了我TextField节点之外的任何地方?
我唯一想做的就是在事件本身上放置一个事件过滤器,拦截鼠标单击,获取单击坐标并确定它们是否在文本框的范围内。我发现这有点矫kill过正,我可能会缺少一些显而易见的东西。
实际上,我认为这是您最好的选择,但有一些变化:
使用该PickResult由提供MouseEvent以获得目标Node和检查,如果它在的层次结构Node。(如果Node具有子元素,则这可能是必要的;例如,a TextField也包含一个Text元素。)
实际上,这似乎是无法通过消耗场景图中某个地方的事件来打破的唯一选择。
如果用户单击以外的其他位置,这会将焦点移到根窗格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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2737 次 |
| 最近记录: |