gpt4 book ai didi

java - 在 javafx 中检测特定 Pane 外的焦点

转载 作者:行者123 更新时间:2023-12-04 02:43:43 24 4
gpt4 key购买 nike

如何检测焦点是否已离开特定 Pane ?因为 Pane (StackPane) 不可聚焦,所以我在执行此操作时遇到了麻烦。例如,我有一个带有 TextFieldStackPane,如果我按几次 Tab,它就会离开焦点 Pane 并转到另一个 Pane 。如果您离开 StackPane 的焦点,我想通过将焦点设置回 Pane 中的第一个 TextField 来防止这种行为。

这是我的尝试:

myStackPane().focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (! isNowFocused) {
setFocus(node);
}
});

但我认为这不起作用,因为 StackPane 不可聚焦。我也尝试过这样的 isFocused() 方法:

myStackPane.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if(pane.isFocused()){
System.out.println("not focused");
setFocus(node);
}else{
System.out.println("is focused");
}
});

但是,正如预期的那样,它没有产生想要的结果。

最佳答案

正如您所发现的,当 child 获得焦点时,父项的 focused 属性未设置为 true,因此检查父项是否获得焦点对您没有帮助.您必须测试新获得焦点的 Node 是否是您希望保持焦点的父节点的后代;如果不是,请将重点放在适当的 child 身上。这是一个基本示例:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application {

private static boolean isParentAncestorOfNode(Parent parent, Node node) {
if (parent == null || node == null || parent == node || node.getParent() == null) {
return false;
}

Parent current = node.getParent();
do {
if (current.equals(parent)) {
return true;
}
current = current.getParent();
} while (current != null);
return false;
}

@Override
public void start(Stage primaryStage) {
VBox innerBox = new VBox(15);
for (int i = 1; i <= 3; i++) {
innerBox.getChildren().add(new TextField("Field #" + i));
}

VBox root = new VBox(15, innerBox, new TextField("Field #4"));
root.setPadding(new Insets(25));
root.setAlignment(Pos.CENTER);
VBox.setVgrow(innerBox, Priority.ALWAYS);

Scene scene = new Scene(root);
scene.focusOwnerProperty().addListener((observable, oldNode, newNode) -> {
if (!isParentAncestorOfNode(innerBox, newNode)) {
innerBox.getChildren().get(0).requestFocus();
}
});

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

}

一旦焦点尝试转到第四个 TextField,它将转而关注第一个 TextField这是绝对的。换句话说,无论如何(例如 Tab、用鼠标单击、以编程方式请求焦点)第四个 TextField 将无法获得焦点 — 任何不是后代的东西也不会的 innerBox。我不确定这是否是所需的行为。要禁用该行为,只需从 focusOwner 属性中删除 ChangeListener(将要求您保留对监听器的引用)。当然,您可以尝试修改代码,使其更加细微。

关于java - 在 javafx 中检测特定 Pane 外的焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58100040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com