JavaFX的:更新与井号标签和数字生活

问题描述:

目前工作的一个文本框的电话号码文本框在那里,如果你输入你的电话号码将更新它想:JavaFX的:更新与井号标签和数字生活

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); 
    }); 
+0

也许'phoneField。 positionCaret(newValue.length())'? –

+0

不幸的是,只是不断设置我的插入到文本的末尾 – Nom

+0

@Nom嘿,你试过我的解决方案吗? – Enigo

我已经对您的代码进行了几处更改。 首先,你应该追加匹配结果以获得正确的值 - 我已经使用了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); 
}); 

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

您不应该使用侦听器,因为您要更改正在侦听的属性,这意味着侦听器会被调用两次。实际上,会产生一个无限循环,除非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; 
}