Tuesday, February 27, 2018
JavaFX ObservableList
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. Heres 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 theBorderPane
. - Place a
Button
and aTextField
in theHBox
. - Add a
ListView
to the center of theBorderPane
.
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 ListViewvisibleList;
private ObservableListnames =
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
andTextView
toaddName()
.
Some notes on the code:
- The key step here is calling the
setItems()
method of thevisibleList
object. This is what binds theObservableList
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. ThevisibleList
object is created after the constructor call, so we cant put this in the constructor. JavaFX ensures thatinitialize()
is called before any other GUI code runs. - By attaching
addName()
to both theButton
and theTextView
, the user can add a name either way.