JavaFX在输入字符后将焦点转移到TextField上



背景

我正在创建一个JavaFX表单,要求用户输入一个IP地址。我的设计目前使用四个TextField,地址的每个字节一个,而不是一个TextField。我的意图是,一旦用户在一个字段中输入了三个字符,焦点就会自动跳到下一个字段。

问题

当用户键入第三个字符时,焦点仍在文本字段中。然后,当他们键入第四个字符时,他们键入的字符将被放置在字段的开始处(而不是结束处(,然后焦点将更改为下一个字段。我在处理程序方法中犯了错误吗?我应该响应不同的事件吗?

查看

<FlowPane fx:id="paneIPAddress" fx:controller="Controller" alignment="CENTER">
    <children>
        <TextField fx:id="textIP1" alignment="CENTER" onKeyTyped="#ip1Change" prefWidth="40.0" />
        <Label text=".">
            <font>
                <Font name="SansSerif Bold" size="18.0" />
            </font>
        </Label>
        <TextField fx:id="textIP2" alignment="CENTER" onKeyTyped="#ip2Change" prefWidth="40.0" />
        <Label text=".">
            <font>
                <Font name="SansSerif Bold" size="18.0" />
            </font>
        </Label>
        <TextField fx:id="textIP3" alignment="CENTER" onKeyTyped="#ip3Change" prefWidth="40.0" />
        <Label text=".">
            <font>
                <Font name="SansSerif Bold" size="18.0" />
            </font>
        </Label>
        <TextField fx:id="textIP4" alignment="CENTER" prefWidth="40.0" />
    </children>
    <VBox.margin>
        <Insets bottom="25.0" />
    </VBox.margin>
</FlowPane>

控制器

public class Controller {
    public void ip1Change() {
        if (textIP1.getText().length() >= 3) {
            textIP2.requestFocus();
        }
    }
    public void ip2Change() {
        if (textIP2.getText().length() >= 3) {
            textIP3.requestFocus();
        }
    }
    public void ip3Change() {
        if (textIP3.getText().length() >= 3) {
            textIP4.requestFocus();
        }
    }
}

最好避免使用关键事件侦听器来管理它(例如,如果用户使用鼠标复制和粘贴文本会发生什么(。相反,使用文本字段的文本属性注册侦听器。

这个例子不使用FXML,但您可以在控制器的初始化方法中做完全相同的事情:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class IPAddressEntry extends Application {
    @Override
    public void start(Stage primaryStage) {
        TextField ipAdd1 = new TextField();
        TextField ipAdd2 = new TextField();
        TextField ipAdd3 = new TextField();
        TextField ipAdd4 = new TextField();
        registerListener(ipAdd1, ipAdd2);
        registerListener(ipAdd2, ipAdd3);
        registerListener(ipAdd3, ipAdd4);
        GridPane root = new GridPane();
        root.addRow(0, ipAdd1, ipAdd2, ipAdd3, ipAdd4);
        Scene scene = new Scene(root, 250, 50);
        primaryStage.setScene(scene) ;
        primaryStage.show();
    }
    private void registerListener(TextField tf1, TextField tf2) {
        tf1.textProperty().addListener((obs, oldText, newText) -> {
            if (oldText.length() < 3 && newText.length() >= 3) {
                tf2.requestFocus();
            }
        });
    }
    public static void main(String[] args) {
        launch(args);
    }
}

最新更新