当前位置: 首页 > 知识库问答 >
问题:

Javafx:使用hashtags和number live更新电话号码文本字段

彭宜人
2023-03-14

当前正在处理一个文本字段,如果您输入您的号码,它会像这样更新:

1##-###-####

12#-###-####

不幸的是,通过控制台将输入“1234”转换为“123-4###########”是可行的,但当我按下更新的字符串“123-4###-#####”时,它会自动将光标部分替换到开始位置,并不断替换第一位数字。当更新文本框中的字符串时,是否有人可以帮助保存光标位置?这是我的更新代码。

phoneField.textProperty().addListener((observable, oldValue, newValue) -> {
       Pattern p = Pattern.compile("-?\\d+");
       Matcher m = p.matcher(newValue);
       String result = "";
       String finalString = "";
       try {
           while (m.find()) {
               result = m.group();
           }
           int size = result.length();
           for(int i = 0; i < size; i++) {
               if(i == 3 || i == 6) finalString += "-";
               finalString += result.charAt(i);
           }
           for(int i = size; i < 10; i++) {
               if(i == 3 || i == 6) finalString += "-";
               finalString += "#";
           }
       } catch (Exception e) {
           finalString = "INVALID NUMBER";
       }
        phoneField.setText(finalString);
    });

共有2个答案

沈冠宇
2023-03-14

我对你的代码做了一些修改。首先,你应该追加匹配的结果,以获得正确的值——我已经使用了StringBuilder.append()。然后,我改变了编译模式,否则它将无法正确处理输入。

phoneField.textProperty().addListener((observable, oldValue, newValue) -> {
    Pattern p = Pattern.compile("\\d+");
    Matcher m = p.matcher(newValue);
    StringBuilder result = new StringBuilder();
    String finalString = "";
    try {
        while (m.find()) {
            result.append(m.group());
        }
        int size = result.length();
        for (int i = 0; i < size; i++) {
            if (i == 3 || i == 6) finalString += "-";
            finalString += result.charAt(i);
        }
        for (int i = size; i < 9; i++) {
            if (i == 3 || i == 6) finalString += "-";
            finalString += "#";
        }
    } catch (Exception e) {
        finalString = "INVALID NUMBER";
    }
    phoneField.setText(finalString);
});

请注意,可能值得为字段添加长度检查。

方和宜
2023-03-14

您不应该使用侦听器,因为您正在更改正在侦听的属性,这意味着侦听器将被调用两次。事实上,将导致无限循环,除非StringProperty足够聪明,能够在新值等于旧值时避免触发更改。(大多数与JavaBean兼容的类都是这样的,但我不知道有任何关于这种行为的保证。)

要限制TextField的行为,通常需要使用TextFormatter:

private TextField createPhoneField() {
    TextField phoneField = new TextField();
    phoneField.setPrefColumnCount(12);

    TextFormatter<String> formatter =
        new TextFormatter<>(this::addPhoneNumberMask);
    phoneField.setTextFormatter(formatter);

    return phoneField;
}

private TextFormatter.Change addPhoneNumberMask(
                                TextFormatter.Change change) {

    // Ignore cursor movements, unless the text is empty (in which case
    // we're initializing the field).
    if (!change.isContentChange() &&
        !change.getControlNewText().isEmpty()) {

        return change;
    }

    String text = change.getControlNewText();
    int start = change.getRangeStart();
    int end = change.getRangeEnd();

    int anchor = change.getAnchor();
    int caret = change.getCaretPosition();

    StringBuilder newText = new StringBuilder(text);

    int dash;
    while ((dash = newText.lastIndexOf("-")) >= start) {
        newText.deleteCharAt(dash);
        if (caret > dash) {
            caret--;
        }
        if (anchor > dash) {
            anchor--;
        }
    }

    while (newText.length() < 3) {
        newText.append('#');
    }
    if (newText.length() == 3 || newText.charAt(3) != '-') {
        newText.insert(3, '-');
        if (caret > 3 || (caret == 3 && end <= 3 && change.isDeleted())) {
            caret++;
        }
        if (anchor > 3 || (anchor == 3 && end <= 3 && change.isDeleted())) {
            anchor++;
        }
    }

    while (newText.length() < 7) {
        newText.append('#');
    }
    if (newText.length() == 7 || newText.charAt(7) != '-') {
        newText.insert(7, '-');
        if (caret > 7 || (caret == 7 && end <= 7 && change.isDeleted())) {
            caret++;
        }
        if (anchor > 7 || (anchor == 7 && end <= 7 && change.isDeleted())) {
            anchor++;
        }
    }

    while (newText.length() < 12) {
        newText.append('#');
    }

    if (newText.length() > 12) {
        newText.delete(12, newText.length());
    }

    text = newText.toString();
    anchor = Math.min(anchor, 12);
    caret = Math.min(caret, 12);

    change.setText(text);
    change.setRange(0, change.getControlText().length());
    change.setAnchor(anchor);
    change.setCaretPosition(caret);

    return change;
}
 类似资料:
  • 如果您在Nuxt页面中包含电话号码,请确保将它们直接包装到链接中: <!-- Example phone number: +7 (982) 536-50-77 --> <template> <a href="tel: +7 (982) 536-50-77">+7 (982) 536-50-77</a> </template> 否则,某些移动Safari版本会自动将这些数字转换为链接。 听起

  • 问题内容: 我在某些网站上找到了此代码,并且效果很好。它验证电话号码是以下格式之一: (123)456-7890 或 123-456-7890 问题是我的客户(我不知道为什么,也许是客户的东西)想添加另一种格式,即连续十个数字,如下所示: 1234567890 。 我正在使用这个正则表达式, 如何添加它还可以验证另一种格式?我对正则表达式不好。 问题答案: 首先,您的格式验证器显然仅适用于NANP

  • 如果我使用tel:我应该写国际电话代码,就像这样。 到目前为止还不错,但我找不到关于如何以“国际”方式写手机号码的信息,如果有的话。

  • 我希望在输入TextField时实时格式化电话号码。目标是在根据国家/地区形成电话号码的不同数字之间添加“分隔符”(空格、破折号、点...)。默认情况下,法国:06 23 65 14 85但也适用于其他国家/地区,如国际格式法语:33 6 23 65 14 85或德国国际格式:xx xxx xxx xx xxx 为此,我有一个监听器,当在TextField中添加新号码时,它会永久查找。然后,程序会

  • 问题内容: 您如何使用递归方法编写一个Java程序,该方法将一个int像“ 234”那样接受并将其转换为电话键盘上的相应字母(2 = ABC,3 = DEF等),并打印出此字符的排列?例如: 输入= 234 输出= ADG ADH ADI AEG AEH AEI AFG AFH AFI BDG BDH BDI BEG BEH BEI BFG BFH BFI CDG CDH CDI CEG CEH

  • 问题内容: 想要将电话号码设置为 10 位数字,如何使用Angular js做到这一点。 这是我尝试过的: 但是我没有收到验证错误。 问题答案: 试试这个: