JavaFX: Bind the textProperty from a Label to the size of an ObservableList


I am new to FX, not so new to Java, so please bear with me! What I have is a simple application using a JavaFX TableView backed by an ObservableList.

When I first launch the application I spawn another Thread (from the start method of Application) to listen to changes to a log file and add another element to the ObservableList so that the row is immediately visable in the TableView. I thought it would be beneficial to have a Label in the window that contains the current size of the ObservableList. I am attempting to bind the textProperty of the Label to the size of the ObservableList. My first attempt yielded:


But I believe I am misunderstanding the Bindings API. I realize that ObservableList.size() returns a regular int instead of an ObservableValue which is necessary for it to even work, but I thought the Bindings class had a static method to create one for me.

The back-end model contains the list as a static variable (I left out the listen-for-changes part):

public class LogFileListener implements Runnable {

private static final ObservableList<SNMPTrap> model = FXCollections.observableArrayList();

public void run() {
    String line = null;
    try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileLocation)))) {
        while ((line = br.readLine()) != null) {
    } catch (Exception ex) {


public static ObservableList<SNMPTrap> getModel() {
    return model;


The Application Class:

public class TableDisplay extends Application {

public void start(Stage stage) throws Exception {

    new Thread(new LogFileListener()).start();

    Parent root = FXMLLoader.load(getClass().getResource("path/to/FXML"));

    Scene scene = new Scene(root);


The Controller Class:

public class TableDisplayController implements Initializable {

private TableView<SNMPTrap> tableView;
private Label tableSizeLabel;

public void initialize(URL url, ResourceBundle rb) {




Is this even possible in FX? Do I need to add a change listener to the entire ObservableList instead and only then update the Label with getSize()?

Thanks in advance!

11/11/2013 11:24:15 PM

Accepted Answer

Your binding statement is correct for what you want to achieve (binding text property of a Label to the size of an ObservableList).

Your code has concurrency issues. What will happen is the LogFileListener runs in its own thread, updates the list of items and the items are updated in the LogFileListener thread, triggering updates to the scene graph off of the JavaFX application thread. This is a "bad thing" as JavaFX uses a single GUI thread.

What you need to do is ensure that the binding trigger and table item updates only occur on the JavaFX application thread (and you might need to do so in an efficient way such that you don't overload the JavaFX event processor with too many little update calls).

A simple fix for your current solution is to use the following code.

final SNMPTrap trap = parseTrap(line);
Platfrom.runLater(new Runnable() {
  @Override public void run() {

Your application might potentially benefit from a more sophisticated approach. You can search StackOverflow for related questions on Platform.runLater, Task, Service and JavaFX concurrency topics as well as review the Oracle documentation on concurrency in JavaFX and the Task javadoc to gain a better understanding of how all this stuff works and what your options are.

3/14/2016 10:24:25 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow