简体   繁体   中英

JavaFX, TableView, dynamic update Item after edit

I'm trying to modify JavaFX sample code for TableView to update item after edit with dynamic approach. The whole tutorial and sample code can be found here:
https://docs.oracle.com/javafx/2/ui_controls/table-view.htm

The update of Item is programed as handler:

firstNameCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
    @Override
    public void handle(CellEditEvent<Person, String> t) {
        ((Person) t.getTableView().getItems().get(
            t.getTablePosition().getRow())
            ).setFirstName(t.getNewValue()); 
    }
} );

I would like to use something dynamic instead of setFirstName() .
Is there other possibility beside of reflection?

I've manged to get the name of Property with:

String propertyName = ((PropertyValueFactory)t.getTableColumn().getCellValueFactory()).getProperty();

Can I set the value of firstName using propertyName somehow?
I know, it can be done with reflection but I would like to use features of properties.

Thank you, Annie

You can do

TableColumn<Person, String> col = t.getTableColumn();
int row = t.getTablePosition().getRow();
ObservableValue<String> ov = col.getCellObservableValue(row);
if (ov instanceof WritableValue) {
    ((WritableValue<String>)ov).setValue(t.getNewValue());
}

and you should be able to replace the specific types Person and String with type variables if you need.

Note that this is basically identical to the default edit commit handler defined on the TableColumn .

As an alternative, you can consider defining a utility method that creates TableColumn s, given a title and a property factory. I often use convenience methods like this (slightly adapted to include your use case):

private static <S,T> TableColumn<S,T> createColumn(String title, Function<S, Property<T>> property) {
    TableColumn<S,T> col = new TableColumn<>(title);
    col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
    col.setOnEditCommit(edit -> {
        S rowValue = edit.getRowValue();
        property.apply(rowValue).setValue(edit.getNewValue());
    });
    return col ;
}

Then you can do things like

TableView<Person> table = new TableView<>();
TableColumn<Person, String> firstNameColumn = createColumn("First Name", Person::firstNameProperty);

and the table column will have the onEditCommit already set.

I far prefer this general style to the PropertyValueFactory , which is not typesafe and prone to errors due to typos in the name, etc. It really should be considered legacy code since the release of Java 8, which allows the much more idiomatic approach to setting the cell value factory as above.

says My object are built with scene builder. but that it will function code defines the fields property in the beans class , which give the possibility of using them.

//@FXML 
@FXML
Label nom;
@FXML
Label prenom;
 @FXML
 private TableColumn<UtilisateurToDisplay, String> firstNameColumn;
@FXML
private TableColumn<UtilisateurToDisplay, String> lastNameColumn;
@FXML
private TableView<UtilisateurToDisplay> UserTable;
private final ObservableList<UtilisateurToDisplay> data_usr = FXCollections.observableArrayList();

public void initialize(URL location, ResourceBundle resources) {
// Initialize table with the two columns.
    firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
    lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());


    // Listen for selection changes and show the person details when changed.
    UserTable.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showUserDetails(newValue));
}
private void showUserDetails(UtilisateurToDisplay person) {
    if (person != null) {
        // Fill the labels with info from the person object.
        nom.setText(person.getNom_usr());
        prenom.setText(person.getPrenom_usr());

    } else {
        // Person is null, remove all the text.
        nom.setText("");
        prenom.setText("");

    }
}
}

you can see for more detail this address: http://code.makery.ch/library/javafx-8-tutorial/part3/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM