JavaFX:以编程方式聚焦文本字段

22

我用JavaFX编写了一个只能通过键盘方向键使用的应用程序。 因此,我阻止了Scene舞台上的MouseEvent事件,并“监听”KeyEvents按键事件。 我还关闭了所有节点的可聚焦性:

for(Node n : children) {
     n.setFocusTraversable(false);

现在我有一些文本框、复选框和按钮。 我想通过编程方式更改输入控件(文本框、复选框等)的状态:例如,我想以编程方式进入文本框以编辑内容。 那么我的问题是:如何进入一个不可聚焦的文本框? 因为textfield.requestFocus(); 不再起作用,因为我将我的文本字段的focustraversable属性设置为false。

谢谢


如果你想以编程的方式设置文本框的值,你可以简单地使用 setText 吗?如果我误解了你的问题,请重新表述问题是什么,你尝试了什么,以及哪些方面不起作用? - Knut Arne Vedaa
我编辑了我的问题并添加了我已经做过的事情。 - PacDroid
@PacDroid,你在我的下面的回答评论中说requestFocus()正在工作。另外,根据你的评论,我编辑了我的答案并添加了更多细节。你需要澄清这个混淆点。 - Uluk Biy
是的,在单独的线程中请求焦点是可以的,谢谢 :) - PacDroid
2个回答

55

通过以下代码:

n.setFocusTraversable(false);

...节点被设置为不可聚焦而非不可获取焦点。它仍然可以通过鼠标或编程方式获得焦点。由于您阻止了鼠标事件,这里提供另一种选项:

Platform.runLater(() -> textfield.requestFocus());

Scene scene = new Scene(root);

编辑:根据评论,
requestFocus 的 Javadoc 表示:

... 要有资格接收焦点,节点必须是场景的一部分, 它和它的所有祖先必须可见,并且它不能被禁用。...

因此,在场景图构建完成后应调用此方法,如下所示:

Scene scene = new Scene(root);
textfield.requestFocus();

然而,上述代码中的Platform.runLater将在主方法start()之后运行,这确保了requestFocus的调用将在场景图构建之后进行。

根据requestFocus实现代码,可能还有其他原因。


好的,我测试过了,它可以工作。 为什么在我的父面板构造末尾加上一个简单的textfield.requestFocus();它就不能工作呢? - PacDroid
1
谢谢,现在我明白了 :) 我想我会创建自己的控件,只能通过改变它们的视觉状态的方法来聚焦。谢谢 - PacDroid
默认情况下,哪个组件会获得焦点?是第一个创建的组件,比如按钮吗? - stephanmg

2
在初始化方法中设置 .requestFocus() 以在 .fxml 文件加载控制器时触发。
@Override
public void initialize(URL url, ResourceBundle rb) {
/* the field defined on .fxml document  
@FXML
private TextField txtYear;
*/
txtYear.requestFocus();
}

在我的情况下,这不适用于 public void initialize(URL url, ResourceBundle rb)。我必须在场景创建并设置到舞台后进行设置。 - User8461
这个不起作用。 - Wortig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接