JavaFX ComboBox <pojo>不更新值

时间:2018-06-21 07:35:40

标签: java javafx combobox

经过几个小时的寻找答案,我终于放弃了。 我有一个带有以下ComboBox的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);
        }
    });
   ...
}

我有一个实现Task<List<Tobra>>的内部类,因此我可以在后台加载数据。然后,就成功了:

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

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

 new Thread(task).start();

在测试代码之前,一切似乎都可以正常工作。不管我单击哪个值,总是将所选值重置为第一项。我试图从代码中强制使用某些值,并且该值显示在组合框中,但是当用户单击组合以选择另一个值时,再次将所选值重置为“第一项”。 仅当使用带有类型参数的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);

但是问题再次出现。我也尝试过声明不带类型参数的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 with custom object displays object address though custom cell factory is used

并尝试对其进行调试,我意识到问题不在于组件的呈现,因为ComboBox的value属性在选择后从未更新。

2 个答案:

答案 0 :(得分:1)

您的equals()方法很奇怪。

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

让我们分解一下。第1部分:

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

如果此cod中的Tobranull,而另一个cod的{​​{1}}是 not {{1} },则此部分为Tobra

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

让我们看第二部分。

true

如果此||中的(this.cod != null && !this.cod.equals(other.cod)) 不是cod,而另一个Tobra的{​​{1}}是,则这部分是null

这又看起来相反。

您很可能需要cod整个表达式。另外,您可以使用Tobra,它会为您检查null。

最后,请确保您也覆盖true并返回不违反!合同的正确值。阅读Javadoc了解更多详细信息。

答案 1 :(得分:0)

我通过以下方法解决了更改equals方法的问题:

implementation

uses
  Fmx.Platform.Win,
  WinApi.Windows;

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
    nativeWindowHandle: HWND;
begin
    nativeWindowHandle := Fmx.Platform.Win.WindowHandleToPlatform(Handle).Wnd;
    // TODO: Check for error when SetWindowPos returns false
    SetWindowPos(nativeWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
end;

课程:永远不要相信自动生成的代码。