# Cómo mostrar un popup de selección modal

> Abrir una lista como ventana modal centrada con filas personalizadas mediante ItemFactory.

Source: https://crossfly.dev/es/docs/cookbook/lists/popup-de-selecao — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Cómo mostrar un popup de selección modal

**Propósito.** Abrir una lista de selección como **ventana flotante** (no incrustada en el layout).
`ListViewWindow` envuelve un `ListView` dentro de un `Window`, lo centra en la pantalla y se cierra
solo cuando el usuario selecciona. Sirve tanto para selección simple como para filas con
apariencia personalizada.

## APIs usadas
- `new ListViewWindow(String[] items, ListViewWindow.ItemType type)` — crea el popup; también existe la sobrecarga con `String title`.
- `ListViewWindow.ItemType.SINGLE` / `MULTIPLE` — **enum propio** de `ListViewWindow` (alias de `ListView.ItemType`, convertido internamente por `toPanel()`).
- `ListViewWindow.size(float widthRatio, float heightRatio)` — tamaño como fracción de la pantalla (defaults `0.5f`, `0.5f`); el popup siempre está centrado.
- `ListViewWindow.onConfirm(Component.Action)` — delega al `ListView` interno; al confirmar en SINGLE, la ventana se cierra mediante `closeAction(this::hide)`.
- `ListViewWindow.ItemFactory(ItemFactory factory)` — **atención: método con inicial mayúscula**. La interfaz es `ItemFactory { Component create(String text, int index) throws Exception; }`.
- `ListViewWindow.show()` / `hide()` — heredados de `Window` (apila/desapila en el `EventsProcessor`).
- `ListViewWindow.getSelectedText()` / `getSelectedIndex()` / `getSelectedTexts()` — delegados al panel interno.
- `ListViewWindow.getPanel()` — acceso al `ListView` subyacente, por si necesitas configuración avanzada.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      final String[] paises = {"Brasil", "Portugal", "Angola", "Moçambique"};

      // ListViewWindow es popup: NO entra en el layout — abre con show() disparado por un Button
      Button abrir = new Button("Escolher país");
      abrir.onClick(e ->
      {
         ListViewWindow popup = new ListViewWindow("País", paises, ListViewWindow.ItemType.SINGLE);
         popup.size(.6f, .5f);                 // 60% del ancho, 50% de la altura de la pantalla
         popup.onConfirm(ev ->
         {
            String pais = popup.getSelectedText();   // la ventana ya se cierra sola en SINGLE
            Debug.log("País: " + pais);
            return null;
         });
         popup.show();                          // abre modal centrado
         return null;
      });

      add(LAY_AUTO, abrir);
   }
}
```

> El fragmento de abajo muestra **solo el núcleo**. Para ejecutarlo, colócalo en el esqueleto `MainWindow` de arriba.

## Fragmento mínimo
```java
// verificado en la fuente: ListViewWindow.java
String[] paises = {"Brasil", "Portugal", "Angola", "Moçambique"};

ListViewWindow popup = new ListViewWindow("País", paises, ListViewWindow.ItemType.SINGLE);
popup.size(.6f, .5f);                 // 60% del ancho, 50% de la altura de la pantalla
popup.onConfirm(e ->
{
   String pais = popup.getSelectedText();   // la ventana ya se cierra sola en SINGLE
   return null;
});
popup.show();                          // abre modal centrado
```

Filas personalizadas con `ItemFactory` (nota la **`I` mayúscula** en el nombre del método):

```java
// verificado en la fuente: ListViewWindow.ItemFactory (interface) + método ItemFactory(...)
ListViewWindow popup = new ListViewWindow("Contato", nomes, ListViewWindow.ItemType.SINGLE);
popup.ItemFactory((text, index) ->
{
   Component linha = new Component();
   linha.setLayout(new GridLayout());
   linha.add(new Label(text));                 // monta la fila como quieras
   return linha;
});
popup.onConfirm(e -> { /* ... */ return null; });
popup.show();
```

> Divergencia Javadoc × código: el Javadoc de clase muestra `sel.show()` sobre un `ListView`, pero
> `show()`/`hide()` existen en `Window` — por lo tanto en el `ListViewWindow`, no en el `ListView`. Para el
> modo popup usa siempre `ListViewWindow`.

## Profundiza
- Versión incrustada (sin ventana) de la misma lista: [lista-simples.md](/docs/cookbook/lists/lista-simples).
- Guía del widget: [ListViewWindow](/docs/ui/widgets/listviewwindow) · Fuente canónica: Capítulo 15
