经过几个小时的寻找答案,我终于放弃了。 我有一个带有以下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属性在选择后从未更新。
答案 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
中的Tobra
是null
,而另一个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;
课程:永远不要相信自动生成的代码。