# Loading data

> I/O off the paint thread (Thread + onUI) and efficient large lists with VirtualListView.

Source: https://crossfly.dev/docs/learn/loading-data — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 8. Loading data

> **What you'll learn:** fetching data without freezing the UI and displaying large lists efficiently.
> **Prerequisites:** [Managing state](/docs/learn/managing-state).

## Complete example (copy, paste, and run)
Loads the data on a background `Thread`, comes back to the paint thread with `Component.onUI`, and displays it in a
virtualized list (`VirtualListView` + `DataAdapter`) that recycles views. Compiles as is.
```java
package com.exemplo;

import java.util.*;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

public class MainWindow extends Window
{
   private final List<Tarefa> tarefas = new ArrayList<>();
   private VirtualListView lista;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      lista = new VirtualListView(Relative.ofFont(3f), new DataAdapter()
      {
         public int getCount() { return tarefas.size(); }
         public Component createView() { return new Label(""); }               // creates once
         public void bindView(Component v, int i) { ((Label) v).setText(tarefas.get(i).titulo); }
      });
      add(LAY_FILL, lista);

      carregar();
   }

   private void carregar()
   {
      new Thread(() -> {
         var dados = listarDoRepositorio();          // heavy work, background thread
         Component.onUI(() -> {                       // back to the paint thread
            tarefas.clear();
            tarefas.addAll(dados);
            lista.notifyDataChanged();                // updates the virtualized list
         });
      }).start();
   }

   private List<Tarefa> listarDoRepositorio()        // simulates I/O
   {
      List<Tarefa> out = new ArrayList<>();
      for (int i = 1; i <= 500; i++) out.add(new Tarefa("Tarefa " + i));
      return out;
   }
}

class Tarefa
{
   final String titulo;
   Tarefa(String titulo) { this.titulo = titulo; }
}
```
> The snippets below show **only the core** (what goes inside `onShow()`). To run them, put them in the `MainWindow` skeleton above.

## Why I/O never happens on the paint thread
The UI runs on a single thread — any blocking on it **freezes the screen**. The mandatory pattern:
```java
new Thread(() -> {
   var dados = repo.listar();                          // heavy work, background thread
   Component.onUI(() -> {                               // back to the paint thread
      vm.tarefas = dados;
      lista.notifyDataChanged();                        // updates the virtualized list
   });
}).start();
```
To react to a UI event already in the background, use `onActionThread` (see
[Handling input](/docs/learn/handling-input)).

## Large lists: `VirtualListView` + `DataAdapter`
`VirtualListView` **recycles views** — it renders only what's visible. The adapter separates **creating** (once) from
**binding** (cheap, many times):
```java
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), new DataAdapter() {
   public int getCount() { return vm.tarefas.size(); }
   public Component createView() throws Exception { return new CardTarefa(); }
   public void bindView(Component v, int i) throws Exception { ((CardTarefa) v).bind(vm.tarefas.get(i)); }
});
add(LAY_FILL, lista);
// when the data changes:
lista.notifyDataChanged();
```
> `bindView` runs **a lot** during scroll — keep it cheap and idempotent (no I/O in there).

## What you build in this step
The list now **loads in the background** and **renders virtualized** (using the `CardTarefa` from
chapter 3).

## Recap
I/O in a `Thread` → `Component.onUI`; large lists with `VirtualListView` (recycling via
`createView`/`bindView`); `notifyDataChanged()` when the data changes.

## Next steps
→ [Persisting data](/docs/learn/persisting-data)

## See also
- [Performance and large lists](/docs/best-practices/performance-e-listas-grandes) · [Background work](/docs/data-and-services/background-work)
