我有一个包含两列的TableView。我已经将这两列都连接到StringProperty对象。一列更新底层对象的更改,但另一列不更新,尽管我已经用同样的方式设置了它们(据我所知)。
第1列总是正确的。第2列仅在初始负载时显示正确的值。对第2列中基础StringProperties的后续更改不会刷新。即使我关闭窗口并重新打开它,值也不会刷新。我已经用调试器验证了底层值确实在变化。
以下是相关代码:
public class UserVariable<T>
{
private transient T value;
private transient T maxValue;
private StringProperty stringValue = new SimpleStringProperty();
private StringProperty stringMaxValue = new SimpleStringProperty();
public UserVariable(T value)
{
setValue(value);
}
public UserVariable(T value, T maxValue)
{
this(value);
setMaxValue(maxValue);
}
public final void setValue(T value)
{
this.value = value;
this.stringValue.set(this.value.toString());
}
public final void setMaxValue(T value)
{
this.maxValue = value;
this.stringMaxValue.set(this.maxValue.toString());
}
public StringProperty stringValueProperty()
{
return stringValue;
}
public StringProperty stringMaxValueProperty()
{
return stringMaxValue;
}
}
以及设置TableView:的代码
@FXML TableView<MapEntry<String, UserVariable<?>>> varsTable;
@FXML TableColumn<MapEntry<String, UserVariable<?>>, String> varValuesColumn, varMaxColumn;
varValuesColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringValueProperty());
varMaxColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringMaxValueProperty());
ObservableList<MapEntry<String, UserVariable<?>>> varEntries = FXCollections.observableArrayList();
// add data to varEntries
varsTable.setItems(varEntries);
随后,如果我对UserVariable
的value
属性进行更改,这些更改将反映在TableView中,但对maxValue
属性的更改则不会。
出于调试目的,我还尝试了以下。。。
varValuesColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringValueProperty());
varMaxColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringValueProperty());
这确实使两列都正确更新,而。。。
varValuesColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringMaxValueProperty());
varMaxColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringMaxValueProperty());
导致NEITHER列正确更新。对我来说,这意味着我设置TableView的方式可能没有什么问题,但可能我在底层StringProperty上做了一些错误的事情。
我忘了为UserVariable<T>
类重写了equals()
和hashCode()
。然后,当我后来添加maxValue
属性时,我没有将其纳入equals()
和hashCode()
的计算中。哎呀。因此,附在我的Map上的MapListener
无法区分maxValue
的变化,因此我的TableView
不会对maxValue
的变化进行刷新。
经验教训:如果要覆盖equals()
和hashCode()
,并且要更新/修改/添加类成员,请确保根据需要修改equals()
和hashCode()
!