いくつかのフォームを作成していますが、いくつかのフィールドのマスクと検証を作成する必要があります。
とにかくJavaFXに実装されていますか?
マスクの私の例。
使用:
<MaskField mask="+7(DDD)DDD-DDDD"/>
<MaskField mask="AA DDD AAA" placeholder="__ ### ___"/>
等
Richard の fxexperience 投稿からの入力を制限する:
TextField field = new TextField() {
@Override public void replaceText(int start, int end, String text) {
// If the replaced text would end up being invalid, then simply
// ignore this call!
if (!text.matches("[a-z]")) {
super.replaceText(start, end, text);
}
}
@Override public void replaceSelection(String text) {
if (!text.matches("[a-z]")) {
super.replaceSelection(text);
}
}
};
マスクを使用して独自のコントロールを作成する場合は、Richard の MoneyFieldを参照してください。サンプル プロジェクトとソースも含まれています。同様に、 fxexperience リポジトリには、入力を Integers、Double、またはフォーマットされた Web カラー (#rrggbb など) に制限するためのコントロールがあります。これらはすべて、Controlをサブクラス化し、パブリック インターフェイスを定義する取得および設定するいくつかのプロパティを提供し、パブリック インターフェイスを介して設定された値に基づいて UI のレンダリングを処理するプライベート バッキング スキンを定義するという共通のテーマに従います。
注: これは、JRE 1.8.0_25 以下でのみ正しく機能します。JRE 1.8.0_48 または 0_51 では、文字入力ごとにキャレット位置が常に 0 に設定されます。
いいえ、これは標準 JavaFX では実装されていません。ライブラリを使用するか、自分で行う必要があります。
これは、テキスト フィールドの静的マスクの実装です。日付、電話、およびその他のタイプの静的マスクで機能します。
/**
* Adds a static mask to the specified text field.
* @param tf the text field.
* @param mask the mask to apply.
* Example of usage: addMask(txtDate, " / / ");
*/
public static void addMask(final TextField tf, final String mask) {
tf.setText(mask);
addTextLimiter(tf, mask.length());
tf.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
String value = stripMask(tf.getText(), mask);
tf.setText(merge(value, mask));
}
});
tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(final KeyEvent e) {
int caretPosition = tf.getCaretPosition();
if (caretPosition < mask.length()-1 && mask.charAt(caretPosition) != ' ' && e.getCode() != KeyCode.BACK_SPACE && e.getCode() != KeyCode.LEFT) {
tf.positionCaret(caretPosition + 1);
}
}
});
}
static String merge(final String value, final String mask) {
final StringBuilder sb = new StringBuilder(mask);
int k = 0;
for (int i = 0; i < mask.length(); i++) {
if (mask.charAt(i) == ' ' && k < value.length()) {
sb.setCharAt(i, value.charAt(k));
k++;
}
}
return sb.toString();
}
static String stripMask(String text, final String mask) {
final Set<String> maskChars = new HashSet<>();
for (int i = 0; i < mask.length(); i++) {
char c = mask.charAt(i);
if (c != ' ') {
maskChars.add(String.valueOf(c));
}
}
for (String c : maskChars) {
text = text.replace(c, "");
}
return text;
}
public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
if (tf.getText().length() > maxLength) {
String s = tf.getText().substring(0, maxLength);
tf.setText(s);
}
}
});
}
現在の javafx-2 プラットフォームでデフォルトでサポートされています - いいえ、しかしこのリンク を参照してください。javaFX でのフォーム検証に関する多くの洞察とサンプル コードがあります。
場合によっては、テキスト プロパティを検証します。
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldV);
});
不運: textField.setText(oldV);
oldVal が一致するかどうか不必要にテストして、同じ関数を再び入力します。
このリスナーが TextField に追加される前に TextField が一致しない値になった場合、一致しない新しい値を入力するとループが発生します!!!
これを避けるには、次のように書く方が安全です。
String acceptableValue = "0";
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldVal.matches("\\d+") ? oldV : acceptableValue);
});
public class NumberTextField extends TextField {
private int maxLenght;
public NumberTextField(int maxLenght) {
super();
this.maxLenght = maxLenght;
}
@Override
public void replaceText(int start, int end, String text) {
if (validate(text)) {
super.replaceText(start, end, text);
}
}
@Override
public void replaceSelection(String text) {
if (validate(text)) {
super.replaceSelection(text);
}
}
private boolean validate(String text) {
if (this.getText() != null) {
}
boolean status = ("".equals(text) || text.matches("[0-9]"));
if (this.getText() == null) {
return status;
} else {
return (status && this.getText().length() < maxLenght);
}
}
}