我想确保用户在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);
但是我甚至不能输入一个数字......它似乎只能用一个输入
答案 0 :(得分:2)
这些都很棘手。
第一个注意事项是您正在使用change.getText()
,它会添加或删除文本;您想测试生成的文本(即添加或删除后的文本)。为此,请使用change.getControlNewText()
。
例如,如果文本字段中的当前文字为"255.2"
,并且用户输入"5"
,则change.getText()
将返回"5"
,而{{1} }}将返回change.getControlNewText()
。
这仍然存在主要问题,即过滤器正在应用于文本的每个单独更改,并且您正在测试完整的IP地址。因此,例如,要键入&#34; 255.255.255.255&#34;,用户首先键入&#34; 2&#34;。你测试(即使用"255.25"
)如果&#34; 2&#34;匹配您的正则表达式,它失败(因为它不是一个完整的IP地址),因此更改被否决。在键入的下一个键上,change.getControlNewText()
将为change.getControlNewText()
,依此类推。因此,您希望整个序列"25"
&#34;,"2
,"25"
,"255"
,"255."
等等通过您的过滤器。您还需要过滤器来接受用户删除字符,复制和粘贴等。
所以你真的需要一个正则表达式来测试部分条目,而不是完整的条目,这当然有点棘手。以下是一个示例,并非旨在防弹,但应该让您走上正确的轨道(至少)。请注意,当用户提交值时,您可能需要额外的验证,以检查您是否拥有完整有效的IP地址。
"255.2"
答案 1 :(得分:0)
您可以手动检查数字。
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;
}
它不优雅,但它有效。