【问题标题】:javaFX text fields and listenersjavaFX 文本字段和侦听器
【发布时间】:2016-06-03 18:14:25
【问题描述】:

我面临的情况是,有两个文本字段,每个字段有 2 个单独的侦听器。

TextField customerId 和 TextField customerName。

1000 莫汉

1002 米通

我正在尝试在填写一个文本字段时自动更新其他文本字段,例如,如果填写了 customerId 1000,则相应的客户名称 mohan 将更新为文本字段 customerName,如果填写了 mohan,则将填写他的客户 id 1000 customerId 文本字段。我正在使用地图,问题是当一个文本字段填充它的侦听器时,它会回调相同的文本字段侦听器,这会导致循环最终导致很多错误。我应该怎么做才能解决这个问题?

小例子

    Map<String, String> treeMapCustomerName,treeMapCustomerId;

     treeMapCustomerName=new TreeMap<String,String>();
     treeMapCustomerId=new TreeMap<String,String>();
String customerName="mohan";
String customerId="1000";

treeMapCustomerId.put("1000","Mohan");
treeMapCustomerId.put("1002","Mithun");

treeMapCustomerName.put("Mohan","1000");
treeMapCustomerName.put("Mithun","1002");




        customerName.textProperty().addListener((observable, oldValue, newValue) -> {

        customerId.setText(treeMapCustomerName.get(customerName));//immediately customerId textfield listener is triggered which will trigger this listener causing cycles  

        });

        customerId.textProperty().addListener((observable, oldValue, newValue) -> {

        customerName.setText(treeMapCustomerId.get(customerId));

        });

【问题讨论】:

  • 当然,您可以在这里得到的唯一错误是空指针异常,因为您必须对 treeMapCustomerName.get(...)treeMapCustomerId.get(...) 的调用必须返回 null(您正在将文本字段传递给 get方法,并且您永远 - 实际上不能 - 将地图中的任何值与文本字段相关联,因此 get() 调用返回 null)。
  • 是的,你是对的,现在已经修复了
  • 以及如何删除冗余代码
  • @James_D 我错了这个“立即触发 customerId 文本字段侦听器,这将触发此侦听器导致循环”。我对 javafx 还很陌生,我知道我需要了解很多概念。
  • 它不会导致循环,它应该在几次迭代后停止(最多)。 (想一想:您在名称字段中输入,这将导致customerId.setText(null),这会触发customerId 上的侦听器:这反过来会导致空指针异常或customerName.setText(null)。如果最后一个不会导致空指针异常,它会导致 customerId.setText(null); 什么都不做,因为值已经为空。)没关系,我想回想起来你可能需要检查映射中存在的值(或者至少检查新值是不为空或为空)。

标签: java javafx binding


【解决方案1】:

您没有利用新值,而是使用控件访问地图,这将在运行时引发错误

您可以检查地图是否包含您的密钥,如果存在则仅更新其他文本字段,如下所示:

            customerName.textProperty().addListener((observable, oldValue, newValue) -> {
                if(treeMapCustomerName.containsKey(newValue)){
                    customerId.setText(treeMapCustomerName.get(newValue));
                }
            });

            customerId.textProperty().addListener((observable, oldValue, newValue) -> {
                if(treeMapCustomerId.containsKey(newValue)){
                    customerName.setText(treeMapCustomerId.get(newValue));
                }
            });

这将避免在输入完整的 ID/用户名之前检查地图的问题,但是这不会解决输入的值是另一个值的子字符串的问题。

例如如果地图包含 id 的 100、1000、10000,并且您不希望每个都显示为用户键入 10000,则您可能需要一个额外的控件(例如按钮)而不是使用属性

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多