# How to show a modal selection popup

> Open a list as a centered modal window with custom rows via ItemFactory.

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

# How to show a modal selection popup

**Purpose.** Open a selection list as a **floating window** (not embedded in the layout).
`ListViewWindow` wraps a `ListView` inside a `Window`, centers it on screen, and closes
itself when the user makes a selection. It works both for simple selection and for rows with
a custom appearance.

## APIs used
- `new ListViewWindow(String[] items, ListViewWindow.ItemType type)` — creates the popup; there is also the overload with `String title`.
- `ListViewWindow.ItemType.SINGLE` / `MULTIPLE` — **own enum** of `ListViewWindow` (alias of `ListView.ItemType`, converted internally by `toPanel()`).
- `ListViewWindow.size(float widthRatio, float heightRatio)` — size as a fraction of the screen (defaults `0.5f`, `0.5f`); the popup is always centered.
- `ListViewWindow.onConfirm(Component.Action)` — delegates to the internal `ListView`; on confirm in SINGLE, the window closes itself via `closeAction(this::hide)`.
- `ListViewWindow.ItemFactory(ItemFactory factory)` — **note: method with an uppercase initial**. The interface is `ItemFactory { Component create(String text, int index) throws Exception; }`.
- `ListViewWindow.show()` / `hide()` — inherited from `Window` (pushes/pops on the `EventsProcessor`).
- `ListViewWindow.getSelectedText()` / `getSelectedIndex()` / `getSelectedTexts()` — delegated to the internal panel.
- `ListViewWindow.getPanel()` — access to the underlying `ListView`, if you need advanced config.

## Complete example (copy, paste and run)
```java
package com.exemplo;

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

/** Runnable main screen. Point the launcher (classname) and run: 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 is a popup: does NOT go into the layout — opens with show() fired by a 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% of the screen width, 50% of the height
         popup.onConfirm(ev ->
         {
            String pais = popup.getSelectedText();   // the window already closes itself on SINGLE
            Debug.log("País: " + pais);
            return null;
         });
         popup.show();                          // opens a centered modal
         return null;
      });

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

> The snippet below shows **only the core**. To run it, place it inside the `MainWindow` skeleton above.

## Minimal snippet
```java
// verified in source: ListViewWindow.java
String[] paises = {"Brasil", "Portugal", "Angola", "Moçambique"};

ListViewWindow popup = new ListViewWindow("País", paises, ListViewWindow.ItemType.SINGLE);
popup.size(.6f, .5f);                 // 60% of the screen width, 50% of the height
popup.onConfirm(e ->
{
   String pais = popup.getSelectedText();   // the window already closes itself on SINGLE
   return null;
});
popup.show();                          // opens a centered modal
```

Custom rows with `ItemFactory` (note the **uppercase `I`** in the method name):

```java
// verified in source: ListViewWindow.ItemFactory (interface) + ItemFactory(...) method
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));                 // build the row however you like
   return linha;
});
popup.onConfirm(e -> { /* ... */ return null; });
popup.show();
```

> Javadoc × code discrepancy: the class Javadoc shows `sel.show()` on a `ListView`, but
> `show()`/`hide()` exist on `Window` — therefore on `ListViewWindow`, not on `ListView`. For the
> popup mode always use `ListViewWindow`.

## Go deeper
- Embedded (windowless) version of the same list: [lista-simples.md](/docs/cookbook/lists/lista-simples).
- Widget guide: [ListViewWindow](/docs/ui/widgets/listviewwindow) · Canonical source: Chapter 15
