0

While i was searching for adding rows from DB to the table view in javaFX, i came across below code from the following code snippet.

Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>()

I cannot Understand what it does in this code. i understood that setCellValueFactory is for adding value for the cell but i cannot understand this series of code from callback

public class DBFXLesson1 extends Application {

private ObservableList<ObservableList> data;
private TableView tableview;

public static void main(String args[]) {

    Application.launch(args);

}

//CONNECTION DATABASE
public void buildData() {
    Connection conn;
    conn = new DBConnection().getConnection();
    data = FXCollections.observableArrayList();
    try {

        //SQL FOR SELECTING ALL OF CUSTOMER
        String SQL = "SELECT * from addrbk";
        //ResultSet
        ResultSet rs = conn.createStatement().executeQuery(SQL);

        /**
         * ********************************
         * TABLE COLUMN ADDED DYNAMICALLY * ********************************
         */
        for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
            //We are using non property style for making dynamic table
            final int j = i;
            TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
            col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
                public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
                    return new SimpleStringProperty(param.getValue().get(j).toString());
                }
            });

            tableview.getColumns().addAll(col);
            System.out.println("Column [" + i + "] ");
        }

        /**
         * ******************************
         * Data added to ObservableList * ******************************
         */
        while (rs.next()) {
            //Iterate Row
            ObservableList<String> row = FXCollections.observableArrayList();
            for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                //Iterate Column
                row.add(rs.getString(i));
            }
            System.out.println("Row [1] added " + row);
            data.add(row);

        }

        //FINALLY ADDED TO TableView
        tableview.setItems(data);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Error on Building Data");
    }
}

public void start(Stage stage) {

    //TableView
    tableview = new TableView();
    buildData();

    //Main Scene
    Scene scene = new Scene(tableview);

    stage.setScene(scene);
    stage.show();
}

}

My Question is

what is the purpose of this callback and the flow of the code.

When and Where the rows get inserted to the table View

2 Answers2

0

The for loop that contains that Callback is just configuring the columns: it's not adding any data. The Callback is a function which takes the data from a specific row (in the form of an ObservableList in this example) and returns the value from that row in the column being configured: so in this example for column j is calls get(j) on the ObservableList (row data), calls toString() on the result, and wraps it in a SimpleStringProperty.

The second loop (the while loop) actually populates the table with data. It does this (in this example) by creating an ObservableList for each row and then adding each ObservableList to an ObservableList<ObservableList> *(i.e. list of lists) called data. Then at the end it calls tableView.setItems(data) to tell the TableView to use that as its data list.

This code is not that well-written: it uses lots of raw types and your compiler should be kicking out a whole load of warnings from it.

Typically, you would only use this structure if you had a highly dynamic situation (i.e. the database table had an unknown set of columns in it). Normally, when the database table schema is fixed, you would create a specific model object for each row (instead of using a general List) and define properties for it. This example uses this more common approach. Even if you have a dynamic case, I would strongly recommend not using raw types for the data structures.

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thank you so much james. i understood most of the part. I will get completely cleared if you explain how the callback gets the data from `obervablelist` using `cellDataFeatures` i dont have knowledge on what `cellDataFeatures` does here. im a newbie so kindly digest my faults.thanks.. – Boopathi T Aug 10 '15 at 13:53
  • [`CellDataFeatures`](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableColumn.CellDataFeatures.html) is just a wrapper for the data in a row, which also gives access to the column and the table the data belong to. So `getValue()` just gives a reference to the row data, which is a list in the example. – James_D Aug 10 '15 at 16:35
  • then what is a `param`? – Boopathi T Aug 11 '15 at 09:07
  • I don't really understand that question. `param` is just the variable name you chose to give to the `CellDataFeatures` passed to the `call(...)` method. – James_D Aug 11 '15 at 10:46
0

Put: return new SimpleStringProperty((String) param.getValue().get(j)); instead of return new SimpleStringProperty(param.getValue().get(j).toString());