13 27 Add Change 2

At this stage the TextArea is too small because the details only take one line of information, and the deadline label and other text look squeezed. The right side has a white background, while the left side keeps a grey area. To balance the layout, we tell the VBox to give the TextArea as much space as possible by setting the vgrow hint to ALWAYS on the TextArea inside the VBox. The VBox keeps just enough room for the labels above and below, and gives all the remaining space to the TextArea.

White background on labels and VBox

Then we work on the background colors. On the first Label we add an inline style:

style="-fx-background-color: white;"

We copy that style to the second Label and also to the parent VBox so the whole right pane stays white, even when nothing is selected.

Auto-selecting the first item

It would be nicer if the first task was already selected when the application starts. In the initialize() method of the controller, we add at the bottom:

todoListView.getSelectionModel().selectFirst();

The first item appears highlighted on launch, but the details panel still does not update because the selection was changed programmatically and not by a mouse click. To fix that, we add a ChangeListener on the ListView's selection model inside initialize(), which reacts to every change of the selected item:

todoListView.getSelectionModel()
    .selectedItemProperty()
    .addListener((obs, oldValue, newValue) -> {
        if (newValue != null) {
            TodoItem item = todoListView
                .getSelectionModel().getSelectedItem();
            detailTextArea.setText(item.getDetails());
        }
    });

This is essentially a generic event handler that runs every time the selection changes — whether the user clicks, presses arrow keys or whether we change the selection from code. With this in place, the first task is selected automatically on launch and its details appear on the right.

That is all for this video. In the next one we will format the deadline nicely so the displayed date is more readable. See you soon.

Summary

This lesson covers building a JavaFX task list application with proper layout, styling, and event handling. It demonstrates how to use VBox/HBox containers for spacing, apply background styling to labels, select the first item by default using selectFirst(), and implement a ChangeListener to update task details when selection changes. The lesson combines UI layout, CSS-like styling in FXML, and event-driven programming patterns.

Key points

  • Use VBox and HBox with proper spacing to allocate space efficiently in the layout—give fixed space to labels and remaining space to the text details area
  • Apply background colors to UI elements in FXML using style attributes; define both the label background and the bounding box background color for consistency
  • Select the first item in a ListView by default using selectFirst() on the selection model to ensure initial data is displayed without user interaction
  • Implement ChangeListener event handlers to automatically update task details when the user selects a different item in the list
  • Wire event listeners in the controller by binding to the selection model change event, allowing real-time UI synchronization when selection changes

FAQ

How do I make a JavaFX ListView show details when I select an item?

Use a ChangeListener on the selection model: monitor when selectedItem changes, then update the text details area with the selected item's content. This keeps the UI synchronized without manual refresh.

Why aren't the details showing even though the first item is selected?

Check the FXML—if you only select the item programmatically without binding a listener to the change event, the detail view won't update. Add a ChangeListener to the selection model's selectedItemProperty() to trigger detail display on selection changes.

What's the best way to structure a task list UI layout in JavaFX?

Use nested VBox/HBox containers: a main HBox holds a ListView on the left and a details VBox on the right. Set VBox.setVgrow() to give the details area flexible height, and use setSpacing() to distribute space proportionally between components.