0

From the eclipse help:

setCellValueFactory

The cell value factory needs to be set to specify how to populate all cells within a single TableColumn. A cell value factory is a Callback that provides a CellDataFeatures instance, and expects an ObservableValue to be returned. The returned ObservableValue instance will be observed internally to allow for immediate updates to the value to be reflected on screen.


CellDataFeatures

A support class used in TableColumn as a wrapper class to provide all necessary information for a particular Cell.


PropertyValueFactory

Creates a default PropertyValueFactory to extract the value from a given TableView row item reflectively, using the given property name.


Explained in my words:

myTableViewColumn.setCellValueFactory(new PropertyValueFactory<MyModelClass, String>("name"));

setCellValueFactory specifies how to populate all cells in the column myTableViewColumn. The data-type used here is a property. By using PropertyValueFactory we get the specified property by looking for the property named "name" (declared in MyModelClass private final SimpleStringProperty name = new SimpleStringProperty("");).

Did I understood the usage of setCellValueFactory and PropertyValueFactory?

Yaerox
  • 608
  • 2
  • 11
  • 27
  • 1
    The value passed to the `PropertyValueFactory` constructor has nothing to do with the name of the variable with the property: it is linked to the *method* names for accessing that property and its value. See the [documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/cell/PropertyValueFactory.html). – James_D Feb 28 '17 at 13:55
  • I don't get the second part of your answer, sry. If the value passed to the constructor has nothing to do with the name of my variable, then I expect I have to have a method called nameProperty, just like the documentation says: _In this example, the "firstName" string is used as a reference to an assumed firstNameProperty() method in the Person class type_ but I don't. Can you try to give me a hint on which special part of the documentation you're pointing for me? Thanks in advance. – Yaerox Feb 28 '17 at 14:52
  • That's what I meant. If the name of the variable is, say `fname ` but the method is `firstNameProperty`, you would need `new PropertyValueFactory("firstName")`, **not** `new PropertyValue("fname")`. – James_D Feb 28 '17 at 14:56
  • 1
    FWIW I strongly advise not using `PropertyValueFactory` at all, and just implementing the callback yourself, as in @ievinm's answer. – James_D Feb 28 '17 at 15:03
  • I stucked on the fact, that I don't have any method like `firstNameProperty`. But after following the documentation _If no method matching this pattern exists, there is fall-through support for attempting to call get() or is()_ I got this. My getter are called getFirstName and if I rename them then I'm getting the expected behaviour that this column doesn't show any values. Thank you sir! – Yaerox Feb 28 '17 at 15:20

2 Answers2

2

Yes that would be correct. Note as well that the data for the table needs to be set with something like the following:

ObservableList<MyModelClass> tableData= FXCollections.observableArrayList();
table.setItems(tableData);

Basically, this table has a list of MyModelClass objects. The cell factory is invoked to bind the desired field from the object to the cells in a given column.

setCellValueFactory can also be used with a lambda rather than a PropertyValueFactory, as seen below.

myTableViewColumn.setCellValueFactory(cellData -> cellData.getValue().name);

Both do the same thing, binding the values from the name field in the list of objects to that column.

ievinm
  • 53
  • 7
  • Is there any reason why I should use lambda rather then PropertyValueFactory or otherwise (like @James_D advises)? – Yaerox Feb 28 '17 at 15:38
  • 1
    Overall, if PropertyValueFactory is implemented correctly, with correctly named methods inside your MyModelClass, there's nothing _wrong_ with it, but it has its disadvantages; among them, it doesn't actually check if the right type is returned until at runtime. Using lambda, the compiler can check if the method exists, firstly, and if the right type is returned. [This link here goes into more detail about it.](http://stackoverflow.com/questions/38049734/java-setcellvaluefactory-lambda-vs-propertyvaluefactory-advantages-disadvant) – ievinm Feb 28 '17 at 19:51
1

I cannot tell if you understood how it's used; The description seems seems to be mostly correct, but there are some details you did not get correct:

  • A Callback itself does not provide a value. The cellValueFactory is a Callback that takes a CellDataFeatures instance as parameter of it's method and returns a ObservableValue; The value stored in the ObservableValue instance is used as item for the TableCell.
    Furthermore the value is only passed to the TableCell responsible for displaying the value. What this cell does with the new value is completely up to it's implementor. A change may or may not be visible on screen and a cell needs not be displayed on screen when the value is changed (It can be scrolled out of view using the TableView's scrollbar).

  • PropertyValueFactory does not look for the field. It looks for a nameProperty() method that is used to retrieve the ObservableValue.
    If there is no such method, it looks for a getter method: getName() or isName(). In the latter case an ObservableValue instance wrapping the value returned by the getter is used (; Note that this makes automatic updates impossible).

fabian
  • 80,457
  • 12
  • 86
  • 114
  • For me, your first point seems to be an easy understanding explaination of how this works together. – Yaerox Mar 01 '17 at 07:51