TableView: display tables in JavaFX

If you were used to use JTable in Swing in order to display tables in your UI, you probably know that was kind of difficult to use and customise. In JavaFX you have what is called a TableView which is complex component allowing you to do a lot of stuff. In this post we will try to cover some basics about the TableView.

Main classes

In order to display tables in JavaFX you will use a TableView. The TableView will host TableColumns. That are the two main classes you will use in order to create a table. The TableRow class also exists but you won’t use it much, except if you want to create your own rowFactory. But that is a bit out of the scope of this post.

Bring up some Generics

A table is a container that will host some kind of data: a product, an account, an item, etc. So your TableView will host some kind of data. So the following declaration makes sense:

TableView<Property> propertiesTable = new ...

Columns will host a specific value of an item in the table, like the name of the product for example. And the name is a string. So declaring columns will be like this:

TableColumn<Property, String> nameColumn;
TableColumn<Property, String> valueColumn;

The power of properties

One of the great concept of JavaFX 2 is the properties and binding (read about here). And it is very useful in our case. Indeed we know what to display in our table, we have the data but I don’t want to say each time I need a new entry in my table that the name is in the first column, the value in the second, and so on. So let’s have a look. First of all I’m going to create a JavaBean with properties:

public class Property implements Serializable {
  public enum Type {

  private final StringProperty name = new SimpleStringProperty();
  private final StringProperty value = new SimpleStringProperty();
  private final ObjectProperty<Type> type = new SimpleObjectProperty<>();
  public Property() {
  public Property(String name, String value, Type type) {;
  public final StringProperty nameProperty() {
  public final String getName() {
    return this.nameProperty().get();
  public final void setName(String name) {
  public final StringProperty valueProperty() {
    return this.value;
  public final String getValue() {
    return this.valueProperty().get();
  public final void setValue(String value) {
  public final ObjectProperty<Type> typeProperty() {
    return this.type;
  public final Type getType() {
    return this.typeProperty().get();

  public final void setType(Type type) {

This quite simple. But now the real power will be revealed. We will create our table completely in FXML, without anything else. But you can of course create your table completely using pure Java code (just have a look on the Oracle website).

<BorderPane prefHeight="800" prefWidth="1000" fx:id="rootPane"
    <TableView fx:id="propertiesTable">
        <TableColumn text="Type" fx:id="typeColumn">
            <PropertyValueFactory property="type" />
        <TableColumn text="Name" fx:id="nameColumn">
            <PropertyValueFactory property="name" />
        <TableColumn text="Value" fx:id="valueColumn">
            <PropertyValueFactory property="value" />

And now take a look at the controller:

public class EnvViewerController implements Initializable {
  private Pane rootPane;
  private TableView<Property> propertiesTable;
  private TableColumn<Property, String> nameColumn;
  private TableColumn<Property, String> valueColumn;
  private TableColumn<Property, Type> typeColumn;
  public void initialize(URL url, ResourceBundle rb) {

As you can read, each TableColumn tag has a cellValueFactory one, which have a PropertyValueFactory. And this last one has an attribute named property. So what about everything? That simply means the column is bound to a property of the main content of the table. In other words, our table contains some Property objects (our JavaBean class) and the first column is bound to the type property, the second to the name one and the third to the value. Easy right? Here is a little screenshot:
Empty EnvViewer
Now we will modify our controller class in order to add some items to our table:

public void initialize(URL url, ResourceBundle rb) {
  for(Map.Entry entry : System.getProperties().entrySet()) {
    propertiesTable.getItems().add(new Property(entry.getKey().toString(), entry.getValue().toString(), Type.SYSTEM));
  for(Map.Entry entry : System.getenv().entrySet()) {
    propertiesTable.getItems().add(new Property(entry.getKey().toString(), entry.getValue().toString(), Type.ENVIRONMENT));

And this is what you get:
EnvViewer filled
And the TableView comes with nice features like having sortable columns by default, you can move columns, and so on. These features were long to develop in Swing so JavaFX brings some really nice feature natively.

Of course you can do a lot more with TableViews, like editing the data, respond to user’s clicks, dynamically add data, customise the look & feel and so on. Maybe I’ll blog about some other features.

The code is from a little app I’ve done and that I’ll update to provide new features. You can find it here.

PS: this blog post took me much more time to write than coding the app, just saying!


4 Responses to TableView: display tables in JavaFX

  1. Pingback: TableView: column’s width using percentage in JavaFX « System.out.println("Thierry WASYL : Java blog")

  2. Pingback: Java desktop links of the week, December 3 | Jonathan Giles

  3. how can i get data from mysql DB and put them into a TableView using javafx and scene builder 2 …please help :/

    • Thierry WASYL says:

      Retrieve the data, make sure to have a bean to represent a single line of your DB, and put them in the table.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: