11

我正在创建一些表单,我需要为某些字段创建掩码和验证。

它是否在 JavaFX 中实现?

4

8 回答 8

13

我的面具的例子。

使用:

<MaskField mask="+7(DDD)DDD-DDDD"/>
<MaskField mask="AA DDD AAA" placeholder="__ ### ___"/>

ETC

于 2015-09-17T17:07:49.080 回答
3

限制来自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 存储库中,有一些控件可以限制对整数、双精度数或格式化的网络颜色(例如#rrggbb )的输入。所有这些都遵循一个共同的主题,它们是Control的子类,提供一些要获取和设置的属性,这些属性定义了公共接口,然后还定义了一个私有的支持皮肤,它根据通过公共接口设置的值来处理 UI 的呈现。

于 2012-12-06T11:11:01.530 回答
2

注意:这只适用于 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.2 TextField maxlength

于 2014-03-03T23:39:23.310 回答
2

我也有同样的需求。我创建了这个字段,将其命名为 SpecialTextField,然后推送到GitHub。也有例子。希望这有帮助。

于 2015-04-25T14:03:42.297 回答
1

当前 javafx-2 平台默认支持 - 否,但通过这个链接 ,它有很多关于 javaFX 中表单验证的见解和示例代码

于 2012-12-06T01:08:34.130 回答
0
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);
        }
    }
}
于 2015-01-10T15:53:39.483 回答
0

在某些情况下,我会验证 text 属性:

myTextField
    .textProperty()
    .addListener(
    (obs, oldVal, newVal) -> 
        { 
            if(!newVal.matches("\\d+"))
                textField.setText(oldV);
        });

Unlucky: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);
        });
于 2016-06-27T17:57:24.177 回答
0

我编写了一个扩展 TextField 并应用掩码的类。

package com.model;

import java.text.NumberFormat;
import java.util.Locale;

/**
 * ATENTION
 * DO NOT FORGUET TO IMPORT IN FXML   
 * <?import com.view.TextFieldMoney?>
 * 
 * */

import javafx.scene.control.TextField;

public class TextFieldMoney extends TextField {
    private int maxlength;
    private String valor = "";

    public TextFieldMoney() {
        this.maxlength = 11;
    }

    public void setMaxlength(int maxlength) {
        this.maxlength = maxlength;
    }

    @Override
    public void replaceText(int start, int end, String text) {
        // Delete or backspace user input.
        if (getText() == null || getText().equalsIgnoreCase("")) {
            valor = "";
        }
        if (text.equals("")) {
            super.replaceText(start, end, text);
        } else{


            text = text.replaceAll("[^0-9]", "");
            valor += text;

            super.replaceText(start, end, text);
            if (!valor.equalsIgnoreCase(""))
                setText(formata(valor));
        }
    }

    @Override
    public void replaceSelection(String text) {
        // Delete or backspace user input.
        if (text.equals("")) {
            super.replaceSelection(text);
        } else if (getText().length() < maxlength) {
            // Add characters, but don't exceed maxlength.
            // text = MascaraFinanceira.show(text);
            if (text.length() > maxlength - getText().length()) {
                // text = MascaraFinanceira.show(text);
                text = text.substring(0, maxlength - getText().length());
            }
            super.replaceSelection(text);
        }
    }

    /*
     *Return the number without money mask
     **/

    public String getCleanValue(){
        String cleanString = getText().replaceAll("[^0-9]", "");
        Double cleanNumber = new Double(cleanString);
        return String.valueOf(cleanNumber/100);
    }

    private String formata(Double valor) {
        Locale locale = new Locale("pt", "BR");
        NumberFormat nf = NumberFormat.getInstance(locale);
        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);

        return nf.format(valor);
    }

    public String formata(String valor) {
        double v = new Double(valor);
        return formata(v/100);
    }

}

在 FXML 中

 <TextField fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />

 <TextFieldMoney fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />
于 2016-12-05T21:58:42.133 回答