Reputation: 695
I have a TableView with two columns. I've connected both columns to StringProperty objects. One column updates on changes to the underlying object but the other doesn't, even though I've set them up (as far as I can tell) in the same way.
Column 1 is always correct. Column 2 displays correct values on initial load only. Subsequent changes to the underlying StringProperties in column 2 are not refreshed. Even if I close the window and re-open it, the values are not refreshed. I have verified with a debugger that the underlying values are indeed changing.
Here is the relevant code:
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;
}
}
And the code that sets up the 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);
Subsequently, if I make changes to a UserVariable
's value
property, those changes are reflected in the TableView, but changes to the maxValue
property are not.
For debug purposes I also tried the following...
varValuesColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringValueProperty());
varMaxColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringValueProperty());
...which did make both columns update correctly, whereas...
varValuesColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringMaxValueProperty());
varMaxColumn.setCellValueFactory(cd -> cd.getValue().getValue().stringMaxValueProperty());
...resulted in NEITHER column updating correctly. To me this implies that there's probably nothing wrong with the way I've set up the TableView, but possibly I'm doing something wrong with the underlying StringProperty.
Upvotes: 0
Views: 348
Reputation: 695
I'd forgotten that I'd overridden equals()
and hashCode()
for my UserVariable<T>
class. And then when I later added the maxValue
property, I didn't incorporate it into the calculation of equals()
and hashCode()
. Oops. Therefore, the MapListener
that was attached to my Map wasn't able to distinguish a change in maxValue
, and so my TableView
wasn't refreshing on changes in maxValue
.
Lesson learned: If you are overriding equals()
and hashCode()
and you update/modify/add to your Class members, make sure you also modify equals()
and hashCode()
as necessary!
Upvotes: 1