0

我在 AnchorPane 中嵌入了一个 TextField 以及几个按钮。默认情况下,TextField 没有焦点,因为我希望它显示提示文本(请参阅javafx 2 的文本字段中的提示文本在某些 java 7 更新后隐藏在焦​​点上- 这似乎是一个已知问题)。当用户按下 ENTER 或 ESCAPE 以外的任何键时,我希望 TextField 获得焦点。我创建了一个附加到我的 AnchorPane.setOnKeyPressed() (以及按钮的 onKeyPressed 侦听器)的 EventHandler,它在键盘事件上运行一个开关,默认为:

                    default:
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            myTxt.requestFocus();
                            myTxt.fireEvent(event);
                        }
                    });

这确实将焦点发送到 TextField;但是,我按下的键实际上并没有显示在 TextField 中。换句话说,如果我输入

test

TextField 将获得焦点,但仅

est

出现在场上。我已经为锚窗格/按钮和 TextField 添加了日志记录到我的 KeyEvent 侦听器,这向我显示:

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 等大写 T 的组合来获得焦点,它会显示出来(似乎 shift 按键是“丢失”的那个而不是字母本身)。

有人遇到过这种情况么?这是 JavaFX2 中的错误还是我做错了什么?我正在使用 Java 7u45 及其包含的 JavaFX 2.2.45,以供参考。

编辑 1: 我应该澄清一下,无论焦点是从窗格还是按钮切换到 TextField 时,都会发生这种情况。

编辑 2(解决方案): 实际问题是“Platform.runLater”包装器。如果我只是在没有“runLater”的情况下请求焦点,我的关键事件就会按我的预期显示。

                    default:
                        myTxt.requestFocus();
4

1 回答 1

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();
                }               
            }
        });
    }
});
于 2013-10-31T16:55:47.483 回答