How to set items for JavaFX TableView - object contains another object?


Question

i want to be short as possible without omitting useful information. I have the following class:

public class Address{
StringProperty city = new SimpleStringProperty();
StringProperty street = new SimpleStringProperty();

//following the constructor, getters and setters
...
}

I have another class Client, that one has an Address member

public class Client {

StringProperty name = new SimpleStringProperty();
StringProperty  id = new SimpleStringProperty();
ObjectProperty<Address> address = new SimpleObjectProperty<>();

//following the constructor, getters and setters
...
}

and a JavaFX interface with a controller that contains a TableView object that should output in 3 column the members of the Client class and the city member of Address class for the given object. My TableView and TableColumn definition are the following code

public class SettingsController {
TableColumn<Client, String> clientNameCol;
TableColumn<Client, String> clientEmailCol;
TableColumn<Client, String> clientCityCol;
private TableView<Client> clientSettingsTableView;
...
...
    clientNameCol = new TableColumn<>("Name");
    clientNameCol.setCellValueFactory(new PropertyValueFactory<Client, String>("name"));

    clientEmailCol = new TableColumn<>("email");
    clientEmailCol.setCellValueFactory(new PropertyValueFactory<Client, String>("email"));

    clientCityCol = new TableColumn<>("City");
    clientCityCol.setCellValueFactory(new PropertyValueFactory<Client, String>("city"));

    clientSettingsTableView.setItems(clientData);
    clientSettingsTableView.getColumns().clear();
    clientSettingsTableView.getColumns().addAll(clientNameCol, clientEmailCol, clientCityCol);

and of course there is an ObservableList clientData that contains an array of Client object. Everything works fine except the column that should output the city for each client. How should i define the column for the city (contained by an Address member) of Client object?

1
5
3/10/2013 7:15:53 PM

Accepted Answer

@invariant thanks for your help, I googled a little bit more and i ended up with the following solution:

clientCityCol = new TableColumn<>("City");
clientCityCol.setCellValueFactory(new PropertyValueFactory<Client, Address>("address"));
// ======== setting the cell factory for the city column  
clientCityCol.setCellFactory(new Callback<TableColumn<Client, Address>, TableCell<Client, Address>>(){

        @Override
        public TableCell<Client, Address> call(TableColumn<Client, Address> param) {

            TableCell<Client, Address> cityCell = new TableCell<Client, Address>(){

                @Override
                protected void updateItem(Address item, boolean empty) {
                    if (item != null) {
                        Label cityLabel = new Label(item.getCity());
                        setGraphic(cityLabel);
                    }
                }                    
            };               

            return cityCell;                
        }

    });

Address class has a getter getCity() which returns the city member as a String().

6
3/11/2013 7:31:35 PM

you forgot to mention that you have to change the definition of clientCityCol TableColumn<Client, String> clientCityCol; into TableColumn<Client, Address> clientCityCol; otherwise it won't work.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon