我有一个嵌入AnchorPane的TextField以及几个按钮。 TextField默认没有焦点,因为我希望它显示提示文本(请参阅prompttext in textfield of javafx 2 hides on focus after some java 7 update - 这似乎是一个已知问题)。我希望TextField在用户按下ENTER或ESCAPE以外的任何键时获得焦点。我创建了一个附加到我的AnchorPane.setOnKeyPressed()(以及按钮'onKeyPressed侦听器)的EventHandler,它在键盘事件上运行一个开关,默认为:
default:
Platform.runLater(new Runnable() {
@Override
public void run() {
myTxt.requestFocus();
myTxt.fireEvent(event);
}
});
这会将焦点发送到TextField;但是,我按下的键实际上并没有显示在TextField中。换句话说,如果我输入
test
TextField将获得焦点,但仅限
est
显示在现场。我已经为我的KeyEvent监听器添加了logpane / button和TextField的日志记录,它显示了我:
Oct 29, 2013 2:22:11 PM com.myapp.AppMainController$4 handle
INFO: Got key t at source Button[id=myBtn, styleClass=button]
Oct 29, 2013 2:22:11 PM com.myapp.AppMainController$6 handle
INFO: Got key t at source TextField[id=myTxt, styleClass=text-input text-field]
因此,关键事件是进入TextField,但它永远不会出现在框中。如果我继续输入,剩下的文本会显示出来,如果我通过输入像SHIFT-T这样的组合来获得焦点,那么它就会显示出来(看起来shift按键是“丢失”的那个)而不是信件本身。)
还有其他人遇到过这个吗?这是JavaFX2中的错误还是我做错了什么?我正在使用Java 7u45及其包含的JavaFX 2.2.45作为参考。
编辑1: 我应该澄清,无论焦点是从窗格还是按钮切换,都会将焦点切换到TextField。
编辑2(解决方案): 实际问题是“Platform.runLater”包装器。如果我只是在没有“runLater”的情况下请求焦点,那么我的关键事件会出现在我期望的地方。
default:
myTxt.requestFocus();
答案 0 :(得分:1)
我不确定你的上下文是怎样的,但我像这样解决了它
public class Main extends Application {
@Override
public void start(Stage stage) {
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
final TextField textField = new TextField();
final Button button = new Button();
vbox.getChildren().addAll(textField, button);
vbox.onKeyPressedProperty().set(new EventHandler<KeyEvent>() {
@Override public void handle(KeyEvent event) {
textField.requestFocus();
}
});
stage.setScene(new Scene(vbox, 300, 500));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
重要的部分是
vbox.onKeyPressedProperty().set(new EventHandler<KeyEvent>() {
@Override public void handle(KeyEvent event) {
textField.requestFocus();
}
});
通过使用keyPressedProperty,当您按任意按钮时,它已经激活,而不是在您键入/释放它时。与首都和非首都合作。
修改强>
插入按钮是为了能够通过点击它来“测试”TextField的非焦点,你可以给它焦点。
修改2
为了匹配实际答案,您可以使用在多种情况下实际需要的Platform.runLater进行一些解决方法。这是IntegerField中的代码(扩展TextField),所以我就是它自己的方法。
this.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent paramT) {
Platform.runLater(new Runnable() {
@Override public void run() {
if (isFocused() && !getText().isEmpty()) {
selectAll();
}
}
});
}
});