Bene
Bene

Reputation: 636

Javafx TableView Edit Validation

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

Answers (4)

Zcon
Zcon

Reputation: 153

Since JavaFX 8u60 you can use(assuming tableView is an instance of TableView class):

tableView.refresh();

It worked for me

Upvotes: 0

Kurt Weaver
Kurt Weaver

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

Rainer
Rainer

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

Bene
Bene

Reputation: 636

Okey this seems to be a bug. I used a work around which is mentioned here:

tblShots.getColumns().get(1).setVisible(false);
tblShots.getColumns().get(1).setVisible(true);

Upvotes: 1

Related Questions