JavaFX TableView Tutorial with Examples
1. TableView
JavaFX gives out TableView class which is used together with TableColumn and TableCell in order to help you to display the data under tabular form.
2. Add column to the TableView
The following example creates a TableView with columns. A columns can contain sub-columns.
TableViewDemo.java
package org.o7planning.javafx.tableview;
import org.o7planning.javafx.model.UserAccount;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TableViewDemo extends Application {
@Override
public void start(Stage stage) {
TableView<UserAccount> table = new TableView<UserAccount>();
// Create column UserName (Data type of String).
TableColumn<UserAccount, String> userNameCol //
= new TableColumn<UserAccount, String>("User Name");
// Create column Email (Data type of String).
TableColumn<UserAccount, String> emailCol//
= new TableColumn<UserAccount, String>("Email");
// Create column FullName (Data type of String).
TableColumn<UserAccount, String> fullNameCol//
= new TableColumn<UserAccount, String>("Full Name");
// Create 2 sub column for FullName.
TableColumn<UserAccount, String> firstNameCol //
= new TableColumn<UserAccount, String>("First Name");
TableColumn<UserAccount, String> lastNameCol //
= new TableColumn<UserAccount, String>("Last Name");
// Add sub columns to the FullName
fullNameCol.getColumns().addAll(firstNameCol, lastNameCol);
// Active Column
TableColumn<UserAccount, Boolean> activeCol//
= new TableColumn<UserAccount, Boolean>("Active");
table.getColumns().addAll(userNameCol, emailCol, fullNameCol, activeCol);
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(table);
stage.setTitle("TableView (o7planning.org)");
Scene scene = new Scene(root, 450, 300);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
UserAccount.java
package org.o7planning.javafx.model;
public class UserAccount {
private Long id;
private String userName;
private String email;
private String firstName;
private String lastName;
private boolean active;
public UserAccount(Long id, String userName, String email, //
String firstName, String lastName, boolean active) {
this.id = id;
this.userName = userName;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
this.active = active;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
Running the example:
3. TableView with data
The following example illustrates a TableView with data. You can set up columns which can be sorted or not.
TableViewDemo2.java
package org.o7planning.javafx.tableview;
import org.o7planning.javafx.model.UserAccount;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TableViewDemo2 extends Application {
@Override
public void start(Stage stage) {
TableView<UserAccount> table = new TableView<UserAccount>();
// Create column UserName (Data type of String).
TableColumn<UserAccount, String> userNameCol //
= new TableColumn<UserAccount, String>("User Name");
// Create column Email (Data type of String).
TableColumn<UserAccount, String> emailCol//
= new TableColumn<UserAccount, String>("Email");
// Create column FullName (Data type of String).
TableColumn<UserAccount, String> fullNameCol//
= new TableColumn<UserAccount, String>("Full Name");
// Create 2 sub column for FullName.
TableColumn<UserAccount, String> firstNameCol//
= new TableColumn<UserAccount, String>("First Name");
TableColumn<UserAccount, String> lastNameCol //
= new TableColumn<UserAccount, String>("Last Name");
// Add sub columns to the FullName
fullNameCol.getColumns().addAll(firstNameCol, lastNameCol);
// Active Column
TableColumn<UserAccount, Boolean> activeCol//
= new TableColumn<UserAccount, Boolean>("Active");
// Defines how to fill data for each cell.
// Get value from property of UserAccount. .
userNameCol.setCellValueFactory(new PropertyValueFactory<>("userName"));
emailCol.setCellValueFactory(new PropertyValueFactory<>("email"));
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
activeCol.setCellValueFactory(new PropertyValueFactory<>("active"));
// Set Sort type for userName column
userNameCol.setSortType(TableColumn.SortType.DESCENDING);
lastNameCol.setSortable(false);
// Display row data
ObservableList<UserAccount> list = getUserList();
table.setItems(list);
table.getColumns().addAll(userNameCol, emailCol, fullNameCol, activeCol);
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(table);
stage.setTitle("TableView (o7planning.org)");
Scene scene = new Scene(root, 450, 300);
stage.setScene(scene);
stage.show();
}
private ObservableList<UserAccount> getUserList() {
UserAccount user1 = new UserAccount(1L, "smith", "smith@gmail.com", //
"Susan", "Smith", true);
UserAccount user2 = new UserAccount(2L, "mcneil", "mcneil@gmail.com", //
"Anne", "McNeil", true);
UserAccount user3 = new UserAccount(3L, "white", "white@gmail.com", //
"Kenvin", "White", false);
ObservableList<UserAccount> list = FXCollections.observableArrayList(user1, user2, user3);
return list;
}
public static void main(String[] args) {
launch(args);
}
}
Running the example:
4. Edit data on the Table
You can edit directly on the TableView, data will be updated to Model. The following image illustrates an editable TableView.
setCellFactory & setCellValueFactory
You need give out the way to display data in a cell via tableColumn.setCellValueFactory method. And the definition of a component (and the data of this component) will be displayed when the cell is editing using tableColumn.setCellFactory method.
onCellEditComit
Next, you need to define how new data will be updated to Model using tableColumn.setOnEditCommit method. After editing on the cell of table, the new data will be updated to Model.
With the cells show CheckBox in TableView:Note that the CheckBoxTableCell renders the CheckBox 'live', meaning that the CheckBox is always interactive and can be directly toggled by the user. This means that it is not necessary that the cell enter its editing state (usually by the user double-clicking on the cell). A side-effect of this is that the usual editing callbacks (such as on edit commit) will not be called. If you want to be notified of changes, it is recommended to directly observe the boolean properties that are manipulated by the CheckBox.
Example:
TableViewEditDemo.java
package org.o7planning.javafx.tableview;
import org.o7planning.javafx.model.Gender;
import org.o7planning.javafx.model.Person;
import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableViewEditDemo extends Application {
@Override
public void start(Stage stage) {
TableView<Person> table = new TableView<Person>();
// Editable
table.setEditable(true);
TableColumn<Person, String> fullNameCol //
= new TableColumn<Person, String>("Full Name");
TableColumn<Person, Gender> genderCol//
= new TableColumn<Person, Gender>("Gender");
TableColumn<Person, Boolean> singleCol//
= new TableColumn<Person, Boolean>("Single?");
// ==== FULL NAME (TEXT FIELD) ===
fullNameCol.setCellValueFactory(new PropertyValueFactory<>("fullName"));
fullNameCol.setCellFactory(TextFieldTableCell.<Person> forTableColumn());
fullNameCol.setMinWidth(200);
// On Cell edit commit (for FullName column)
fullNameCol.setOnEditCommit((CellEditEvent<Person, String> event) -> {
TablePosition<Person, String> pos = event.getTablePosition();
String newFullName = event.getNewValue();
int row = pos.getRow();
Person person = event.getTableView().getItems().get(row);
person.setFullName(newFullName);
});
// ==== GENDER (COMBO BOX) ===
ObservableList<Gender> genderList = FXCollections.observableArrayList(//
Gender.values());
genderCol.setCellValueFactory(new Callback<CellDataFeatures<Person, Gender>, ObservableValue<Gender>>() {
@Override
public ObservableValue<Gender> call(CellDataFeatures<Person, Gender> param) {
Person person = param.getValue();
// F,M
String genderCode = person.getGender();
Gender gender = Gender.getByCode(genderCode);
return new SimpleObjectProperty<Gender>(gender);
}
});
genderCol.setCellFactory(ComboBoxTableCell.forTableColumn(genderList));
genderCol.setOnEditCommit((CellEditEvent<Person, Gender> event) -> {
TablePosition<Person, Gender> pos = event.getTablePosition();
Gender newGender = event.getNewValue();
int row = pos.getRow();
Person person = event.getTableView().getItems().get(row);
person.setGender(newGender.getCode());
});
genderCol.setMinWidth(120);
// ==== SINGLE? (CHECH BOX) ===
singleCol.setCellValueFactory(new Callback<CellDataFeatures<Person, Boolean>, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(CellDataFeatures<Person, Boolean> param) {
Person person = param.getValue();
SimpleBooleanProperty booleanProp = new SimpleBooleanProperty(person.isSingle());
// Note: singleCol.setOnEditCommit(): Not work for
// CheckBoxTableCell.
// When "Single?" column change.
booleanProp.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
person.setSingle(newValue);
}
});
return booleanProp;
}
});
singleCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, //
TableCell<Person, Boolean>>() {
@Override
public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> p) {
CheckBoxTableCell<Person, Boolean> cell = new CheckBoxTableCell<Person, Boolean>();
cell.setAlignment(Pos.CENTER);
return cell;
}
});
ObservableList<Person> list = getPersonList();
table.setItems(list);
table.getColumns().addAll(fullNameCol, genderCol, singleCol);
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(table);
stage.setTitle("TableView (o7planning.org)");
Scene scene = new Scene(root, 450, 300);
stage.setScene(scene);
stage.show();
}
private ObservableList<Person> getPersonList() {
Person person1 = new Person("Susan Smith", Gender.FEMALE.getCode(), true);
Person person2 = new Person("Anne McNeil", Gender.FEMALE.getCode(), true);
Person person3 = new Person("Kenvin White", Gender.MALE.getCode(), false);
ObservableList<Person> list = FXCollections.observableArrayList(person1, person2, person3);
return list;
}
public static void main(String[] args) {
launch(args);
}
}
Gender.java
package org.o7planning.javafx.model;
public enum Gender {
FEMALE("F", "Famale"), MALE("M", "Male");
private String code;
private String text;
private Gender(String code, String text) {
this.code = code;
this.text = text;
}
public String getCode() {
return code;
}
public String getText() {
return text;
}
public static Gender getByCode(String genderCode) {
for (Gender g : Gender.values()) {
if (g.code.equals(genderCode)) {
return g;
}
}
return null;
}
@Override
public String toString() {
return this.text;
}
}
Person.java
package org.o7planning.javafx.model;
public class Person {
private String fullName;
private String gender;
private boolean single;
public Person(String fullName, String gender, boolean single) {
this.fullName = fullName;
this.gender = gender;
this.single = single;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public boolean isSingle() {
return single;
}
public void setSingle(boolean single) {
this.single = single;
}
}
JavaFX Tutorials
- Open a new Window in JavaFX
- JavaFX ChoiceDialog Tutorial with Examples
- JavaFX Alert Dialogs Tutorial with Examples
- JavaFX TextInputDialog Tutorial with Examples
- Install e(fx)clipse for Eclipse (JavaFX Tooling)
- Install JavaFX Scene Builder for Eclipse
- JavaFX Tutorial for Beginners - Hello JavaFX
- JavaFX FlowPane Layout Tutorial with Examples
- JavaFX TilePane Layout Tutorial with Examples
- JavaFX HBox, VBox Layout Tutorial with Examples
- JavaFX BorderPane Layout Tutorial with Examples
- JavaFX AnchorPane Layout Tutorial with Examples
- JavaFX TitledPane Tutorial with Examples
- JavaFX Accordion Tutorial with Examples
- JavaFX ListView Tutorial with Examples
- JavaFX Group Tutorial with Examples
- JavaFX ComboBox Tutorial with Examples
- JavaFX Transformations Tutorial with Examples
- JavaFX Effects Tutorial with Examples
- JavaFX GridPane Layout Tutorial with Examples
- JavaFX StackPane Layout Tutorial with Examples
- JavaFX ScrollPane Tutorial with Examples
- JavaFX WebView and WebEngine Tutorial with Examples
- JavaFX HTMLEditor Tutorial with Examples
- JavaFX TableView Tutorial with Examples
- JavaFX TreeView Tutorial with Examples
- JavaFX TreeTableView Tutorial with Examples
- JavaFX Menu Tutorial with Examples
- JavaFX ContextMenu Tutorial with Examples
- JavaFX Image and ImageView Tutorial with Examples
- JavaFX Label Tutorial with Examples
- JavaFX Hyperlink Tutorial with Examples
- JavaFX Button Tutorial with Examples
- JavaFX ToggleButton Tutorial with Examples
- JavaFX RadioButton Tutorial with Examples
- JavaFX MenuButton and SplitMenuButton Tutorial with Examples
- JavaFX TextField Tutorial with Examples
- JavaFX PasswordField Tutorial with Examples
- JavaFX TextArea Tutorial with Examples
- JavaFX Slider Tutorial with Examples
- JavaFX Spinner Tutorial with Examples
- JavaFX ProgressBar and ProgressIndicator Tutorial with Examples
- JavaFX ChoiceBox Tutorial with Examples
- JavaFX Tooltip Tutorial with Examples
- JavaFX DatePicker Tutorial with Examples
- JavaFX ColorPicker Tutorial with Examples
- JavaFX FileChooser and DirectoryChooser Tutorial with Examples
- JavaFX PieChart Tutorial with Examples
- JavaFX AreaChart and StackedAreaChart Tutorial with Examples
- JavaFX BarChart and StackedBarChart Tutorial with Examples
- JavaFX Line Tutorial with Examples
- JavaFX Rectangle and Ellipse Tutorial with Examples
Show More