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);
});
答
我已经对您的代码进行了几处更改。 首先,你应该追加匹配结果以获得正确的值 - 我已经使用了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;
}
也许'phoneField。 positionCaret(newValue.length())'? –
不幸的是,只是不断设置我的插入到文本的末尾 – Nom
@Nom嘿,你试过我的解决方案吗? – Enigo