如何限制TextField,使其只能包含一个'。'字符? JavaFX的 [英] How to restrict TextField so that it can contain only one '.' character? JavaFX

查看:129
本文介绍了如何限制TextField,使其只能包含一个'。'字符? JavaFX的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在互联网上,我找到了非常有用的类,使用它我可以限制TextField。我遇到了一个问题,我的TextField只能包含一个'。'字符。我怀疑我可以通过编写appripriate正则表达式并将其设置为对该类实例的限制来处理此问题。我使用以下正则表达式:[0-9.-],但它允许与用户类型一样多的点。我可以请你帮我配置我的TextField,以便允许不超过一个'。'。

On the Internet, I found very useful class, using which I can restrict TextField. I encountered a problem, where my TextField can contain only one '.' character. I suspect that I can handle this by writing an appripriate regex and set it as a restriction on the instance of that class. I use the following regex: "[0-9.-]", but it allows as many dots as the user types. May I ask you to help me to configure my TextField so that no more than one '.' is allowed.

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
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;

/**
 * Created by Anton on 7/14/2015.
 */
public class RestrictiveTextField extends TextField {
private IntegerProperty maxLength = new SimpleIntegerProperty(this, "maxLength", -1);
private StringProperty restrict = new SimpleStringProperty(this, "restrict");

public RestrictiveTextField() {
    super("0");
    textProperty().addListener(new ChangeListener<String>() {

        private boolean ignore;

        @Override
        public void changed(ObservableValue<? extends String> observableValue, String s, String s1) {

            if (ignore || s1 == null)
                return;
            if (maxLength.get() > -1 && s1.length() > maxLength.get()) {
                ignore = true;
                setText(s1.substring(0, maxLength.get()));
                ignore = false;
            }

            if (restrict.get() != null && !restrict.get().equals("") && !s1.matches(restrict.get() + "*")) {
                ignore = true;
                setText(s);
                ignore = false;
            }
        }
    });
}

/**
 * The max length property.
 *
 * @return The max length property.
 */
public IntegerProperty maxLengthProperty() {
    return maxLength;
}

/**
 * Gets the max length of the text field.
 *
 * @return The max length.
 */
public int getMaxLength() {
    return maxLength.get();
}

/**
 * Sets the max length of the text field.
 *
 * @param maxLength The max length.
 */
public void setMaxLength(int maxLength) {
    this.maxLength.set(maxLength);
}

/**
 * The restrict property.
 *
 * @return The restrict property.
 */
public StringProperty restrictProperty() {
    return restrict;
}

/**
 * Gets a regular expression character class which restricts the user input.

 *
 * @return The regular expression.
 * @see #getRestrict()
 */
public String getRestrict() {
    return restrict.get();
}

/**
 * Sets a regular expression character class which restricts the user input.

 * E.g. [0-9] only allows numeric values.
 *
 * @param restrict The regular expression.
 */
public void setRestrict(String restrict) {
    this.restrict.set(restrict);
}

}

推荐答案

正则表达式有各种版本,具体取决于您想要支持的内容。请注意,您不仅要匹配有效数字,还要匹配部分条目,因为用户必须能够编辑它。因此,例如,空字符串不是有效数字,但您当然希望用户能够删除编辑时那里的所有内容;同样你想允许0。等等。

There are various versions of the regex, depending on exactly what you want to support. Note that you don't only want to match valid numbers, but also partial entries, because the user has to be able to edit this. So, for example, an empty string is not a valid number, but you certainly want the user to be able to delete everything that's there while they are editing; similarly you want to allow "0.", etc.

所以你可能想要像

可选减号,后跟 任意数字,至少一位数,一段时间(),以及任意数量的数字。

Optional minus sign, followed by either any number of digits, or at least one digit, a period (.), and any number of digits.

这个的正则表达式可能是 - ?((\\\\ *)|(\\d + \。\ \d *))。可能有其他方法可以做到这一点,其中一些可能更有效。如果你想支持指数形式(1.3e12),它会变得更复杂。

The regex for this could be -?((\\d*)|(\\d+\.\\d*)). There are probably other ways to do this, some of them perhaps more efficient. And if you want to support exponential forms ("1.3e12") it gets more complex.

要使用它以的TextField ,推荐的方法是使用一个 TextFormatter TextFormatter 包含两件事:一个转换器,用于在文本及其代表的值之间进行转换( Double case:你可以使用内置的 DoubleStringConverter ),反之亦然,然后使用过滤器。过滤器实现为一个函数,它接受 TextFormatter.Change 对象并返回相同类型的对象。通常你要保留更改对象并将其返回(按原样接受更改),或以某种方式修改它。返回 null 表示无变化也是合法的。所以在这里简单的例子中,只需检查新建议的文本,看它是否与正则表达式匹配,如果匹配则返回原样,否则返回 null

To use this with a TextField, the recommended way is to use a TextFormatter. The TextFormatter consists of two things: a converter to convert between the text and the value it represents (a Double in your case: you can just use the built-in DoubleStringConverter), and vice versa, and then a filter. The filter is implemented as a function that takes a TextFormatter.Change object and returns an object of the same type. Typically you either leave the Change object as it is and return it (to accept the Change "as is"), or modify it somehow. It is also legal to return null to represent "no change". So in your simple case here, just examine the new proposed text, see if it matches the regular expression, return the change "as is" if it matches and return null otherwise.

示例:

import java.util.regex.Pattern;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.converter.DoubleStringConverter;

public class NumericTextFieldExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TextField textField = new TextField();

        Pattern validDoubleText = Pattern.compile("-?((\\d*)|(\\d+\\.\\d*))");

        TextFormatter<Double> textFormatter = new TextFormatter<Double>(new DoubleStringConverter(), 0.0, 
            change -> {
                String newText = change.getControlNewText() ;
                if (validDoubleText.matcher(newText).matches()) {
                    return change ;
                } else return null ;
            });

        textField.setTextFormatter(textFormatter);

        textFormatter.valueProperty().addListener((obs, oldValue, newValue) -> {
            System.out.println("New double value "+newValue);
        });

        StackPane root = new StackPane(textField);
        root.setPadding(new Insets(24));
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这篇关于如何限制TextField,使其只能包含一个'。'字符? JavaFX的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆