I have a list of simple Person objects that I am using a TableView to display:
class Person {
private final StringProperty name = new SimpleStringProperty();
private final StringProperty emailAddress = new SimpleStringProperty();
private final StringProperty phoneNumber = new SimpleStringProperty();
public Person(String name, String emailAddress, String phoneNumber) {
this.name.set(name);
this.emailAddress.set(emailAddress);
this.phoneNumber.set(phoneNumber);
}
}
My goal in this example is to display both emailAddress and phoneNumber in the same TableColumn. This goes beyond simply concatenating the values as I am implementing a custom TableCell for this column (real-world application is more complex):
private TableCell<Person, Person> buildContactCell() {
return new TableCell<Person, Person>() {
final VBox root = new VBox();
final Label lblEmailAddress = new Label();
final Label lblPhoneNumber = new Label();
{
root.getChildren().addAll(lblEmailAddress, lblPhoneNumber);
}
@Override
protected void updateItem(Person person, boolean empty) {
super.updateItem(person, empty);
if (person != null && !empty) {
lblEmailAddress.setText(person.getEmailAddress());
lblPhoneNumber.setText(person.getPhoneNumber());
setGraphic(root);
} else {
setGraphic(null);
}
}
};
}
I am assuming this works fine, but I am unsure on how to configure the CellValueFactory for this TableColumn to accept the entire Person object.
Is there another way of setting up the TableCell to be able to access more than one property of Person? The other questions I've seen on implementing multiple properties only deal with concatenating, which is not what I am looking for.
Full Code:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TableCellSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
root.getChildren().add(getTableView());
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
private TableView<Person> getTableView() {
TableView<Person> tableView = new TableView<>();
TableColumn<Person, String> colName = new TableColumn<>("Name");
colName.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
TableColumn<Person, Person> colContact = new TableColumn<>("Contact");
colContact.setCellFactory(cell -> buildContactCell());
// **********************************************************************************************
// Need to set the CellValueFactory for colContact here
// **********************************************************************************************
tableView.getColumns().addAll(colName, colContact);
tableView.setItems(getSampleData());
return tableView;
}
private TableCell<Person, Person> buildContactCell() {
return new TableCell<Person, Person>() {
final VBox root = new VBox();
final Label lblEmailAddress = new Label();
final Label lblPhoneNumber = new Label();
{
root.getChildren().addAll(lblEmailAddress, lblPhoneNumber);
}
@Override
protected void updateItem(Person person, boolean empty) {
super.updateItem(person, empty);
if (person != null && !empty) {
lblEmailAddress.setText(person.getEmailAddress());
lblPhoneNumber.setText(person.getPhoneNumber());
setGraphic(root);
} else {
setGraphic(null);
}
}
};
}
private ObservableList<Person> getSampleData() {
ObservableList<Person> persons = FXCollections.observableArrayList();
persons.addAll(
new Person("Jack", "jack@outlook.com", "123-456-7890"),
new Person("Jenny", "goodtime@yahoo.com", "555-867-5309"),
new Person("Jesse", "mygirl@hotmail.com", "846-989-9988"));
return persons;
}
}
class Person {
private final StringProperty name = new SimpleStringProperty();
private final StringProperty emailAddress = new SimpleStringProperty();
private final StringProperty phoneNumber = new SimpleStringProperty();
public Person(String name, String emailAddress, String phoneNumber) {
this.name.set(name);
this.emailAddress.set(emailAddress);
this.phoneNumber.set(phoneNumber);
}
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public String getEmailAddress() {
return emailAddress.get();
}
public StringProperty emailAddressProperty() {
return emailAddress;
}
public String getPhoneNumber() {
return phoneNumber.get();
}
public StringProperty phoneNumberProperty() {
return phoneNumber;
}
}