• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Can't Understand "setCellValueFactory"

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello everyone,

I need your help to understand the setCellValueFactory method for TableColumn<?, ?> class in JavaFx. I am a necomer to Java and would like understand what exactly this method does and the context in which it is to be used.

Please consider the following code snippet taken from: http://code.makery.ch/java/javafx-8-tutorial-part2/

/**
* Initializes the controller class. This method is automatically called
* after the fxml file has been loaded.
*/

@FXML
private void initialize() {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
}

I can understand that these methods will populate the cells of the firstnameColumn and lastNameColumn with the firstNameProperty and lastNameProperty correspondingly. However some important and few trivial things I don't understand:

Q1. There is no mention of the Person object (bean) from which the firstNameProperty is extracted in the code. How does the method know what is going to be passed to it? After all, "cellData" is just a dummy argument for the lambda expression to work.

Q2. After this method has run, how do we get the first person in the first row of the column, second person in the second row of the column and so on? I don't see any code that populates the corresponding entry based on the cell location.

Q3. Trivial question: What does the term "Factory" signify in the method name "setCellValueFactory". Does it indicate some type of Factory API or does it mean that this method is literally a factory of cell values?

Thank you so much for your time and effort,
Anand
 
Rancher
Posts: 387
30
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A1. cellData is not a dummy value, it is a CellDataFeatures object which is used to "provide all necessary information for a particular Cell". Iin your sample, it is providing the value of the row object (a person object), from which the cell value factory can be invoked to extract the field value from the object so that it can utilized by the associated cell.

A2. Your table has an associated list of items which have been added to that. It is these items which are displayed, by default based on the order of the items added to the list. JavaFX 8 also adds features for sorting and filtering the items.

A3. Yes, this method is literally a factory of cell values.
 
Anand Paralkar
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello John,

Thank you for replying. (I was beginning to get worried that no one had noticed my post.)

Sorry, I realize that cellData is not a dummy value. What I meant is that it is a implicitly declared object. (There is no declaration/instantiating statement for this object.)

In this example the assignment of the "list" table to the "view" table happens here (personTable.setItems(mainApp.getPersonData());):

/**
* Is called by the main application to give a reference back to itself.
*
* @param mainApp
*/
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;

// Add observable list data to the table
personTable.setItems(mainApp.getPersonData());
}

So then, if I understand correctly, the firstNameColumn.setCellValueFactory is only used to extract the firstNameProperty for each cell.

What is amazing for me is that I don't see code which says "do this (extract the firstNameProperty) for cell location1, location2, ....", and yet, that is what happens! All at one go!

Thanks once again for your valuable time.

Regards,
Anand



 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Anand,

I am also new to JavaFX and I believe I was using the same tutorial you were using: http://code.makery.ch/. I am using Netbeans to go through the tutorial and after going through Part 2 of the tutorial, the first and last name of the persons should have populated when I open the preview of the application. But mine did not populate, and I have reviewed the code over and over again, and cannot seem to find out what the problem is... the only thing I could think of is what you pointed out: "there is no mention of the Person object (bean) from which the firstNameProperty is extracted in the code. How does the method know what is going to be passed to it? After all, "cellData" is just a dummy argument for the lambda expression to work."

I read the reply to your post, and that did not give me the insight as to how the initialize method knows to look in the Person class, and then look in the MainApp class to find the values to populate the column of the tables with. If you were able to get your code to work can you please advice what you did. Also if you have gotten any clearer with how the code knows to look in the Person object without any explicit reference to that, can you please provide a description.

Thank you for you!
 
Anand Paralkar
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Paul,

Well, to be honest, I am not too fluent with this thing myself, but here's the way I understand this thing. The table operates on a list of objects and must populate itself based on the list. Since the table has columns as its members/children, the responsibility of populating values passes on to the columns. Then,

firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());

does the trick. This statement sets the rule for the "firstNameColumn" column. In non-Javaese:

Each cell within the column has a cellData object. This is a given for any column in JavaFX. The object (Person object) in the list pops out after the cellData.getValue() method. Next, the rule says to query each Person object in the list that was originally passed to the table (parent of the column) with the method in the (Person) object called "firstNameProperty". Notice this method in the Person object returns a StringProperty. JavaFX columns have cells, which when given a StringProperty, automatically show the value (string) of the StringProperty.

This rule (firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());) is what causes the automatic mechanism and the ensuing awe of "how does this work!".

In your case, you must review your code. The tutorial worked correctly for me when did a "copy-paste" from the website. I have successfully adapted that code many times over in my project. I don't know if it is ok to post your code here for review, but you could try stackoverflow.com too for that. Worry not, this will work out.

I have risked giving you an explanation in layman's terms despite being a "greenhorn" myself - all in good faith. May the force consider that before awarding my punishment.

Regards,
Anand
 
John Damien Smith
Rancher
Posts: 387
30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@paulTt create a new question and post your code in it as an MCVE, http://stackoverflow.com/help/mcve

Then somebody can copy and paste your code, compile it, fix it and tell you what you are doing wrong.
 
paulTt johnTt
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Anand,

Thank you for your reply. After looking at the parameters which make up the setCellValueFactory object, I think things sort of make more sense to me. From what I see this code:

private TableColumn<Person, String> firstNameColumn;

already gives the reference to the person class, and like you said since a column was referred here, then the code which follows in the initialize method just continues the assignment of first and last names to each cell of that column.

Thanks again for your response, it was really helpful to me.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic