Reputation: 636
I build a little JavaFX TableView for displaying data. The user should be able to edit the data in the tableview. The problem is: only specific values are allowed in certain fields. If the user entered a wrong value, the field is set to 0.
Here is my Class:
private ObservableList shots;
@FXML
void initialize() {
this.shots = FXCollections.observableArrayList(match.getShots()); // values from database
tblShots.setItems(shots);
tblShots.setEditable(true);
lblserienid.setText(GUIConstants.idPlaceHolder);
lblresult.setText(GUIConstants.idPlaceHolder);
colShotID.setCellValueFactory(new PropertyValueFactory<Schuss, String>("idSchuss"));
colRing.setCellValueFactory(new PropertyValueFactory<Schuss, String>("ringString"));
colRing.setCellFactory(TextFieldTableCell.forTableColumn());
colRing.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Schuss, String>>() {
@Override
public void handle(TableColumn.CellEditEvent<Schuss, String> t) {
Schuss s = (Schuss) t.getTableView().getItems().get(
t.getTablePosition().getRow());
try {
int ring = Integer.parseInt(t.getNewValue());
s.setRing(ring);
} catch (Exception ex) {
s.setRing(0);
}
SerienauswertungViewController.this.refreshTable();
}
});
colRing.setEditable(true);
// .... omitted
}
private void refreshTable(){
if(shots.size()>0) {
btnDeleteAll.setDisable(false);
btnEdit.setDisable(false);
int res = 0;
for(int i=0;i<shots.size();i++){
Schuss s = (Schuss)shots.get(i);
res += s.getRing();
}
lblresult.setText(""+res);
}
else {
btnDeleteAll.setDisable(true);
btnEdit.setDisable(true);
lblresult.setText(GUIConstants.idPlaceHolder);
}
}
So when I edit a tableviewcell and enter "q" (this value is not allowed) and press enter, the debugger jumps in the above catch block, sets the specific value in the observablelist to 0 (I can see this in the debugger, when I expand this object) but the tableviewcell still displays q instead of 0 (which has been corrected by the system)...
Why does the tableview not show the right values of the observablelist-Object???
Upvotes: 3
Views: 3284
Reputation: 153
Since JavaFX 8u60 you can use(assuming tableView is an instance of TableView class):
tableView.refresh();
It worked for me
Upvotes: 0
Reputation: 11
Though the refresh()
definitely works in conjunction with an upgrade to 8u60
, the large project on which I work is currently stuck on 8u51
and cannot reasonably move to u60
any time soon. I tried to implement the code in the refresh()
that Rainer referenced in place of the other kluges mentioned above, specifically setting the column invisible/visible. However, simply implementing
getProperties().put(TableViewSkinBase.RECREATE, Boolean.TRUE);
did not work within u51
. Upon doing more googling, I came across the JavaFx/Oracle Jira issue here:
https://bugs.openjdk.java.net/browse/JDK-8098085
If you open the rt22599.patch
attachment you will find changes to various skins, specifically for TableViews
, the TableViewSkinBase
. This module is not delivered in the src-javafx.zip
that comes with the jdk install. Looking for info on how to possibly incorporate the SkinBase
change to a u51
install.
Upvotes: 1
Reputation: 793
This was required but brandnew since Java8u60 (yes - they changed API in an udpate!?!) there is a refresh() method on the TableView itself.
/**
* Calling {@code refresh()} forces the TableView control to recreate and
* repopulate the cells necessary to populate the visual bounds of the control.
* In other words, this forces the TableView to update what it is showing to
* the user. This is useful in cases where the underlying data source has
* changed in a way that is not observed by the TableView itself.
*
* @since JavaFX 8u60
*/
public void refresh() {
getProperties().put(TableViewSkinBase.RECREATE, Boolean.TRUE);
}
It is so new, it´s not even in the official oracle docs... So I cannot provide a link.
cheers.
Upvotes: 4