Reputation: 1174
I have the following problem: I write my app using JavaFX. I use TableView. Users should use it to observe, add and remove data. I have ID field that should be unique. So when user finishes to edit it I have to check whether result is unique or not. And if it’s unique I have to dismiss changings. Or even better I have to check it at the moment when data is updated and if necessary skip update.
I have TableView with three columns
colID.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSID());
colCaption.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSCaption());
colType.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSType());
colID.setCellFactory(TextFieldTableCell.forTableColumn());
colCaption.setCellFactory(TextFieldTableCell.forTableColumn());
colType.setCellFactory(TextFieldTableCell.forTableColumn());
lstObservable = FXCollections.observableList(lstData, (CDataType param)->{
param.getSID().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
System.out.println("getSID().ChangeListener: Changed: " + observable + ")"+ observable.getClass() + ") [" + oldValue + " -> " + newValue + "]");
}
});
return new Observable[]{param.getSID(),
param.getSCaption(),
param.getSType()
};
});
tabView.setItems(lstObservable);
What is usual practice for this? I’m sure that this problem is not new, but I can not find solution.
UPD: I mean that I don't understand what event should I handle to dimiss user changings. I suppose that it must be ChangeListener but if I change back data item value I got infinite recursion.
Upvotes: 1
Views: 1213
Reputation: 4209
You can handle this in the edit commit - something like the following:
colID.setOnEditCommit(event -> {
String newValue = event.getNewValue();
if(checkUniqueness(newValue)){
event.getRowValue().setSID(newValue);
}else {
event.getRowValue().setSID(null);
}
//Weird FX Bug - on the second time through, the value was set, but the table
//column didn't repaint, showing the incorrect amount.
colID.setVisible(false);
colID.setVisible(true);
});
//Stream the backing collection for the table and look for the value that needs to be unique
public boolean checkUniqueness(String value) {
return backingCollection
.stream()
.noneMatch(item -> item.getSID().equals(value));
}
Upvotes: 1