如何在 JavaFX 中的 TextField 中强制进行双输入?

2024-02-22

如何确保用户仅输入双精度值在给定的文本字段中?

我找到了一个整数的解 https://stackoverflow.com/questions/7555564/what-is-the-recommended-way-to-make-a-numeric-textfield-in-javafx但我无法将其用于双打。我应该写什么而不是"\\d*" and "[^\\d]"让它适用于双打?

textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        if (!newValue.matches("\\d*")) {
            textField.setText(newValue.replaceAll("[^\\d]", ""));
        }
    }
});

使用侦听器并在用户输入无效值时恢复为有效值的方法将起作用,但如果文本字段上有其他侦听器,则可能会产生问题textProperty。这些侦听器将观察无效值和有效值,因此他们必须知道过滤掉任何无效值。

更好的方法是使用TextFormatter http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TextFormatter.html. The TextFormatter可以做两件事:

  1. 定义一个“过滤器”,它可以否决或修改对TextField's text
  2. 定义一个“转换器”,它定义如何在文本与任何特定类型的值之间进行转换(例如Double)在你的情况下。

定义适当的过滤器可能很棘手:您希望允许用户进行任何合理的编辑。这意味着用户在编辑时文本可能处于无效状态;例如您可能希望允许文本字段完全为空,即使这并不代表有效值。 (否则,例如,如果用户想要将“1”更改为“2”,这会让用户感到厌烦。)类似地,您可能希望允许“-”和“.”等内容。

这是一个例子。如果需要,过滤器应该修改传递给它的更改,并且可以返回null完全否决变更。此示例只是检查文本是否表示有效的编辑状态,如果是,则返回未修改的更改,否则否决它。格式化程序需要处理过滤器允许的任何文本并将其转换为双精度型。这里任何不完整的东西都被表示为零。

Pattern validEditingState = Pattern.compile("-?(([1-9][0-9]*)|0)?(\\.[0-9]*)?");

UnaryOperator<TextFormatter.Change> filter = c -> {
    String text = c.getControlNewText();
    if (validEditingState.matcher(text).matches()) {
        return c ;
    } else {
        return null ;
    }
};

StringConverter<Double> converter = new StringConverter<Double>() {

    @Override
    public Double fromString(String s) {
        if (s.isEmpty() || "-".equals(s) || ".".equals(s) || "-.".equals(s)) {
            return 0.0 ;
        } else {
            return Double.valueOf(s);
        }
    }


    @Override
    public String toString(Double d) {
        return d.toString();
    }
};

TextFormatter<Double> textFormatter = new TextFormatter<>(converter, 0.0, filter);
TextField textField = new TextField();
textField.setTextFormatter(textFormatter);

如果需要,您可以使正则表达式更复杂,例如支持对字符进行分组("1,000.0")、本地化("1.003,14159"如果这适用于语言环境),或类似科学记数法的表示("6.022E23"等),并强制执行最小值或最大值等。您甚至可以执行诸如修改更改之类的操作,以便如果用户键入-在文本中的任何位置,它只是翻转数字的符号。 (请参阅TextFormatter.Change文档 http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TextFormatter.Change.html对于这种功能。)

请注意,您可以直接从格式化程序获取和设置双精度值(由转换器提供),格式化程序有一个ObjectProperty<Double> valueProperty()。所以你可以做类似的事情

// update text field:
double value = ... ;
textFormatter.setValue(value);

// listen for changes in double value represented in text field
// Listener will be invoked when the user commits an edit:

textFormatter.valueProperty().addListener((ObservableValue<? extends Double> obs, Double oldValue, Double newValue) -> {
    System.out.println("User entered value: "+newValue.doubleValue());
});

这是一个 SSCCE。第二个文本字段就在那里,以便您可以看到将焦点移动到不同控件的效果(如果值已更改,它会“提交”该值并调用文本格式化程序上的侦听器;如果用户按回车键)。

import java.util.function.UnaryOperator;
import java.util.regex.Pattern;

import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class NumericTextField extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Pattern validEditingState = Pattern.compile("-?(([1-9][0-9]*)|0)?(\\.[0-9]*)?");

        UnaryOperator<TextFormatter.Change> filter = c -> {
            String text = c.getControlNewText();
            if (validEditingState.matcher(text).matches()) {
                return c ;
            } else {
                return null ;
            }
        };

        StringConverter<Double> converter = new StringConverter<Double>() {

            @Override
            public Double fromString(String s) {
                if (s.isEmpty() || "-".equals(s) || ".".equals(s) || "-.".equals(s)) {
                    return 0.0 ;
                } else {
                    return Double.valueOf(s);
                }
            }


            @Override
            public String toString(Double d) {
                return d.toString();
            }
        };

        TextFormatter<Double> textFormatter = new TextFormatter<>(converter, 0.0, filter);
        TextField textField = new TextField();
        textField.setTextFormatter(textFormatter);

        textFormatter.valueProperty().addListener((ObservableValue<? extends Double> obs, Double oldValue, Double newValue) -> {
            System.out.println("User entered value: "+newValue.doubleValue());
        });

        VBox root = new VBox(5, textField, new TextField());
        root.setAlignment(Pos.CENTER);
        primaryStage.setScene(new Scene(root, 250, 250));
        primaryStage.show();
    }

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

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 JavaFX 中的 TextField 中强制进行双输入? 的相关文章

随机推荐

  • C# 中的复杂计算

    最好的 最有效的 工具是什么 NET C 用于计算 积分 偏导数 其他不平凡的数学 人们能否对 Mathematica 和 Matlab 及其集成发表评论C Math NET http www mathdotnet com是一个用 C 编写
  • 2d 球未正确碰撞

    我只是想编写一个漂亮的物理游戏 球碰撞看起来不错 但如果球碰撞太慢 它们就会 粘 在一起 我不知道他们为什么这样做 这是我的碰撞函数 private void checkForCollision ArrayList
  • 将网络响应流放入 iframe - 麻烦

    嘿 又来了 stackoverflowers 我正在从旧的 ASP VBScript 中 迁移一个网站 并且我必须使用 iFrame 来保持旧的内容在新容器中工作 在 aspx 页面上 我有一个带有 runat server 属性的 iFr
  • 调用map后pyspark EOFError

    我是 Spark 和 pyspark 的新手 我正在将一个小 csv 文件 40k 读入数据帧 from pyspark sql import functions as F df sqlContext read format com dat
  • 使用 ODBC + Access 时转义 SQL 查询中的输入数据

    我试过了odbc prepare odbc execute 更新 Access 文件中的记录 但我总是得到SQL state 07001关于不正确的列计数的错误消息 实际上 该消息是西班牙式英语 没有多大意义
  • 重写超类的指定初始值设定项

    我正在读一本书 其中有一个指南 如果一个类声明了与其超类不同的指定初始值设定项 则必须覆盖超类的指定初始值设定项才能调用新的指定初始值设定项 换句话说 据我了解 这条准则是 如果我从其超类中对我的类进行子类化 并且我的子类有一个与 des
  • Keras model.to_json() 错误:“rawunicodeescape”编解码器无法解码位置 94-98 中的字节:截断的 \uXXXX

    model to json 对于模型 层 类型 输出形状参数 连接到 lambda 1 Lambda 无 3 160 320 0lambda input 1 0 0
  • Linux内核中如何选择“sys”和“proc”文件

    据我所知 在Linux文件系统中 为了用户空间和内核空间之间的信息通信 使用了两种虚拟文件系统 1 过程文件系统 http www tldp org LDP Linux Filesystem Hierarchy html proc html
  • Perl 没有警告旧 Perl 的“实验性”

    我有一段代码使用了很多实验 when smartmatch given 功能 这不是我的代码 我不想看到很多关于实验性功能的警告 所以我添加了no warnings experimental 到这段代码 但experimental类别仅在
  • AFNetworking 2.x.x 中的 AFJSONParameterEncoding

    我正在实施以下贝宝 REST API curl v https api sandbox paypal com v1 vault credit card H Content Type application json H Authorizat
  • 我的 docker 容器没有互联网

    我本来可以正常工作 但现在停止了 我尝试了以下命令但没有效果 docker run dns 8 8 8 8 base ping google com docker run base ping google com sysctl w net
  • React Native 中的旋转动画

    我需要用一个图像创建一个动画 该图像将围绕另一个图像旋转 我已经尝试使用类似问题的建议 例如围绕另一个圆制作一个圆的动画 https stackoverflow com questions 55667722 animate a circle
  • TFS 2017 是否能够将构建定义导出和导入到远程服务器中?

    我们在内部服务器上安装了 Team Foundation Server 2017 我们在沙箱环境中构建 NET 代码 但希望能够手动或远程推送新的构建定义或更新 到我们的客户端 生产服务器 自动化的方式 是的 您可以在 TFS 2017 中
  • 在不知道键的情况下解析 json

    我试图在不知道 json 格式的键和结构的情况下解析 java 中的 json 并将该数据保存到 hashmap 中 我如何循环遍历整个 json 格式并将键和值存储到 hashmap 中 id 12345 value 123 person
  • 原始“null”和 Java 8

    我知道处理的最佳实践null原语是使用盒装包装器 例如Integer代替int 正如这里所讨论的 原始数据类型为 Null https stackoverflow com questions 11047276 null for primit
  • dartlang 和 dartdap 库以及与活动目录的连接

    我一直在为 Dart 寻找一个好的 ldap 库来连接 Microsoft Active Directory 我找到了 dartdap 但我似乎无法让它工作 我 100 确信我的 CN 和密码是正确的 因为我可以使用 lpap 浏览器连接到
  • 剪切 HTML 标签并再次包装 HTML 标签第 1 部分 [重复]

    这个问题在这里已经有答案了 我尝试转换以下字符串 p string b bold em italic string em also bold b p 到这个字符串 p string p b bold b em italic string e
  • Parse 中的主要错误:[PFUser currentUser] 死锁

    Parse 社区已多次提出通过解析后台调用因线程争用而导致 PFUser 死锁的问题 但 Parse 选择不处理框架中的这个巨大错误 有谁知道这个问题的解决方法 关于此问题的其他明显报告 https developers facebook
  • 如何在android中将数据库文件附加到电子邮件中?

    您好 我正在尝试通过附加数据库发送电子邮件 我收到邮件 但没有附加以下是我的代码 谁能帮我 尝试 String host smtp gmail com String from email protected cdn cgi l email
  • 如何在 JavaFX 中的 TextField 中强制进行双输入?

    如何确保用户仅输入双精度值在给定的文本字段中 我找到了一个整数的解 https stackoverflow com questions 7555564 what is the recommended way to make a numeri