javafx 文本框ip地址
javafx textfield ip address
我想确保用户在 JavaFX TextField(0.0.0.0 到 255.255.255.255)中输入有效的 IPv4 地址,但我似乎找不到任何有效的解决方案。
我试过那个代码:
private final TextField serverURI = new TextField();
final UnaryOperator<TextFormatter.Change> urlFilter = new UnaryOperator<TextFormatter.Change>() {
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
final String text = change.getText();
return (text.isEmpty() || text.matches("^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")) ? change : null;
}
};
final TextFormatter<String> urlFormatter = new TextFormatter(urlFilter);
serverURI.setTextFormatter(urlFormatter);
但是我什至不能输入一个数字...它似乎只用一个输入就可以工作
您可以手动查看号码。
private static boolean checkIfValidIpv4(String text){
StringTokenizer st = new StringTokenizer(text,".");
for(int i = 0; i < 4; i++){
if(!st.hasMoreTokens()){
return false;
}
int num = Integer.parseInt(st.nextToken());
if(num < 0 || num > 255){
return false;
}
}
if(st.hasMoreTokens()){
return false;
}
return true;
}
虽然不优雅,但很管用。
这些很棘手。
第一个注意事项是您正在使用 change.getText()
,它给出了添加或删除的文本;你想测试结果文本(即添加或删除后的文本)。为此,使用 change.getControlNewText()
。
例如,如果文本字段中的当前文本是 "255.2"
,并且用户键入 "5"
,则 change.getText()
将 return "5"
,而 change.getControlNewText()
将 return "255.25"
.
这仍然存在主要问题,即过滤器应用于文本的每个单独更改,并且您正在测试完整的 IP 地址。因此,例如,要键入“255.255.255.255”,用户将首先键入“2”。您测试(即使使用 change.getControlNewText()
)如果“2”与您的正则表达式匹配,它会失败(因为它不是完整的 IP 地址),因此更改被否决。在键入下一个键时,change.getControlNewText()
将变为 "25"
,依此类推。因此,您希望整个序列 "2
"、"25"
、"255"
、"255."
、"255.2"
等通过您的过滤器。您还需要过滤器接受用户删除字符、复制粘贴等操作。
所以您确实需要一个正则表达式来测试部分条目,而不是完整的条目,这当然需要一些技巧才能正确完成。以下是一个示例,并非旨在防弹,但应该让您走上正确的轨道(至少)。请注意,您可能需要在用户提交值时进行额外验证,以检查您是否拥有完整、有效的 IP 地址。
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class IPTextFieldTest extends Application {
@Override
public void start(Stage primaryStage) {
TextField ipTextField = new TextField();
String regex = makePartialIPRegex();
final UnaryOperator<Change> ipAddressFilter = c -> {
String text = c.getControlNewText();
if (text.matches(regex)) {
return c ;
} else {
return null ;
}
};
ipTextField.setTextFormatter(new TextFormatter<>(ipAddressFilter));
StackPane root = new StackPane(ipTextField);
Scene scene = new Scene(root, 350, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
private String makePartialIPRegex() {
String partialBlock = "(([01]?[0-9]{0,2})|(2[0-4][0-9])|(25[0-5]))" ;
String subsequentPartialBlock = "(\."+partialBlock+")" ;
String ipAddress = partialBlock+"?"+subsequentPartialBlock+"{0,3}";
return "^"+ipAddress ;
}
public static void main(String[] args) {
launch(args);
}
}
我想确保用户在 JavaFX TextField(0.0.0.0 到 255.255.255.255)中输入有效的 IPv4 地址,但我似乎找不到任何有效的解决方案。
我试过那个代码:
private final TextField serverURI = new TextField();
final UnaryOperator<TextFormatter.Change> urlFilter = new UnaryOperator<TextFormatter.Change>() {
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
final String text = change.getText();
return (text.isEmpty() || text.matches("^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")) ? change : null;
}
};
final TextFormatter<String> urlFormatter = new TextFormatter(urlFilter);
serverURI.setTextFormatter(urlFormatter);
但是我什至不能输入一个数字...它似乎只用一个输入就可以工作
您可以手动查看号码。
private static boolean checkIfValidIpv4(String text){
StringTokenizer st = new StringTokenizer(text,".");
for(int i = 0; i < 4; i++){
if(!st.hasMoreTokens()){
return false;
}
int num = Integer.parseInt(st.nextToken());
if(num < 0 || num > 255){
return false;
}
}
if(st.hasMoreTokens()){
return false;
}
return true;
}
虽然不优雅,但很管用。
这些很棘手。
第一个注意事项是您正在使用 change.getText()
,它给出了添加或删除的文本;你想测试结果文本(即添加或删除后的文本)。为此,使用 change.getControlNewText()
。
例如,如果文本字段中的当前文本是 "255.2"
,并且用户键入 "5"
,则 change.getText()
将 return "5"
,而 change.getControlNewText()
将 return "255.25"
.
这仍然存在主要问题,即过滤器应用于文本的每个单独更改,并且您正在测试完整的 IP 地址。因此,例如,要键入“255.255.255.255”,用户将首先键入“2”。您测试(即使使用 change.getControlNewText()
)如果“2”与您的正则表达式匹配,它会失败(因为它不是完整的 IP 地址),因此更改被否决。在键入下一个键时,change.getControlNewText()
将变为 "25"
,依此类推。因此,您希望整个序列 "2
"、"25"
、"255"
、"255."
、"255.2"
等通过您的过滤器。您还需要过滤器接受用户删除字符、复制粘贴等操作。
所以您确实需要一个正则表达式来测试部分条目,而不是完整的条目,这当然需要一些技巧才能正确完成。以下是一个示例,并非旨在防弹,但应该让您走上正确的轨道(至少)。请注意,您可能需要在用户提交值时进行额外验证,以检查您是否拥有完整、有效的 IP 地址。
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class IPTextFieldTest extends Application {
@Override
public void start(Stage primaryStage) {
TextField ipTextField = new TextField();
String regex = makePartialIPRegex();
final UnaryOperator<Change> ipAddressFilter = c -> {
String text = c.getControlNewText();
if (text.matches(regex)) {
return c ;
} else {
return null ;
}
};
ipTextField.setTextFormatter(new TextFormatter<>(ipAddressFilter));
StackPane root = new StackPane(ipTextField);
Scene scene = new Scene(root, 350, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
private String makePartialIPRegex() {
String partialBlock = "(([01]?[0-9]{0,2})|(2[0-4][0-9])|(25[0-5]))" ;
String subsequentPartialBlock = "(\."+partialBlock+")" ;
String ipAddress = partialBlock+"?"+subsequentPartialBlock+"{0,3}";
return "^"+ipAddress ;
}
public static void main(String[] args) {
launch(args);
}
}