背景
我正在创建一个要求用户输入IP地址的JavaFX表单。我的设计目前使用四个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();
}
}
}
答案 0 :(得分:1)
最好避免使用键事件监听器来管理它(例如,如果用户使用鼠标复制和粘贴文本会发生什么)。而是使用文本字段的文本属性注册侦听器。
此示例不使用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);
}
}