A simple JavaFX 2.0 TableView example

I wanted to quickly show the current state of how a TableView may be built in JavaFX 2.0. I just copied the demo created by Adam Bien, and pasted it into my blog software, so apologies for typos. The approach shown here depends on the data that is backing the TableView being a Bean – if this is the case you can simply provide the relevant PropertyReference for that column and it’ll be populated as expected.

There are alternative approaches to this style that are also supported – Adam shows one such approach in his blog post. I am keen to hear what people out there think about the API that Adam and I have shown in our posts, and what else you would like to see.

The code below creates a TableView that is populated from an ObservableList. This means that should this collection ever be modified, the TableView will immediately be updated to reflect these changes. It even watches the provided properties of the Person objects, such that if the Person.FIRST_NAME or Person.LAST_NAME values change for any visible row, that cell will automatically be refreshed also.

Before I get to the code, I just want to add the normal, but very important disclaimer: this code is written using an API that isn’t public yet. By the time it is public, it may have changed drastically. Do not assume anything you see here will be in the final API. Also, this code sample is my own creation (and derived from Adam’s linked above) – it is not provided by Oracle and does not represent them.

[sourcecode language=’java’]
import javafx.application.Application;
import javafx.application.Launcher;
import javafx.collections.FXCollections;
import javafx.collections.Sequence;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.table.TableColumn;
import javafx.scene.control.table.TableView;
import javafx.scene.control.table.model.SequenceTableModel;
import javafx.stage.Stage;

public class Main extends Application {

@Override
public void start() {
Stage stage = new Stage();
stage.setTitle(“Hello Table”);

final Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);

Sequence children = root.getChildren();
children.add(getTableView());

stage.setVisible(true);
}

public TableView getTableView() {
ObservableList data = FXCollections.sequence(
new Person(“Duke”, “Java”),
new Person(“DukeFX”, “JavaFX”));

TableView tableView = new TableView();
tableView.setItems(data);

TableColumn firstNameCol = new TableColumn(“First”);
firstNameCol.setProperty(Person.FIRST_NAME);

TableColumn lastNameCol = new TableColumn(“Last”);
lastNameCol.setProperty(Person.LAST_NAME);

tableView.getColumns().addAll(firstNameCol, lastNameCol);

return tableView;
}

public static void main(String[] args) {
Launcher.launch(Main.class, args);
}
}

public class Person implements Bean {

private String firstName;
private String lastName;

public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

//with getters and other Bean functionality
}
[/sourcecode]

15 thoughts on “A simple JavaFX 2.0 TableView example”

  1. Where does the FIRST_NAME variable / constant come from?

    You say it’s a bean, so using PCE? Or are you binding using the JavaFX features?

    1. Tom,

      This is using the JavaFX APIs that are in the javafx.beans package. This has no relationship to previous beans APIs. I’m not sure what is provided with your EA builds, but that would be the first place to call regarding this new API.

      If there is nothing there, you know how to get in touch πŸ™‚

      — Jonathan

  2. We already talked about it but:

    tableView.getColumns().add(…)
    root.getChildren().add(…)

    is that a common streak through the api, no cover methods? Could say that’s even worse than Swing

    The column adding code looks a bit verbose to me: there’s no real need to actually hold the colum (titles should be read from a properties files anyway, or in the simplest case default to a beautified property name), so how about something like:

    tablView.addColumns(Person.FIRST_NAME, Person.LAST_NAME)

    Cheers
    Jeanette

    1. Agree on the getColumns call; getRootPane squared.
      But I suspect there will often be a need to override methods in the TableColumn class, so that suggestion problably wont work. A fluent API would be nice though;

      tableView.addColumns(
      new TableColumn(“First”).withProperty(FIRST_NAME),
      new TableColumn(“Second”).withProperty(LAST_NAME)
      );

      1. assume you mean set column properties (like name, width, binding..) instead of override?. If so, that would be a usefule reason for getColumns(), grab and configure

        fluent, sigh … not that big a friend of it – advantages not really outweighing the disvantages, IMO – but that’s an aside πŸ™‚

        If there would be one, I would reverse your suggestion, as the binding is what matters, everything else is decoration:

        tableView.addColumns(
        new TableColumn(FIRST_NAME).withName(“First”),
        new TableColumn(LAST_NAME).withName(“Last”)
        );

        CU
        Jeanette

        1. We’re getting close to my Swing BeanTableModel πŸ˜‰ The most common use case would be to set a property and a title (columns without titles are very uncommon), so:

          tableView.addColumns(
          new TableColumn(FIRST_NAME, β€œFirst”),
          new TableColumn(LAST_NAME, β€œLast”)
          );

          1. @Tom

            I was considering this very constructor as I wrote my blog post. At present I support just the TableColumn(String text) constructor, but also considered adding TableColumn(String text, PropertyReference property) constructor also.

            The question for me is just how frequently people will build TableColumns with a PropertyReference, versus any of the other approaches.

            Anywho, I am seriously considering adding this API, so then you can write precisely what you show above.

    2. @Jeanette
      Like I’ve said before, at present we use the get*() method and then add() to that. That is our consistent approach throughout the API.

      Whether we add API in the future to support the short-cuts is unclear at this point. But, it’s always easier to add API later than to rush it in and regret it being added in a hurry.

  3. By default, when you add a component (in swing) or a node, it will be visible.

    But we have to write stage.setVisible(true). In my opinion, it would be better if the visibility of stage is set to true by default.

    Sorry for my english, I hope I’m clear πŸ™‚

  4. Hello,

    I’m really confused of this line:
    FXCollections.sequence(
    new Person(“Duke”, “Java”),
    new Person(“DukeFX”, “JavaFX”));

    I think FXCollection is trying to keep all the elements having Person Bean. What does the FxCollections. means? Or is this like a ArrayList? can’t figure out!

    1. Judging from the variable it is assigned to, it is a factory method to create an observable list.

    2. @Narayan
      That line is basically just using the FXCollections API within JavaFX 2.0 to create a sequence collection. FXCollections provides a number of useful methods, and is the primary way our new collections should be created.

  5. Hi, what is the ambition for the grid? is the goal to match devexpress products in terms of power, ease of use and functionality?

Comments are closed.