当前位置: 首页 > 知识库问答 >
问题:

JavaFX组合框< POJO >不更新值

孟树
2023-03-14

几个小时寻找答案后,我终于放弃了。我有一个包含以下组合框的FXML表单:

<ComboBox fx:id="cboTipo" disable="true" prefWidth="247.0" promptText="Tipo de obra..." GridPane.columnIndex="1" GridPane.rowIndex="2" />

它注入到 JavaFX 控制器类中:

    @FXML
    public ComboBox<Tobra> cboTipo;

该组合显示了使用Eclipselink 2.7和JPA 2.2从嵌入式H2数据库加载的Tobra(在西班牙语中代表Tipo de Obra)列表。

我不会向用户展示Tobra的价值。toString,相反,我在初始化中设置了一个转换器:

@Override
public void initialize(URL url, ResourceBundle rb) {
    ...
    Objects.requireNonNull(cboTipo, "cboTipo not injected");
    ...
    cboTipo.setConverter(new StringConverter<Tobra>() {
        @Override
        public String toString(Tobra object) {
            return object.getCod() + ": " + object.getNombre();
        }

        @Override
        public Tobra fromString(String string) {
            return new Tobra(string);
        }
    });
   ...
}

我有一个实现<code>Task的内部类

task.setOnSucceeded(evt ->
    cboTipo.setItems(FXCollections.observableArrayList(task.getValue()))
);

当然,当显示窗体时,我在线程中运行任务:

 new Thread(task).start();

在代码被测试之前,一切似乎都很好。不管我点击什么值,总是选择的值重置为第一个项目。我试图从代码中强制一些值,它显示在组合框中,但是当用户单击组合框选择另一个值时,选择的值再次被重置为“第一项”。只有在使用带有类型参数的ComboBox时,才会出现这种行为。当我创建没有类型参数的combobox,然后我添加字符串值,就像这样:

 cboTipo.getItems().clear();
 cboTipo.getItems().addAll(
  tobraList.stream().map(x 
       -> x.getCod() + ": " + x.getNombre())
  .toArray());

一切正常。

因此,我尝试在不映射到字符串的情况下对POJO Tobra执行同样的操作:

 cboTipo.getItems().clear();
 cboTipo.getItems().addAll(tobraList);

但是问题又出现了。我也尝试过在没有类型参数的情况下声明< code>ComboBox cboTipo,但是都不起作用。我的POJO Tobra以这种方式覆盖equals方法:

@Override
public boolean equals(Object object) {
    if (!(object instanceof Tobra)) {
        return false;
    }
      var other = (Tobra) object;
    return ((this.cod == null && other.cod != null)
            || (this.cod != null && !this.cod.equals(other.cod)));
}

我做错了什么?

PS:我还尝试按照以下建议设置自己的单元格工厂:带有自定义对象的Javafx组合框显示对象地址,尽管使用自定义单元格工厂

尝试并调试它,我意识到问题不在于组件的呈现,因为 ComboBox 的值属性在选择后永远不会更新。

共有2个答案

萧远
2023-03-14

我这样解决了改变equals方法的问题:

@Override
    public boolean equals(Object object) {
        if (object == null || !getClass().isAssignableFrom(object.getClass())) {
            return false;
        } else {
              var other = (Tobra) object;
            return Objects.equals(this.cod, other.cod);
        }
    }

教训:永远不要相信自动生成的代码。

隗翰海
2023-03-14

您的equals()方法很奇怪。

return ((this.cod == null && other.cod != null)
        || (this.cod != null && !this.cod.equals(other.cod)));

我们分手吧。第一部分:

(this.cod == null && other.cod != null)

如果此Tobracodnull并且另一个Tobracod不是null,则此部分为true

现在,当发生这种情况时,整个表达式将返回 true,因为您有一个 || 运算符。

我们来看第二部分。

(this.cod != null && !this.cod.equals(other.cod))

如果此Tobracod不为 ,并且其他 cod不相等,则此部分为true

这看起来又是相反的。

很可能你需要整个表达式。或者,您可以使用 Objects.equals(this.cod, other.cod),它会为您检查 null。

最后,确保您还重写了hashCode(),并返回一个正确的值,该值不会破坏equals()的约定。阅读Javadoc了解更多详细信息。

 类似资料:
  • 我需要关于设置组合框按钮单元格的帮助。我使用一个组合框来显示可观察列表中的数据,该列表包含两个列的表中的数据,“步骤”和“下一步”(下一步包含一个插入在步骤列中的项目);我需要做的是显示带有“步骤”列表的组合框列表单元格和相对的“下一步”按钮单元格。现在,我可以正确地看到列表单元格,但我的按钮单元格总是空的。 代码: 提前感谢。

  • 我想做的是让一个类保持国家的静态可观察列表。我想在组合框中显示这些国家。我这部分工作得很好。现在,我还想让用户能够向列表中添加新的国家。因此,组合框旁边有一个按钮,它将显示另一个允许输入另一个国家名称的对话框。在用户输入国家名称并单击save之后,我希望单个静态ObservableList用新的国家更新,然后显示在组合框中。这部分没有发生。 我将展示什么有效,什么无效。 保存对静态列表的引用并更新

  • 提前谢了。

  • 我试图创建一个,它将显示所选的预览,但是会显示字符串值。 唯一有效的方法似乎是创建

  • 我想要一个组合框,它会在用户键入时过滤列表项。它应该如下工作: 键入时,文本字段应该显示一个可能的选择,但是用户尚未键入的单词部分应该突出显示。 当他打开列表时,下拉框应该只显示可能的选项? 使用箭头键,用户应该在缩小可能的项目后选择剩余的项目之一。 过滤并不重要,跳转到第一个匹配的选择也可以。 有类似的吗?

  • 我正在开发一些学术性的JavaFX桌面应用程序。在创建注册表单时,我需要使用combobox/choicebox,但在这一步中我遇到了几个问题。组合框没有显示任何项目。我尝试了许多在堆栈溢出上找到的修复方法,但似乎都不起作用。我在分享我的主要观点。java控制器代码和我的FXML代码放在一边。 Main.java Controller.java FXML文件