# Como acessar o banco fora da paint thread

> Rodar consultas SQLite em uma thread de trabalho e voltar à UI com Component.onUI.

Source: https://crossfly.dev/pt/docs/cookbook/data/banco-fora-da-paint-thread — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Como acessar o banco fora da paint thread

**Propósito.** Consultas pesadas (varreduras, bulk, migrações) travam a UI se rodarem na paint thread única do CrossFly. A regra é: **faça o I/O do banco numa thread de trabalho** e **atualize a UI apenas via `Component.onUI(...)`**, que reencaminha o código para a thread de UI.

## APIs usadas
- `new Thread(Runnable).start()` — cria uma thread de trabalho para o acesso ao banco. Todo o `SqliteDb`/`query`/`bulkInsert` roda aqui, longe da paint thread.
- `Component.onUI(Runnable r)` — enfileira `r` para rodar na **thread de UI** (internamente `Gdx.app.postRunnable`). **Toda** manipulação de componentes (setar texto, adicionar itens à lista, `repaint`) deve acontecer dentro deste callback.
- `SqliteDb` / `SqliteCursor` — abertos e **fechados dentro da própria thread** (via `try-with-resources`). Não compartilhe uma conexão entre threads; abra a sua onde vai usar.

> **Regra de ouro do threading.** Ler/escrever no banco: thread de trabalho. Tocar em componentes de UI: `Component.onUI`. Nunca o contrário — acessar componentes fora da thread de UI causa corrupção; bloquear a paint thread com I/O trava o app.

> **Coletar antes de sair da thread.** O `SqliteCursor` é `AutoCloseable` e ligado à sua conexão. **Não** passe o cursor para dentro do `onUI`. Materialize os dados (ex.: numa `List`) na thread de trabalho e passe só a lista pronta para a UI.

## Exemplo completo (copiar, colar e rodar)

```java
package com.exemplo;

import java.util.*;                          // List, ArrayList

import dev.crossfly.ui.*;                     // Window, Component
import dev.crossfly.ui.layout.*;             // VerticalLayout
import dev.crossfly.sqlite.*;                // SqliteDb, SqliteCursor

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      new Thread(() ->
      {
         // --- thread de trabalho: I/O do banco ---
         List<String> nomes = new ArrayList<>();
         try (SqliteDb db = SqliteDb.open("app.db");
              SqliteCursor c = db.query("SELECT name FROM person ORDER BY name"))
         {
            while (c.next())
               nomes.add(c.getString(0));   // coleta ANTES de sair da thread
         }

         // --- volta para a UI apenas para atualizar componentes ---
         Component.onUI(() ->
         {
            // aqui é seguro tocar em componentes (setar lista, repaint, etc.)
            preencheLista(nomes);
         });
      }).start();
   }

   /** Stub: atualize aqui seus componentes de UI com os dados carregados. */
   private void preencheLista(List<String> nomes)
   {
      // ex.: montar itens numa lista, setar textos, repaint()...
   }
}
```

> O trecho abaixo mostra **só o miolo**. Para rodar, coloque-o no esqueleto `MainWindow` acima.

## Trecho mínimo
```java
// verificado na fonte: Component.onUI (Gdx.app.postRunnable), SqliteDb.query/cursor 0-based
import dev.crossfly.sqlite.*;
import dev.crossfly.ui.Component;
import java.util.*;

new Thread(() ->
{
   // --- thread de trabalho: I/O do banco ---
   List<String> nomes = new ArrayList<>();
   try (SqliteDb db = SqliteDb.open("app.db");
        SqliteCursor c = db.query("SELECT name FROM person ORDER BY name"))
   {
      while (c.next())
         nomes.add(c.getString(0));   // coleta ANTES de sair da thread
   }

   // --- volta para a UI apenas para atualizar componentes ---
   Component.onUI(() ->
   {
      // aqui é seguro tocar em componentes (setar lista, repaint, etc.)
      preencheLista(nomes);
   });
}).start();
```

## Aprofunde-se
- [Trabalho em background](/docs/data-and-services/background-work) · [Tratamento de erros e logging](/docs/best-practices/seguranca)
- Receitas irmãs: [CRUD parametrizado](/docs/cookbook/data/crud) · [Transação e escrita em massa](/docs/cookbook/data/transacao-e-bulk)
