TextField requestFocus丢失第一个按键? (JavaFX2)

时间:2013-10-29 18:44:01

标签: java javafx-2 javafx

我有一个嵌入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();

1 个答案:

答案 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();
                }               
            }
        });
    }
});