javafx文本域ip地址

javafx文本域ip地址,java,javafx,ip,textfield,ipv4,Java,Javafx,Ip,Textfield,Ipv4,我希望确保用户在JavaFX文本字段(0.0.0.0到255.255.255.255)中输入有效的IPv4地址,但我似乎找不到任何有效的解决方案 我试过使用该代码: private final TextField serverURI = new TextField(); final UnaryOperator<TextFormatter.Change> urlFilter = new UnaryOperator<TextFormatter.Change>(

我希望确保用户在JavaFX文本字段(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 final TextField serverURI=new TextField();
最终一元运算符urlFilter=新一元运算符(){
@凌驾
公共TextFormatter.Change应用(TextFormatter.Change){
最终字符串text=change.getText();
return(text.isEmpty()| text.matches(^(25[0-5]| 2[0-4][0-9]|[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]1240-5]|[0-4][0-9]|[0]。[0-9])(25[0-5]1240-5]1240]2[0-4][0-9]1240-9]);[0-9]1240]。[0;
}
};
最终TextFormatter urlFormatter=新的TextFormatter(urlFilter);
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;
}
private静态布尔checkIfValidIpv4(字符串文本){
StringTokenizer st=新的StringTokenizer(文本“.”);
对于(int i=0;i<4;i++){
如果(!st.hasMoreTokens()){
返回false;
}
int num=Integer.parseInt(st.nextToken());
如果(num<0 | | num>255){
返回false;
}
}
如果(st.hasMoreTokens()){
返回false;
}
返回true;
}
虽然不雅致,但很管用。

这些都很棘手

第一个注意事项是,您使用的是
change.getText()
,它给出了要添加或删除的文本;您希望测试结果文本(即添加或删除后的文本)。为此,请使用
change.getControlNewText()

例如,如果文本字段中的当前文本是
“255.2”
,并且用户键入了
“5”
,则
change.getText()
将返回
“5”
,而
change.getControlNewText()
将返回
“255.25”

这仍然留下了一个主要问题,即过滤器将应用于文本的每个单独更改,并且您正在测试完整的ip地址。因此,例如,要键入“255.255.255.255”,用户将首先键入“2”。如果“2”与正则表达式匹配,则测试(即使使用
change.getControlNewText()
)失败(因为它不是完整的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);
    }
}
import java.util.function.UnaryOperator;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.TextField;
导入javafx.scene.control.TextFormatter;
导入javafx.scene.control.TextFormatter.Change;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类IPTextFieldTest扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
TextField ipTextField=新的TextField();
字符串regex=makePartialIPRegex();
最终一元运算符ipAddressFilter=c->{
String text=c.getControlNewText();
if(text.matches(regex)){
返回c;
}否则{
返回null;
}
};
setTextFormatter(新的TextFormatter(ipAddressFilter));
StackPane root=新的StackPane(ipTextField);
场景=新场景(根,350,120);
初级阶段。场景(场景);
primaryStage.show();
}
私有字符串makePartialIPRegex(){
字符串partialBlock=“([01]?[0-9]{0,2})|(2[0-4][0-9])|(25[0-5])”;
字符串subsequentPartialBlock=“(\\.“+partialBlock+””);
字符串ipAddress=partialBlock+“?”+随后的partialBlock+“{0,3}”;
返回“^”+IP地址;
}
公共静态void main(字符串[]args){
发射(args);
}
}

是,但这不会阻止用户键入数字以外的任何内容。我想在实时:)哦。。。如果是这样的话,我帮不了你:)但你可以查一下问题。。。有点类似@Phostetanks,很好用!但我不明白为什么它能与你的正则表达式一起工作,而不是我的正则表达式,即使我使用getControlNewText()而不是getText(),我只需要弄清楚如何确保用户在两点之间输入一些东西,并可能防止在前面加零:)因为
“2”
“25”
“255”
“255.”
“255.2”
等与您的正则表达式不匹配。每次文本更改时都会进行检查。编辑答案以澄清最后一点。如果回答了你的问题,请接受正确的答案。最后一点:我不会试图避免前导零。例如,如果用户意外地键入了
200
而不是
100
,并且您不允许在任何块中输入
00
,这将使他们很难编辑它。如果您只输入一个点,则返回true。