如何在文本字段中格式化 phone 数字
How to format a phone number in a textfield
我希望在将 phone 数字输入 TextField 时对其进行实时格式化。
目标是根据国家/地区在构成 phone 号码的不同数字之间添加一个“分隔符”(space、破折号、点...)。
默认法国:
06 23 65 14 85
但也适用于其他国家作为国际格式法语:
+33 6 23 65 14 85
或德国国际格式:
+xx xxx xxx xx xxx
为此,我有一个侦听器,当在 TextField 中添加新数字时,它会永久查看。然后该程序负责检测正在输入的 phone 数字的格式,并根据这一点,该程序使用我自己创建的“格式”来修改字符串的格式。
问题是用户的光标在重新格式化字符串时不断移动。
如果用户删除或选择一个区域然后删除它...每次,光标移动到字符串的开头或结尾,写起来很烦人。
您是否有解决方案来实时更改字符串的格式,同时确保光标位于正确的位置?
我目前找到的唯一选择是一个库,但这似乎很难维护,所以我宁愿自己做。否则我必须等待图形组件上的注意力不集中,然后再更改格式,但这不是我想要的。
我在下面提供我的代码,如果里面有一点法语,请原谅,我有时会写一些。
import java.util.function.UnaryOperator;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.util.converter.IntegerStringConverter;
public class FormPhoneNumber {
private StringProperty textPropertyFromComponent = new SimpleStringProperty();
private TextField tf;
private String separator;
private String last = "";
private int lastCaretPosition = 0;
private ChangeListener<String> updateText;
public FormPhoneNumber(TextField textField, String separator) {
this.textPropertyFromComponent = textField.textProperty();
this.tf = textField;
//On unfocus
// tf.focusedProperty().addListener((ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) -> {
// if (t1 == false) {
// System.out.println("i");
// }
// });
if (separator != null && !separator.isEmpty()) {
this.separator = separator;
} else {
separator = " ";
}
checkNumberFormat();
}
private void checkNumberFormat() {
//Listener on write in the textfield
updateText = (ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
if (newValue == null || newValue.isEmpty()) {
return;
}
//My customs formatters
if (newValue.startsWith("+33")) {
// System.out.println("FRANCE");
String resultat = getPhoneNumberFormatted(newValue, "###-#-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+49")) {
// System.out.println("ALLEMAGNE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-###-##-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 18);
} else if (newValue.startsWith("+34")) {
// System.out.println("ESPAGNE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+3245") || newValue.replaceAll(separator, "").startsWith("+3249")) {
// System.out.println("BELGIQUE GSM");
String resultat = getPhoneNumberFormatted(newValue, "###-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+322") || newValue.replaceAll(separator, "").startsWith("+323") || newValue.replaceAll(separator, "").startsWith("+329")) {
// System.out.println("BELGIQUE AUTRE 1");
String resultat = getPhoneNumberFormatted(newValue, "###-#-###-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 15);
} else if (newValue.startsWith("+32")) {
// System.out.println("BELGIQUE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 15);
} else if (newValue.replaceAll(separator, "").startsWith("+3526")) {
// System.out.println("LUXEMBOURG 1");
String resultat = getPhoneNumberFormatted(newValue, "####-###-###-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+352")) {
// System.out.println("LUXEMBOURG AUTRE");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+377")) {
// System.out.println("MONACO");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+41")) {
// System.out.println("SUISSE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-###-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+390")) {
// System.out.println("ITALIE FIXE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-####-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+393")) {
// System.out.println("ITALIE PORTABLE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-###-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+39")) {
// System.out.println("ITALIE AUTRE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-####-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+376")) {
// System.out.println("ANDORRE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-###-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+590")) {
// System.out.println("GUADELOUPE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+596")) {
// System.out.println("MARTINIQUE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+594")) {
// System.out.println("GUYANE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+262")) {
// System.out.println("REUNION ET MAYOTTE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+687")) {
// System.out.println("NOUVELLE-CALEDONIE");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 13);
} else if (newValue.startsWith("+")) {
// System.out.println("AUTRE - PAYS NON REFERENCE");
String resultat = getPhoneNumberFormatted(newValue, "######################");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 22);
} else if (newValue.length() >= 3) {
if (Character.isDigit(newValue.charAt(0))) {
// System.out.println("France Nationnal");
String resultat = getPhoneNumberFormatted(newValue, "##-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 14);
}
}
};
textPropertyFromComponent.addListener(updateText);
}
//My attempt to put the cursor in the right place, but VERY scary code
private void setResult(String resultat, int caretPosition, String oldValue, String newValue, int maxLength) {
Platform.runLater(() -> {
if (resultat.length() <= maxLength && newValue != null && oldValue != null) {
textPropertyFromComponent.set(resultat);
// int diffAddLetter = newValue.length() - oldValue.length();
// int diffRemLetter = oldValue.length() - newValue.length();
// System.out.println("oldValue = " + oldValue);
// System.out.println("newValue = " + newValue);
// System.out.println("resultat = " + resultat);
// System.out.println("test = " + last);
// if (newValue.length() == maxLength) {
// if (!"".equals(last)) {
// tf.positionCaret(caretPosition + 1);
// }
// } else if (diffAddLetter > 0) {
// System.out.println("diffAddLetter = " + diffAddLetter);
// System.out.println("lastCaretPosition = " + lastCaretPosition);
// System.out.println("caretPosition = " + caretPosition);
// if ("".equals(last)) {
// if (StringUtils.countMatches(oldValue, separator) < StringUtils.countMatches(newValue, separator)) {
// tf.positionCaret(caretPosition + 1);
// } else {
// tf.positionCaret(caretPosition);
// }
// System.out.println("a1");
// } else {
// tf.positionCaret(caretPosition + diffAddLetter);
// System.out.println("a2");
// }
// if (lastCaretPosition == caretPosition) {
// last = "";
// } else {
// last = oldValue;
// }
// } else if (diffRemLetter > 0) {
// System.out.println("lastCaretPosition = " + lastCaretPosition);
// System.out.println("caretPosition = " + caretPosition);
// System.out.println("diffRemLetter = " + diffRemLetter);
// if ((lastCaretPosition == caretPosition || lastCaretPosition == (caretPosition - diffRemLetter)) && diffRemLetter > 1) {
// tf.positionCaret(caretPosition - diffRemLetter);
// System.out.println("r1");
// } else {
// System.out.println("caretPosition + diffRemLetter = " + (caretPosition - diffRemLetter));
//// System.out.println("(newValue.substring(0, caretPosition) = " + (newValue.substring(0, caretPosition)));
// System.out.println("oldValue.substring(0, caretPosition) = " + oldValue.substring(0, caretPosition));
//// System.out.println("newValue.substring(caretPosition) = " + newValue.substring(caretPosition +1));
// System.out.println("caretPosition = " + caretPosition);
// if (newValue.length() > caretPosition) {
// if (newValue.substring(0, caretPosition).equals(oldValue.substring(0, caretPosition)) && oldValue.endsWith(newValue.substring(caretPosition + 1)) && !"".equals(newValue.substring(caretPosition + 1)) && !String.valueOf(newValue.charAt(caretPosition - 1)).equals(separator)) {
// tf.positionCaret(caretPosition);
// System.out.println("r2");
// } else if (Character.isDigit(newValue.charAt(caretPosition - 1)) && Character.isDigit(newValue.charAt(caretPosition)) && diffRemLetter == 1) {
// tf.positionCaret(caretPosition);
// System.out.println("r5");
// } else {
// tf.positionCaret(caretPosition + 1);
// System.out.println("r3");
// }
// } else {
// System.out.println("r4");
// tf.positionCaret(lastCaretPosition);
// }
// last = oldValue;
// }
// } else if (String.valueOf(resultat.charAt(caretPosition - 1)).equals(separator) && last.length() < resultat.length()) {
// tf.positionCaret(caretPosition + 1);
// System.out.println("s");
// } else {
// tf.positionCaret(caretPosition);
// System.out.println("o");
// }
// if (resultat.length() >= caretPosition) {
// if (oldValue.replaceAll(separator, "").equals(newValue.replaceAll(separator, "")) && String.valueOf(resultat.charAt(caretPosition)).equals(separator)) {
// tf.positionCaret(caretPosition);
// System.out.println("c");
// }
// }
// lastCaretPosition = caretPosition;
} else {
textPropertyFromComponent.set(oldValue);
}
});
textPropertyFromComponent.addListener(updateText);
}
//Method to format the phone number
private String getPhoneNumberFormatted(String phoneNumber, String format) {
textPropertyFromComponent.removeListener(updateText);
String vretour = "";
if (phoneNumber.length() <= format.length()) {
phoneNumber = phoneNumber.replaceAll("[^0-9+]", "");
int index = findXDotPosition(format, phoneNumber.length());
format = format.substring(0, index + 1);
int indexCharArray = 0;
for (char unChar : format.toCharArray()) {
if ("#".charAt(0) == unChar) {
vretour = vretour + phoneNumber.toCharArray()[indexCharArray];
indexCharArray++;
}
if ("-".charAt(0) == unChar) {
vretour = vretour + separator;
}
}
} else {
vretour = phoneNumber;
}
return vretour;
}
//Method to find a separator
private static int findXDotPosition(String s, int separatorToFind) {
int result = -1;
char[] ca = s.toCharArray();
for (int i = 0; i < ca.length; ++i) {
if (ca[i] == '#') {
--separatorToFind;
}
if (separatorToFind == 0) {
return i;
}
}
return result;
}
}
我还为您提供了应用程序实际工作的一些屏幕截图。
https://i.goopics.net/Jl8aR.png
https://i.goopics.net/RVvdZ.png
希望你能给我一个解决方案,
提前致谢!
TextFormatter 绝对是正确的选择。您需要构建的是 TextFormatter 的 filter
组件。基本上,您可以将其视为击键处理器(也处理鼠标操作),其中已为您处理了所有低级内容。您得到一个传递给您的 TextFormatter.Change
对象,您可以看到该更改将如何影响该字段中的值,然后修改它、抑制它或让它通过。
所以所有的格式都会立即发生,就在您键入时就在 TextField 中。
我构建了一个来处理北美风格的 phone 数字,因为它比欧洲风格更有趣,因为它有括号和破折号。但是你可以适应它。
我采用的方法是从字符串中删除所有格式字符,然后在每次进行更改时从头开始重新格式化。这似乎比尝试逐个字符 fiddle 更容易。唯一棘手的部分是在“-”或“)”上按 ,我假设您想要删除特殊字符前面的数字。将插入符号移动到特殊字符的左侧可能更有意义:
public class PhoneNumberFilter implements UnaryOperator<TextFormatter.Change> {
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if (change.isContentChange()) {
handleBackspaceOverSpecialCharacter(change);
if (change.getText().matches("[0-9]*")) {
int originalNewTextLength = change.getControlNewText().length();
change.setText(formatNumber(change.getControlNewText()));
change.setRange(0, change.getControlText().length());
int caretOffset = change.getControlNewText().length() - originalNewTextLength;
change.setCaretPosition(change.getCaretPosition() + caretOffset);
change.setAnchor(change.getAnchor() + caretOffset);
return change;
} else {
return null;
}
}
return change;
}
private void handleBackspaceOverSpecialCharacter(TextFormatter.Change change) {
if (change.isDeleted() && (change.getSelection().getLength() == 0)) {
if (!Character.isDigit(change.getControlText().charAt(change.getRangeStart()))) {
if (change.getRangeStart() > 0) {
change.setRange(change.getRangeStart() - 1, change.getRangeEnd() - 1);
}
}
}
}
private String formatNumber(String numbers) {
numbers = numbers.replaceAll("[^\d]", "");
numbers = numbers.substring(0, Math.min(10, numbers.length()));
if (numbers.length() == 0) {
return "";
}
if (numbers.length() < 4) {
return "(" + numbers;
}
if (numbers.length() < 7) {
return numbers.replaceFirst("(\d{3})(\d+)", "()");
}
return numbers.replaceFirst("(\d{3})(\d{3})(\d+)", "()-");
}
}
这是一个小测试应用程序。您可以看到转换器只是“开箱即用”的默认转换器,因为它只是一个主要由数字组成的字符串:
public class PhoneNumberTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
TextFormatter<String> textFormatter = new TextFormatter(new DefaultStringConverter(), "", new PhoneNumberFilter());
textField.setTextFormatter(textFormatter);
Scene scene = new Scene(new VBox(textField), 300, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
非常感谢您的回答 DaveB!
它运行良好,我为您提供最终代码:
package PhoneNumberTest;
import java.util.function.UnaryOperator;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.util.converter.DefaultStringConverter;
import org.apache.commons.lang3.StringUtils;
public class PhoneNumberFilter implements UnaryOperator<TextFormatter.Change> {
private String separator = " ";
private int length = 0;
private TextField tf;
private final String formatForFrance = "###-#-##-##-##-##";
private final String formatForAllemagne = "###-###-###-##-###";
private final String formatForEspagne = "###-###-##-##-##";
private final String formatForBelgiqueGSM = "###-###-##-##-##";
private final String formatForBelgiqueAutre = "###-#-###-##-##";
private final String formatForBelgique = "###-##-##-##-##";
private final String formatForLuxembourg = "####-###-###-###";
private final String formatForLuxembourgAutre = "####-##-##-##-##";
private final String formatForMonaco = "####-##-##-##-##";
private final String formatForSuisse = "###-##-###-##-##";
private final String formatForItalieFixe = "###-##-####-####";
private final String formatForItaliePort = "###-###-###-####";
private final String formatForItalieAutre = "###-##-####-####";
private final String formatForAndorre = "####-###-###-###";
private final String formatForGuadeloupe = "####-###-##-##-##";
private final String formatForMartinique = "####-###-##-##-##";
private final String formatForGuyane = "####-###-##-##-##";
private final String formatForReunionMayotte = "####-###-##-##-##";
private final String formatForNouvelleCaledonie = "####-##-##-##";
private final String formatForAutre = "######################";
private final String formatForFranceNationnal = "##-##-##-##-##";
public PhoneNumberFilter(TextField textField, String separator) {
this.tf = textField;
if (separator != null && !separator.isEmpty()) {
this.separator = separator;
} else {
this.separator = "";
}
TextFormatter<String> textFormatter = new TextFormatter(new DefaultStringConverter(), "", new PhoneNumberFilter());
tf.setTextFormatter(textFormatter);
}
public PhoneNumberFilter() {
}
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if (change.isContentChange()) {
String resultat = "";
handleBackspaceOverSpecialCharacter(change);
int originalNewTextLength = change.getControlNewText().length();
if (change.getControlNewText().startsWith("+33")) {
// System.out.println("FRANCE");
length = formatForFrance.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForFrance);
} else if (change.getControlNewText().startsWith("+49")) {
// System.out.println("ALLEMAGNE");
length = formatForAllemagne.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAllemagne);
} else if (change.getControlNewText().startsWith("+34")) {
// System.out.println("ESPAGNE");
length = formatForEspagne.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForEspagne);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+3245") || change.getControlNewText().replaceAll(separator, "").startsWith("+3249")) {
// System.out.println("BELGIQUE GSM");
length = formatForBelgiqueGSM.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgiqueGSM);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+322") || change.getControlNewText().replaceAll(separator, "").startsWith("+323") || change.getControlNewText().replaceAll(separator, "").startsWith("+329")) {
// System.out.println("BELGIQUE AUTRE 1");
length = formatForBelgiqueAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgiqueAutre);
} else if (change.getControlNewText().startsWith("+32")) {
// System.out.println("BELGIQUE");
length = formatForBelgique.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgique);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+3526")) {
// System.out.println("LUXEMBOURG 1");
length = formatForLuxembourg.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForLuxembourg);
} else if (change.getControlNewText().startsWith("+352")) {
// System.out.println("LUXEMBOURG AUTRE");
length = formatForLuxembourgAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForLuxembourgAutre);
} else if (change.getControlNewText().startsWith("+377")) {
// System.out.println("MONACO");
length = formatForMonaco.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForMonaco);
} else if (change.getControlNewText().startsWith("+41")) {
// System.out.println("SUISSE");
length = formatForSuisse.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForSuisse);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+390")) {
// System.out.println("ITALIE FIXE");
length = formatForItalieFixe.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItalieFixe);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+393")) {
// System.out.println("ITALIE PORTABLE");
length = formatForItaliePort.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItaliePort);
} else if (change.getControlNewText().startsWith("+39")) {
// System.out.println("ITALIE AUTRE");
length = formatForItalieAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItalieAutre);
} else if (change.getControlNewText().startsWith("+376")) {
// System.out.println("ANDORRE");
length = formatForAndorre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAndorre);
} else if (change.getControlNewText().startsWith("+590")) {
// System.out.println("GUADELOUPE");
length = formatForGuadeloupe.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForGuadeloupe);
} else if (change.getControlNewText().startsWith("+596")) {
// System.out.println("MARTINIQUE");
length = formatForMartinique.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForMartinique);
} else if (change.getControlNewText().startsWith("+594")) {
// System.out.println("GUYANE");
length = formatForGuyane.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForGuyane);
} else if (change.getControlNewText().startsWith("+262")) {
// System.out.println("REUNION ET MAYOTTE");
length = formatForReunionMayotte.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForReunionMayotte);
} else if (change.getControlNewText().startsWith("+687")) {
// System.out.println("NOUVELLE-CALEDONIE");
length = formatForNouvelleCaledonie.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForNouvelleCaledonie);
} else if (change.getControlNewText().startsWith("+")) {
// System.out.println("AUTRE - PAYS NON REFERENCE");
length = formatForAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAutre);
} else if (change.getControlNewText().length() >= 3) {
if (Character.isDigit(change.getControlNewText().charAt(0))) {
// System.out.println("France Nationnal");
length = formatForFranceNationnal.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForFranceNationnal);
}
} else {
resultat = change.getControlNewText();
}
if (change.getControlText().length() == length && originalNewTextLength > length && length != 0) {
change.setText(change.getControlText());
} else {
change.setText(resultat);
}
change.setRange(0, change.getControlText().length());
int caretOffset = change.getControlNewText().length() - originalNewTextLength;
change.setCaretPosition(change.getCaretPosition() + caretOffset);
change.setAnchor(change.getAnchor() + caretOffset);
return change;
}
return change;
}
private void handleBackspaceOverSpecialCharacter(TextFormatter.Change change) {
if (change.isDeleted() && (change.getSelection().getLength() == 0)) {
if (!Character.isDigit(change.getControlText().charAt(change.getRangeStart())) && !"+".equals(String.valueOf(change.getControlText().charAt(change.getRangeStart())))) {
if (change.getRangeStart() > 0) {
change.setRange(change.getRangeStart() - 1, change.getRangeEnd() - 1);
}
}
}
}
private String getPhoneNumberFormatted(String phoneNumber, String format) {
if (phoneNumber.length() > length) {
phoneNumber = phoneNumber.substring(0, length);
}
String vretour = "";
if (phoneNumber.length() <= format.length()) {
phoneNumber = phoneNumber.replaceAll("[^0-9+]", "");
int index = findXDotPosition(format, phoneNumber.length());
format = format.substring(0, index + 1);
int indexCharArray = 0;
for (char unChar : format.toCharArray()) {
if ("#".charAt(0) == unChar) {
vretour = vretour + phoneNumber.toCharArray()[indexCharArray];
indexCharArray++;
}
if ("-".charAt(0) == unChar) {
vretour = vretour + separator;
}
}
} else {
vretour = phoneNumber;
}
return vretour;
}
private static int findXDotPosition(String s, int separatorToFind) {
int result = -1;
char[] ca = s.toCharArray();
for (int i = 0; i < ca.length; ++i) {
if (ca[i] == '#') {
--separatorToFind;
}
if (separatorToFind == 0) {
return i;
}
}
return result;
}
}
像这样创建一个对象new PhoneNumberFilter(tf, " ");
(tf = TextField,第二个参数是不同 phone 数字之间的分隔符)。这将执行程序的其余部分并将重新格式化输入的数字。
我只有最后一个问题。当我在 phone 数字的末尾单击两次,或者当我尝试在数字已经是指示的最大字符数时写到最后时,我的光标无缘无故地向后移动了 1 个缺口并且我找不到强制光标停留在数字末尾的方法。
这是正常的吗?有解决办法吗?
我希望在将 phone 数字输入 TextField 时对其进行实时格式化。 目标是根据国家/地区在构成 phone 号码的不同数字之间添加一个“分隔符”(space、破折号、点...)。 默认法国: 06 23 65 14 85 但也适用于其他国家作为国际格式法语: +33 6 23 65 14 85 或德国国际格式: +xx xxx xxx xx xxx
为此,我有一个侦听器,当在 TextField 中添加新数字时,它会永久查看。然后该程序负责检测正在输入的 phone 数字的格式,并根据这一点,该程序使用我自己创建的“格式”来修改字符串的格式。
问题是用户的光标在重新格式化字符串时不断移动。 如果用户删除或选择一个区域然后删除它...每次,光标移动到字符串的开头或结尾,写起来很烦人。
您是否有解决方案来实时更改字符串的格式,同时确保光标位于正确的位置? 我目前找到的唯一选择是一个库,但这似乎很难维护,所以我宁愿自己做。否则我必须等待图形组件上的注意力不集中,然后再更改格式,但这不是我想要的。
我在下面提供我的代码,如果里面有一点法语,请原谅,我有时会写一些。
import java.util.function.UnaryOperator;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.util.converter.IntegerStringConverter;
public class FormPhoneNumber {
private StringProperty textPropertyFromComponent = new SimpleStringProperty();
private TextField tf;
private String separator;
private String last = "";
private int lastCaretPosition = 0;
private ChangeListener<String> updateText;
public FormPhoneNumber(TextField textField, String separator) {
this.textPropertyFromComponent = textField.textProperty();
this.tf = textField;
//On unfocus
// tf.focusedProperty().addListener((ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) -> {
// if (t1 == false) {
// System.out.println("i");
// }
// });
if (separator != null && !separator.isEmpty()) {
this.separator = separator;
} else {
separator = " ";
}
checkNumberFormat();
}
private void checkNumberFormat() {
//Listener on write in the textfield
updateText = (ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
if (newValue == null || newValue.isEmpty()) {
return;
}
//My customs formatters
if (newValue.startsWith("+33")) {
// System.out.println("FRANCE");
String resultat = getPhoneNumberFormatted(newValue, "###-#-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+49")) {
// System.out.println("ALLEMAGNE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-###-##-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 18);
} else if (newValue.startsWith("+34")) {
// System.out.println("ESPAGNE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+3245") || newValue.replaceAll(separator, "").startsWith("+3249")) {
// System.out.println("BELGIQUE GSM");
String resultat = getPhoneNumberFormatted(newValue, "###-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+322") || newValue.replaceAll(separator, "").startsWith("+323") || newValue.replaceAll(separator, "").startsWith("+329")) {
// System.out.println("BELGIQUE AUTRE 1");
String resultat = getPhoneNumberFormatted(newValue, "###-#-###-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 15);
} else if (newValue.startsWith("+32")) {
// System.out.println("BELGIQUE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 15);
} else if (newValue.replaceAll(separator, "").startsWith("+3526")) {
// System.out.println("LUXEMBOURG 1");
String resultat = getPhoneNumberFormatted(newValue, "####-###-###-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+352")) {
// System.out.println("LUXEMBOURG AUTRE");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+377")) {
// System.out.println("MONACO");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+41")) {
// System.out.println("SUISSE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-###-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+390")) {
// System.out.println("ITALIE FIXE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-####-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.replaceAll(separator, "").startsWith("+393")) {
// System.out.println("ITALIE PORTABLE");
String resultat = getPhoneNumberFormatted(newValue, "###-###-###-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+39")) {
// System.out.println("ITALIE AUTRE");
String resultat = getPhoneNumberFormatted(newValue, "###-##-####-####");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+376")) {
// System.out.println("ANDORRE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-###-###");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 16);
} else if (newValue.startsWith("+590")) {
// System.out.println("GUADELOUPE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+596")) {
// System.out.println("MARTINIQUE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+594")) {
// System.out.println("GUYANE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+262")) {
// System.out.println("REUNION ET MAYOTTE");
String resultat = getPhoneNumberFormatted(newValue, "####-###-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 17);
} else if (newValue.startsWith("+687")) {
// System.out.println("NOUVELLE-CALEDONIE");
String resultat = getPhoneNumberFormatted(newValue, "####-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 13);
} else if (newValue.startsWith("+")) {
// System.out.println("AUTRE - PAYS NON REFERENCE");
String resultat = getPhoneNumberFormatted(newValue, "######################");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 22);
} else if (newValue.length() >= 3) {
if (Character.isDigit(newValue.charAt(0))) {
// System.out.println("France Nationnal");
String resultat = getPhoneNumberFormatted(newValue, "##-##-##-##-##");
int caretPosition = tf.getCaretPosition();
setResult(resultat, caretPosition, oldValue, newValue, 14);
}
}
};
textPropertyFromComponent.addListener(updateText);
}
//My attempt to put the cursor in the right place, but VERY scary code
private void setResult(String resultat, int caretPosition, String oldValue, String newValue, int maxLength) {
Platform.runLater(() -> {
if (resultat.length() <= maxLength && newValue != null && oldValue != null) {
textPropertyFromComponent.set(resultat);
// int diffAddLetter = newValue.length() - oldValue.length();
// int diffRemLetter = oldValue.length() - newValue.length();
// System.out.println("oldValue = " + oldValue);
// System.out.println("newValue = " + newValue);
// System.out.println("resultat = " + resultat);
// System.out.println("test = " + last);
// if (newValue.length() == maxLength) {
// if (!"".equals(last)) {
// tf.positionCaret(caretPosition + 1);
// }
// } else if (diffAddLetter > 0) {
// System.out.println("diffAddLetter = " + diffAddLetter);
// System.out.println("lastCaretPosition = " + lastCaretPosition);
// System.out.println("caretPosition = " + caretPosition);
// if ("".equals(last)) {
// if (StringUtils.countMatches(oldValue, separator) < StringUtils.countMatches(newValue, separator)) {
// tf.positionCaret(caretPosition + 1);
// } else {
// tf.positionCaret(caretPosition);
// }
// System.out.println("a1");
// } else {
// tf.positionCaret(caretPosition + diffAddLetter);
// System.out.println("a2");
// }
// if (lastCaretPosition == caretPosition) {
// last = "";
// } else {
// last = oldValue;
// }
// } else if (diffRemLetter > 0) {
// System.out.println("lastCaretPosition = " + lastCaretPosition);
// System.out.println("caretPosition = " + caretPosition);
// System.out.println("diffRemLetter = " + diffRemLetter);
// if ((lastCaretPosition == caretPosition || lastCaretPosition == (caretPosition - diffRemLetter)) && diffRemLetter > 1) {
// tf.positionCaret(caretPosition - diffRemLetter);
// System.out.println("r1");
// } else {
// System.out.println("caretPosition + diffRemLetter = " + (caretPosition - diffRemLetter));
//// System.out.println("(newValue.substring(0, caretPosition) = " + (newValue.substring(0, caretPosition)));
// System.out.println("oldValue.substring(0, caretPosition) = " + oldValue.substring(0, caretPosition));
//// System.out.println("newValue.substring(caretPosition) = " + newValue.substring(caretPosition +1));
// System.out.println("caretPosition = " + caretPosition);
// if (newValue.length() > caretPosition) {
// if (newValue.substring(0, caretPosition).equals(oldValue.substring(0, caretPosition)) && oldValue.endsWith(newValue.substring(caretPosition + 1)) && !"".equals(newValue.substring(caretPosition + 1)) && !String.valueOf(newValue.charAt(caretPosition - 1)).equals(separator)) {
// tf.positionCaret(caretPosition);
// System.out.println("r2");
// } else if (Character.isDigit(newValue.charAt(caretPosition - 1)) && Character.isDigit(newValue.charAt(caretPosition)) && diffRemLetter == 1) {
// tf.positionCaret(caretPosition);
// System.out.println("r5");
// } else {
// tf.positionCaret(caretPosition + 1);
// System.out.println("r3");
// }
// } else {
// System.out.println("r4");
// tf.positionCaret(lastCaretPosition);
// }
// last = oldValue;
// }
// } else if (String.valueOf(resultat.charAt(caretPosition - 1)).equals(separator) && last.length() < resultat.length()) {
// tf.positionCaret(caretPosition + 1);
// System.out.println("s");
// } else {
// tf.positionCaret(caretPosition);
// System.out.println("o");
// }
// if (resultat.length() >= caretPosition) {
// if (oldValue.replaceAll(separator, "").equals(newValue.replaceAll(separator, "")) && String.valueOf(resultat.charAt(caretPosition)).equals(separator)) {
// tf.positionCaret(caretPosition);
// System.out.println("c");
// }
// }
// lastCaretPosition = caretPosition;
} else {
textPropertyFromComponent.set(oldValue);
}
});
textPropertyFromComponent.addListener(updateText);
}
//Method to format the phone number
private String getPhoneNumberFormatted(String phoneNumber, String format) {
textPropertyFromComponent.removeListener(updateText);
String vretour = "";
if (phoneNumber.length() <= format.length()) {
phoneNumber = phoneNumber.replaceAll("[^0-9+]", "");
int index = findXDotPosition(format, phoneNumber.length());
format = format.substring(0, index + 1);
int indexCharArray = 0;
for (char unChar : format.toCharArray()) {
if ("#".charAt(0) == unChar) {
vretour = vretour + phoneNumber.toCharArray()[indexCharArray];
indexCharArray++;
}
if ("-".charAt(0) == unChar) {
vretour = vretour + separator;
}
}
} else {
vretour = phoneNumber;
}
return vretour;
}
//Method to find a separator
private static int findXDotPosition(String s, int separatorToFind) {
int result = -1;
char[] ca = s.toCharArray();
for (int i = 0; i < ca.length; ++i) {
if (ca[i] == '#') {
--separatorToFind;
}
if (separatorToFind == 0) {
return i;
}
}
return result;
}
}
我还为您提供了应用程序实际工作的一些屏幕截图。
https://i.goopics.net/Jl8aR.png https://i.goopics.net/RVvdZ.png
希望你能给我一个解决方案, 提前致谢!
TextFormatter 绝对是正确的选择。您需要构建的是 TextFormatter 的 filter
组件。基本上,您可以将其视为击键处理器(也处理鼠标操作),其中已为您处理了所有低级内容。您得到一个传递给您的 TextFormatter.Change
对象,您可以看到该更改将如何影响该字段中的值,然后修改它、抑制它或让它通过。
所以所有的格式都会立即发生,就在您键入时就在 TextField 中。
我构建了一个来处理北美风格的 phone 数字,因为它比欧洲风格更有趣,因为它有括号和破折号。但是你可以适应它。
我采用的方法是从字符串中删除所有格式字符,然后在每次进行更改时从头开始重新格式化。这似乎比尝试逐个字符 fiddle 更容易。唯一棘手的部分是在“-”或“)”上按
public class PhoneNumberFilter implements UnaryOperator<TextFormatter.Change> {
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if (change.isContentChange()) {
handleBackspaceOverSpecialCharacter(change);
if (change.getText().matches("[0-9]*")) {
int originalNewTextLength = change.getControlNewText().length();
change.setText(formatNumber(change.getControlNewText()));
change.setRange(0, change.getControlText().length());
int caretOffset = change.getControlNewText().length() - originalNewTextLength;
change.setCaretPosition(change.getCaretPosition() + caretOffset);
change.setAnchor(change.getAnchor() + caretOffset);
return change;
} else {
return null;
}
}
return change;
}
private void handleBackspaceOverSpecialCharacter(TextFormatter.Change change) {
if (change.isDeleted() && (change.getSelection().getLength() == 0)) {
if (!Character.isDigit(change.getControlText().charAt(change.getRangeStart()))) {
if (change.getRangeStart() > 0) {
change.setRange(change.getRangeStart() - 1, change.getRangeEnd() - 1);
}
}
}
}
private String formatNumber(String numbers) {
numbers = numbers.replaceAll("[^\d]", "");
numbers = numbers.substring(0, Math.min(10, numbers.length()));
if (numbers.length() == 0) {
return "";
}
if (numbers.length() < 4) {
return "(" + numbers;
}
if (numbers.length() < 7) {
return numbers.replaceFirst("(\d{3})(\d+)", "()");
}
return numbers.replaceFirst("(\d{3})(\d{3})(\d+)", "()-");
}
}
这是一个小测试应用程序。您可以看到转换器只是“开箱即用”的默认转换器,因为它只是一个主要由数字组成的字符串:
public class PhoneNumberTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
TextFormatter<String> textFormatter = new TextFormatter(new DefaultStringConverter(), "", new PhoneNumberFilter());
textField.setTextFormatter(textFormatter);
Scene scene = new Scene(new VBox(textField), 300, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
非常感谢您的回答 DaveB! 它运行良好,我为您提供最终代码:
package PhoneNumberTest;
import java.util.function.UnaryOperator;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.util.converter.DefaultStringConverter;
import org.apache.commons.lang3.StringUtils;
public class PhoneNumberFilter implements UnaryOperator<TextFormatter.Change> {
private String separator = " ";
private int length = 0;
private TextField tf;
private final String formatForFrance = "###-#-##-##-##-##";
private final String formatForAllemagne = "###-###-###-##-###";
private final String formatForEspagne = "###-###-##-##-##";
private final String formatForBelgiqueGSM = "###-###-##-##-##";
private final String formatForBelgiqueAutre = "###-#-###-##-##";
private final String formatForBelgique = "###-##-##-##-##";
private final String formatForLuxembourg = "####-###-###-###";
private final String formatForLuxembourgAutre = "####-##-##-##-##";
private final String formatForMonaco = "####-##-##-##-##";
private final String formatForSuisse = "###-##-###-##-##";
private final String formatForItalieFixe = "###-##-####-####";
private final String formatForItaliePort = "###-###-###-####";
private final String formatForItalieAutre = "###-##-####-####";
private final String formatForAndorre = "####-###-###-###";
private final String formatForGuadeloupe = "####-###-##-##-##";
private final String formatForMartinique = "####-###-##-##-##";
private final String formatForGuyane = "####-###-##-##-##";
private final String formatForReunionMayotte = "####-###-##-##-##";
private final String formatForNouvelleCaledonie = "####-##-##-##";
private final String formatForAutre = "######################";
private final String formatForFranceNationnal = "##-##-##-##-##";
public PhoneNumberFilter(TextField textField, String separator) {
this.tf = textField;
if (separator != null && !separator.isEmpty()) {
this.separator = separator;
} else {
this.separator = "";
}
TextFormatter<String> textFormatter = new TextFormatter(new DefaultStringConverter(), "", new PhoneNumberFilter());
tf.setTextFormatter(textFormatter);
}
public PhoneNumberFilter() {
}
@Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if (change.isContentChange()) {
String resultat = "";
handleBackspaceOverSpecialCharacter(change);
int originalNewTextLength = change.getControlNewText().length();
if (change.getControlNewText().startsWith("+33")) {
// System.out.println("FRANCE");
length = formatForFrance.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForFrance);
} else if (change.getControlNewText().startsWith("+49")) {
// System.out.println("ALLEMAGNE");
length = formatForAllemagne.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAllemagne);
} else if (change.getControlNewText().startsWith("+34")) {
// System.out.println("ESPAGNE");
length = formatForEspagne.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForEspagne);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+3245") || change.getControlNewText().replaceAll(separator, "").startsWith("+3249")) {
// System.out.println("BELGIQUE GSM");
length = formatForBelgiqueGSM.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgiqueGSM);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+322") || change.getControlNewText().replaceAll(separator, "").startsWith("+323") || change.getControlNewText().replaceAll(separator, "").startsWith("+329")) {
// System.out.println("BELGIQUE AUTRE 1");
length = formatForBelgiqueAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgiqueAutre);
} else if (change.getControlNewText().startsWith("+32")) {
// System.out.println("BELGIQUE");
length = formatForBelgique.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForBelgique);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+3526")) {
// System.out.println("LUXEMBOURG 1");
length = formatForLuxembourg.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForLuxembourg);
} else if (change.getControlNewText().startsWith("+352")) {
// System.out.println("LUXEMBOURG AUTRE");
length = formatForLuxembourgAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForLuxembourgAutre);
} else if (change.getControlNewText().startsWith("+377")) {
// System.out.println("MONACO");
length = formatForMonaco.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForMonaco);
} else if (change.getControlNewText().startsWith("+41")) {
// System.out.println("SUISSE");
length = formatForSuisse.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForSuisse);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+390")) {
// System.out.println("ITALIE FIXE");
length = formatForItalieFixe.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItalieFixe);
} else if (change.getControlNewText().replaceAll(separator, "").startsWith("+393")) {
// System.out.println("ITALIE PORTABLE");
length = formatForItaliePort.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItaliePort);
} else if (change.getControlNewText().startsWith("+39")) {
// System.out.println("ITALIE AUTRE");
length = formatForItalieAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForItalieAutre);
} else if (change.getControlNewText().startsWith("+376")) {
// System.out.println("ANDORRE");
length = formatForAndorre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAndorre);
} else if (change.getControlNewText().startsWith("+590")) {
// System.out.println("GUADELOUPE");
length = formatForGuadeloupe.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForGuadeloupe);
} else if (change.getControlNewText().startsWith("+596")) {
// System.out.println("MARTINIQUE");
length = formatForMartinique.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForMartinique);
} else if (change.getControlNewText().startsWith("+594")) {
// System.out.println("GUYANE");
length = formatForGuyane.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForGuyane);
} else if (change.getControlNewText().startsWith("+262")) {
// System.out.println("REUNION ET MAYOTTE");
length = formatForReunionMayotte.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForReunionMayotte);
} else if (change.getControlNewText().startsWith("+687")) {
// System.out.println("NOUVELLE-CALEDONIE");
length = formatForNouvelleCaledonie.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForNouvelleCaledonie);
} else if (change.getControlNewText().startsWith("+")) {
// System.out.println("AUTRE - PAYS NON REFERENCE");
length = formatForAutre.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForAutre);
} else if (change.getControlNewText().length() >= 3) {
if (Character.isDigit(change.getControlNewText().charAt(0))) {
// System.out.println("France Nationnal");
length = formatForFranceNationnal.length();
resultat = getPhoneNumberFormatted(change.getControlNewText(), formatForFranceNationnal);
}
} else {
resultat = change.getControlNewText();
}
if (change.getControlText().length() == length && originalNewTextLength > length && length != 0) {
change.setText(change.getControlText());
} else {
change.setText(resultat);
}
change.setRange(0, change.getControlText().length());
int caretOffset = change.getControlNewText().length() - originalNewTextLength;
change.setCaretPosition(change.getCaretPosition() + caretOffset);
change.setAnchor(change.getAnchor() + caretOffset);
return change;
}
return change;
}
private void handleBackspaceOverSpecialCharacter(TextFormatter.Change change) {
if (change.isDeleted() && (change.getSelection().getLength() == 0)) {
if (!Character.isDigit(change.getControlText().charAt(change.getRangeStart())) && !"+".equals(String.valueOf(change.getControlText().charAt(change.getRangeStart())))) {
if (change.getRangeStart() > 0) {
change.setRange(change.getRangeStart() - 1, change.getRangeEnd() - 1);
}
}
}
}
private String getPhoneNumberFormatted(String phoneNumber, String format) {
if (phoneNumber.length() > length) {
phoneNumber = phoneNumber.substring(0, length);
}
String vretour = "";
if (phoneNumber.length() <= format.length()) {
phoneNumber = phoneNumber.replaceAll("[^0-9+]", "");
int index = findXDotPosition(format, phoneNumber.length());
format = format.substring(0, index + 1);
int indexCharArray = 0;
for (char unChar : format.toCharArray()) {
if ("#".charAt(0) == unChar) {
vretour = vretour + phoneNumber.toCharArray()[indexCharArray];
indexCharArray++;
}
if ("-".charAt(0) == unChar) {
vretour = vretour + separator;
}
}
} else {
vretour = phoneNumber;
}
return vretour;
}
private static int findXDotPosition(String s, int separatorToFind) {
int result = -1;
char[] ca = s.toCharArray();
for (int i = 0; i < ca.length; ++i) {
if (ca[i] == '#') {
--separatorToFind;
}
if (separatorToFind == 0) {
return i;
}
}
return result;
}
}
像这样创建一个对象new PhoneNumberFilter(tf, " ");
(tf = TextField,第二个参数是不同 phone 数字之间的分隔符)。这将执行程序的其余部分并将重新格式化输入的数字。
我只有最后一个问题。当我在 phone 数字的末尾单击两次,或者当我尝试在数字已经是指示的最大字符数时写到最后时,我的光标无缘无故地向后移动了 1 个缺口并且我找不到强制光标停留在数字末尾的方法。 这是正常的吗?有解决办法吗?