Friday, January 23, 2015

JavaFX ObservableList

Continuing my exploration of JavaFX, another very useful feature is its collections library.  In particular, it includes automatically observable versions of the List and Map interfaces from the Java Collections framework.  These can enable very convenient GUI updates.

For example, consider a program that allows a user to enter names into a list.  JavaFX allows us to store our data internally in an ObservableList; the GUI automatically updates whenever ObservableList changes.  Here's a screenshot of the program in action:

To create the interface in SceneBuilder:

  • Create a BorderPane as the root container.
  • Add an HBox to the top of the BorderPane.
    • Place a Button and a TextField in the HBox.
  • Add a ListView to the center of the BorderPane.
The following is the Controller class I wrote to implement the functionality:
package application;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;

public class Controller {
 @FXML
 private Button add;
 @FXML
 private TextField name;
 @FXML
 private ListView visibleList;
 
 private ObservableList names = 
                FXCollections.observableArrayList();
 
 @FXML
 private void initialize() {
  visibleList.setItems(names);
 }
 
 @FXML
 private void addName() {
  if (name.getText().length() > 0) {
   names.add(name.getText());
   name.setText("");
  }
 }
}

In SceneBuilder:

  • Set up the above class as the controller.
  • Bind the three controls to the corresponding variables.
  • Bind the actions for the Button and TextView to addName().
Some notes on the code:
  • The key step here is calling the setItems() method of the visibleList object.  This is what binds the ObservableList names to the GUI.  Once this method is called, any changes to names will automatically appear in the list.
  • Note that this call must be in the initialize() method.  The visibleList object is created after the constructor call, so we can't put this in the constructor.  JavaFX ensures that initialize() is called before any other GUI code runs.
  • By attaching addName() to both the Button and the TextView, the user can add a name either way.

No comments:

Post a Comment