JavaFX TableView

JavaFX TableView Tutorial and Examples.

TableView is a JavaFX control we can use to render tabular data. TableView is very powerful. It can allow us to visualize an unlimited number of rows of data, broken out into columns.

It’s in a way similar to ListView. Except for the fact that it can render 2D data. That is data in both rows and columns. Normally ListView only renders data in rows only, with a single column.

Hence this makes JavaFX TableView an integral part of JavaFX as a Framework.

This control resides in the javafx.scene.control package.

Features of JavaFX TableView

Here are some of the features of this powerful control:

  1. Powerful TableColumn API: Support for cell factories to easily customize cell contents in both rendering and editing states.
    Specification of minWidth/ prefWidth/ maxWidth, and also fixed width columns.
  2. Width resizing by the user at runtime.
  3. Column reordering by the user at runtime.
  4. Built-in support for column nesting
  5. Different resizing policies to dictate what happens when the user resizes columns.
  6. Support for multiple column sorting by clicking the column header (hold down Shift keyboard key whilst clicking on a header to sort by multiple columns).

Note that TableView is intended to be used to visualize data – it is not intended to be used for laying out your user interface. If you want to lay your user interface out in a grid-like fashion, consider the javafx.scene.layout.GridPane layout instead.

JavaFX TableView Examples

1. Simple JavaFX TableView Example

JavaFX TableView

JavaFX TableView


This will be our model class. It will represent a single Spaceship. Our Spaceship will have name, propellant as well as destination properties.


public class Spaceship { 

    private final SimpleStringProperty name;
    private final SimpleStringProperty destination;
    private final SimpleStringProperty propellant;

    public Spaceship(String name, String propellant, String destination) { = new SimpleStringProperty(name);
        this.destination = new SimpleStringProperty(destination);
        this.propellant = new SimpleStringProperty(propellant);

    public String getName() {
        return name.get();

    public void setName(String spaceshipName) {

    public String getDestination() {
        return destination.get();

    public void setDestination(String spaceshipDestination) {

    public String getPropellant() {
        return propellant.get();

    public void setPropellant(String spaceshipPropellant) {

This will be our main class. This class will derive or extend the Application class.

public class Main extends Application {..}

We will have two instance fields:

    private final ObservableList<Spaceship> data = FXCollections.observableArrayList(new Spaceship("Casini", "Laser Beam", "Jupiter"));
    final HBox hb = new HBox();

The first is an ObservableList and represents our data source. An ObservableList is a list that allows listeners to track changes when they occur.

So if we modify our observable list then listeners to it will be notified hence being able to update themselves.

The next is a HBox. A HBox is a layout that lays out its children in a single horizontal row. If the hbox has a border and/or padding set, then the contents will be layed out within those insets.

Then we override the start() method of the Application class. There first we instantita eour Scene, then set it’s width as well as height.

        Scene scene = new Scene(new Group());

Then we instantiate our TableView:

        TableView table = new TableView();

We’ve used an empty default constructor.
We now invoke the setEditable(), passing in true. This will set make our TableView to be editable at runtime.

Then there is what we call TableColumn. Normally a TableView is made up of a number of TableColumn instances. Each TableColumn in a table is responsible for displaying (and editing) the contents of that column.

We initialize create TableColumns:

        TableColumn nameTableColumn = createColumn("Spaceship Name", "name");
        TableColumn propellantTableColumn = createColumn("Propellant", "propellant");
        TableColumn destinationTableColumn = createColumn("Destination", "destination");

As you can see we’ve used the createColumn() method. This a custom method to create for us our TableColumns in JavaFX. Here’s it’s definition:

    private TableColumn createColumn(String columnHeader, String propertyValue) {
        TableColumn myTableColumn = new TableColumn(columnHeader);
        myTableColumn.setCellValueFactory(new PropertyValueFactory<>(propertyValue));
        return myTableColumn;

Then how do we set items or data to our tableview? Well we use the setItems() method of the TableView class. In this case our ObservableList is our data source:


Then we add our columns:

        table.getColumns().addAll(nameTableColumn, propellantTableColumn, destinationTableColumn);

Now we will be adding rows at runtime. When a button is clicked then we add rows to our JavaFX TableView. Here’s how we do it:

        final Button addButton = new Button("Add Spaceship");
        addButton.setOnAction((ActionEvent e) -> {
            data.add(new Spaceship("Enterprise", "Warp Drive", "Andromeda"));

Listed below is the full source code.

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.geometry.Insets; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.image.Image; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class Main extends Application {

    private final ObservableList<Spaceship> data = FXCollections.observableArrayList(new Spaceship("Casini", "Laser Beam", "Jupiter"));
    final HBox hb = new HBox();

    public void start(Stage stage) throws Exception{

        Scene scene = new Scene(new Group());

        TableView table = new TableView();

        TableColumn nameTableColumn = getNewColumn("Spaceship Name", "name");
        TableColumn propellantTableColumn = getNewColumn("Propellant", "propellant");
        TableColumn destinationTableColumn = getNewColumn("Destination", "destination");

        table.getColumns().addAll(nameTableColumn, propellantTableColumn, destinationTableColumn);

        final Button addButton = new Button("Add Spaceship");
        addButton.setOnAction((ActionEvent e) -> {
            data.add(new Spaceship("Enterprise", "Warp Drive", "Andromeda"));


        final VBox vbox = getNewVBox(10, 0, 0, 10);
        vbox.getChildren().addAll(table, hb);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);


        //stage.getIcons().add(new Image(getClass().getResourceAsStream("circle-icon.png")));

    private TableColumn getNewColumn(String columnHeader, String propertyValue) {
        TableColumn tc = new TableColumn(columnHeader);
        tc.setCellValueFactory(new PropertyValueFactory<>(propertyValue));
        return tc;

    private VBox getNewVBox(int top, int right, int bottom, int left) {
        VBox vbox = new VBox();
        vbox.setPadding(new Insets(top, right, bottom, left));
        return vbox;

    public static void main(String[] args) {

How to Run

  1. Copy the two files in the same folder.
  2. Open them in an IDE or Text Editor like Visual Studio Code.
  3. Then run.

Share an Example

Share an Example